Commit de2cd12f authored by Poojasri's avatar Poojasri
Browse files

password reset

parent 4cdaca34
Loading
Loading
Loading
Loading
+68 −12
Original line number Diff line number Diff line
import { Context } from "hono";
import db from "../../db/db.connect";
import { users } from "../models/user.model";
import { eq } from "drizzle-orm";
import { eq, gt, and } from "drizzle-orm";
import { hashPassword, verifyPassword } from "./password.utill";
import { verificationTokens } from "../models/verification.token.model";
import crypto from 'crypto';
import crypto from "crypto";

export const registerUser = async (c: Context) => {
  const body = await c.req.json();
@@ -61,8 +61,8 @@ export const loginUser = async (c: Context) => {
      id: user.id,
      email: user.email,
      firstName: user.firstName,
      lastName: user.lastName
    }
      lastName: user.lastName,
    },
  });
};

@@ -73,28 +73,84 @@ export const forgotPassword = async (c: Context) => {
    const [user] = await db.select().from(users).where(eq(users.email, email));

    if (!user) {
      return c.json({ error: 'User not found' }, 404);
      return c.json({ error: "User not found" }, 404);
    }

    // Create the expiry date (1 day from now)
    const expiryDate = new Date();
    expiryDate.setDate(expiryDate.getDate() + 1);

    const token = crypto.randomBytes(32).toString('hex');
    const token = crypto.randomBytes(32).toString("hex");

    await db.insert(verificationTokens).values({
      userAccountId: user.id,
      token: token,
      type: 'PWD_RESET',
      type: "PWD_RESET",
      notificationTime: null,
      expiryTime: expiryDate,
      createdAt: new Date(),
      updatedAt: new Date(),
    });

    return c.json({ status: 'SUCCESS' }, 200);
    return c.json({ status: "SUCCESS" }, 200);
  } catch (error) {
    console.error('Error in forgotPassword:', error);
    return c.json({ error: 'Internal Server Error' }, 500);
    console.error("Error in forgotPassword:", error);
    return c.json({ error: "Internal Server Error" }, 500);
  }
};

export const passwordReset = async (c: Context) => {
  const body = await c.req.json();
  const tokenValue = body.token;
  const newPassword = body.password;

  // Find the token in the verificationTokens table
  const tokenResult = await db
    .select()
    .from(verificationTokens)
    .where(
      and(
        eq(verificationTokens.token, tokenValue),
        eq(verificationTokens.type, "PWD_RESET"),
        gt(verificationTokens.expiryTime, new Date())
      )
    );

  if (tokenResult.length === 0) {
    return c.json(
      { error: "Invalid password recovery link or the link has expired." },
      400
    );
  }

  const token = tokenResult[0];

  // Find the user account associated with the token
  const userResult = await db
    .select()
    .from(users)
    .where(eq(users.id, token.userAccountId));

  if (userResult.length === 0) {
    return c.json(
      { error: "Invalid password recovery link or the link has expired." },
      400
    );
  }

  const user = userResult[0];

  // Reset the password
  const hashedPassword = await hashPassword(newPassword);
  await db
    .update(users)
    .set({ password: hashedPassword })
    .where(eq(users.id, user.id));

  // Delete the used token
  await db
    .delete(verificationTokens)
    .where(eq(verificationTokens.id, token.id));

  return c.json({ status: "SUCCESS" });
};
+19 −1
Original line number Diff line number Diff line
import { Hono } from "hono";
import { forgotPassword, loginUser, registerUser } from "./user.controller";
import {
  forgotPassword,
  loginUser,
  passwordReset,
  registerUser,
} from "./user.controller";
import {
  forgotPasswordSchema,
  loginSchema,
  passwordResetSchema,
  registrationSchema,
} from "./user.validation.schema";

@@ -42,4 +48,16 @@ export const userRoutes = (app: Hono) => {

    return forgotPassword(c);
  });

  app.post("/user/password-reset", async (c) => {
    const body = await c.req.json();

    try {
      passwordResetSchema.parse(body);
    } catch (error: any) {
      return c.json({ error: error.errors }, 400);
    }

    return passwordReset(c);
  });
};
+9 −1
Original line number Diff line number Diff line
@@ -20,4 +20,12 @@ const forgotPasswordSchema = z.object({
  email: z.string().nonempty("Email is required").email("Invalid email format"),
});

export { registrationSchema, loginSchema, forgotPasswordSchema };
const passwordResetSchema = z.object({
  token: z.string().nonempty("Token is required"),
  password: z
    .string()
    .nonempty("Password is required")
    .min(4, "Password must be at least 4 characters long"),
});

export { registrationSchema, loginSchema, forgotPasswordSchema, passwordResetSchema };