Skip to content

Commit

Permalink
🎊 forgot password backend complete
Browse files Browse the repository at this point in the history
  • Loading branch information
Gyoumi committed Dec 8, 2024
1 parent 8a0eb32 commit 7e5d5ef
Show file tree
Hide file tree
Showing 9 changed files with 18 additions and 90 deletions.
11 changes: 11 additions & 0 deletions backend/prisma/migrations/20241206134721_init/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
Warnings:
- You are about to drop the `OtpToken` table. If the table is not empty, all the data it contains will be lost.
*/
-- DropForeignKey
ALTER TABLE "OtpToken" DROP CONSTRAINT "OtpToken_userId_fkey";

-- DropTable
DROP TABLE "OtpToken";
10 changes: 0 additions & 10 deletions backend/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ model User {
salt String
dateJoined DateTime
profilePicture String?
oneTimeToken OtpToken?
}

model Attendee {
Expand Down Expand Up @@ -69,13 +68,4 @@ model Keyword {
text String @unique
attendees Attendee[]
events Event[]
}

model OtpToken {
id Int @id @default(autoincrement())
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
userId Int @unique
token String
timeCreated DateTime
expiryTime DateTime
}
8 changes: 3 additions & 5 deletions backend/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import prisma from "./prisma";
import RedisStore from "connect-redis";
import { createClient } from "redis";
import { generateOTP } from "./routes/OTP/generateOTP";
import { removeExpiredOTPs } from "./routes/OTP/deleteExpired";
import { verifyOTP } from "./routes/OTP/verifyOTP";

declare module "express-session" {
Expand Down Expand Up @@ -57,9 +56,6 @@ app.use(
})
);

// OTP removing cron job
removeExpiredOTPs.start();

app.get("/", (req: Request, res: Response) => {
console.log("Hello, TypeScript with Express :)))!");
res.send("Hello, TypeScript with Express :)))!");
Expand Down Expand Up @@ -151,11 +147,13 @@ app.post("/auth/otp/verify", async(req: Request, res: Response) => {
const hash = await redisClient.get(email);

if(!hash) {
throw Error("One time code has expired.");
throw new Error("One time code is invalid or expired.");
}

await verifyOTP(token, hash);

await redisClient.del(email);

return res.status(200).json({message: "ok" });

} catch (error) {
Expand Down
40 changes: 0 additions & 40 deletions backend/src/routes/OTP/OTPToken.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,44 +17,4 @@ export const getUserFromEmail = async (emailAddress: string) => {
});

return result;
}

export const deleteToken = async(userId: number) => {
const result = await prisma.otpToken.deleteMany({
where: {
userId
}
});

return result;
}

export const addTokenToDb = async(token: OTPToken) => {
const result = await prisma.otpToken.create({
data: {
userId: token.user.id,
token: token.token,
timeCreated: token.timeCreated,
expiryTime: token.expiryTime
}
});
return result;
}

export const getTokenFromEmail = async(emailAddress: string) => {
const user = await getUserFromEmail(emailAddress);
if(!user) {
throw new Error(`User with email address ${emailAddress} not found.`)
}
const otpToken = await prisma.otpToken.findFirst({
where: {
userId: user.id
}
});

if(!otpToken) {
throw new Error(`OTP Token for ${emailAddress} not found.`);
}

return otpToken;
}
16 changes: 0 additions & 16 deletions backend/src/routes/OTP/deleteExpired.ts

This file was deleted.

13 changes: 1 addition & 12 deletions backend/src/routes/OTP/generateOTP.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import crypto from 'crypto';
import bcrypt from 'bcrypt';
import { addTokenToDb, deleteToken, getUserFromEmail, OTPToken } from './OTPToken';
import { getUserFromEmail } from './OTPToken';
import { sendEmail } from './sendEmail';
import { RedisClientType, RedisModules } from 'redis';

export const generateOTP = async (emailAddress: string, salt_rounds: number) => {
const user = await getUserFromEmail(emailAddress);
Expand All @@ -11,21 +10,11 @@ export const generateOTP = async (emailAddress: string, salt_rounds: number) =>
throw new Error("User not found.");
}

//await deleteToken(user.id);

const rand = crypto.randomBytes(4).readUint32BE(0);
const sixDigits = (rand % 900000) + 100000;
const otpCode = sixDigits.toString();
const hash = await bcrypt.hash(otpCode, salt_rounds);

// const token: OTPToken = {
// token: hash,
// timeCreated: new Date(),
// expiryTime: new Date(Date.now()+60000),
// };

//await addTokenToDb(token);

await sendEmail(emailAddress, user.username, otpCode);

return hash;
Expand Down
4 changes: 2 additions & 2 deletions backend/src/routes/OTP/sendEmail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const sendEmail = async (emailAddress: string, userName: string, code: st
throw new Error("invalid email key");
}

console.log(`emailing ${userName} at ${emailAddress} with otp ${code}.`);
//console.log(`emailing ${userName} at ${emailAddress} with otp ${code}.`);
const senderDomain = "mg.pyrmds.app";

try {
Expand All @@ -30,7 +30,7 @@ export const sendEmail = async (emailAddress: string, userName: string, code: st
<p>Dear ${userName},</p>
<p>We have received a request from you to reset your password for Pyramids.</p>
<p>Your one time code is: <strong>${code}</strong>.</p>
<p>Please note that this code will expire in 5 minutes.</p>
<p>Please note that this code will expire in 60 seconds.</p>
<br/>
<p>Thank you.</p>
</div>`
Expand Down
5 changes: 1 addition & 4 deletions backend/src/routes/OTP/verifyOTP.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import prisma from "../../prisma";
import { getTokenFromEmail } from "./OTPToken";
import bcrypt from 'bcrypt';

export const verifyOTP = async (token: string, hash: string) => {
Expand All @@ -10,5 +8,4 @@ export const verifyOTP = async (token: string, hash: string) => {
}

return verify;
}

}
1 change: 0 additions & 1 deletion backend/tests/otp.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { expect, test, vi, describe } from "vitest"; // 👈🏻 Added the `vi`
import request from "supertest";
import app from "../src/index";
import { createClient } from "redis";
import { afterEach, beforeEach } from "node:test";
import prisma from "../src/prisma";

describe("Tests", () => {
Expand Down

0 comments on commit 7e5d5ef

Please sign in to comment.