Loading hono-postgres-setup/src/user/user.controller.ts +33 −0 Original line number Diff line number Diff line Loading @@ -3,6 +3,8 @@ import db from "../../db/db.connect"; import { users } from "./user.model"; import { eq } from "drizzle-orm"; import { hashPassword, verifyPassword } from "./password.utill"; import { verificationTokens } from "./verification.token.model"; import crypto from 'crypto'; export const registerUser = async (c: Context) => { const body = await c.req.json(); Loading Loading @@ -64,4 +66,35 @@ export const loginUser = async (c: Context) => { }); }; export const forgotPassword = async (c: Context) => { try { const { email } = await c.req.json(); const [user] = await db.select().from(users).where(eq(users.email, email)); if (!user) { 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'); await db.insert(verificationTokens).values({ userAccountId: user.id, token: token, type: 'PWD_RESET', notificationTime: null, expiryTime: expiryDate, createdAt: new Date(), updatedAt: new Date(), }); return c.json({ status: 'SUCCESS' }, 200); } catch (error) { console.error('Error in forgotPassword:', error); return c.json({ error: 'Internal Server Error' }, 500); } }; No newline at end of file hono-postgres-setup/src/user/user.route.ts +18 −2 Original line number Diff line number Diff line import { Hono } from "hono"; import { loginUser, registerUser } from "./user.controller"; import { loginSchema, registrationSchema } from "./user.validationschema"; import { forgotPassword, loginUser, registerUser } from "./user.controller"; import { forgotPasswordSchema, loginSchema, registrationSchema, } from "./user.validation.schema"; export const userRoutes = (app: Hono) => { app.post("/user/register", async (c) => { Loading @@ -26,4 +30,16 @@ export const userRoutes = (app: Hono) => { return loginUser(c); }); app.post("/user/forgot-password", async (c) => { const body = await c.req.json(); try { forgotPasswordSchema.parse(body); } catch (error: any) { return c.json({ error: error.errors }, 400); } return forgotPassword(c); }); }; hono-postgres-setup/src/user/user.validationschema.ts→hono-postgres-setup/src/user/user.validation.schema.ts +8 −3 Original line number Diff line number Diff line Loading @@ -4,15 +4,20 @@ import { z } from "zod"; const registrationSchema = z.object({ firstName: z.string().nonempty("First Name is required"), lastName: z.string().optional().nullable(), email: z.string().nonempty("Email is required"), email: z.string().nonempty("Email is required").email("Invalid email format"), phoneNumber: z.string().optional().nullable(), password: z.string().min(4, "Password must be at least 4 characters long"), }); // Login schema const loginSchema = z.object({ email: z.string().nonempty("Email is required"), email: z.string().nonempty("Email is required").email("Invalid email format"), password: z.string().nonempty("Password is required"), }); export { registrationSchema, loginSchema }; // Forgot Password schema const forgotPasswordSchema = z.object({ email: z.string().nonempty("Email is required").email("Invalid email format"), }); export { registrationSchema, loginSchema, forgotPasswordSchema }; hono-postgres-setup/src/user/verification.token.model.ts 0 → 100644 +14 −0 Original line number Diff line number Diff line import { integer, pgTable, serial, text, timestamp } from 'drizzle-orm/pg-core'; export const verificationTokens = pgTable('verification_tokens', { id: serial('id').primaryKey(), userAccountId: integer('userAccountId').notNull(), token: text('token').notNull(), type: text('type').notNull(), notificationTime: timestamp('notificationTime'), expiryTime: timestamp('expiryTime').notNull(), createdAt: timestamp('createdAt').notNull(), updatedAt: timestamp('updatedAt').notNull(), }); No newline at end of file Loading
hono-postgres-setup/src/user/user.controller.ts +33 −0 Original line number Diff line number Diff line Loading @@ -3,6 +3,8 @@ import db from "../../db/db.connect"; import { users } from "./user.model"; import { eq } from "drizzle-orm"; import { hashPassword, verifyPassword } from "./password.utill"; import { verificationTokens } from "./verification.token.model"; import crypto from 'crypto'; export const registerUser = async (c: Context) => { const body = await c.req.json(); Loading Loading @@ -64,4 +66,35 @@ export const loginUser = async (c: Context) => { }); }; export const forgotPassword = async (c: Context) => { try { const { email } = await c.req.json(); const [user] = await db.select().from(users).where(eq(users.email, email)); if (!user) { 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'); await db.insert(verificationTokens).values({ userAccountId: user.id, token: token, type: 'PWD_RESET', notificationTime: null, expiryTime: expiryDate, createdAt: new Date(), updatedAt: new Date(), }); return c.json({ status: 'SUCCESS' }, 200); } catch (error) { console.error('Error in forgotPassword:', error); return c.json({ error: 'Internal Server Error' }, 500); } }; No newline at end of file
hono-postgres-setup/src/user/user.route.ts +18 −2 Original line number Diff line number Diff line import { Hono } from "hono"; import { loginUser, registerUser } from "./user.controller"; import { loginSchema, registrationSchema } from "./user.validationschema"; import { forgotPassword, loginUser, registerUser } from "./user.controller"; import { forgotPasswordSchema, loginSchema, registrationSchema, } from "./user.validation.schema"; export const userRoutes = (app: Hono) => { app.post("/user/register", async (c) => { Loading @@ -26,4 +30,16 @@ export const userRoutes = (app: Hono) => { return loginUser(c); }); app.post("/user/forgot-password", async (c) => { const body = await c.req.json(); try { forgotPasswordSchema.parse(body); } catch (error: any) { return c.json({ error: error.errors }, 400); } return forgotPassword(c); }); };
hono-postgres-setup/src/user/user.validationschema.ts→hono-postgres-setup/src/user/user.validation.schema.ts +8 −3 Original line number Diff line number Diff line Loading @@ -4,15 +4,20 @@ import { z } from "zod"; const registrationSchema = z.object({ firstName: z.string().nonempty("First Name is required"), lastName: z.string().optional().nullable(), email: z.string().nonempty("Email is required"), email: z.string().nonempty("Email is required").email("Invalid email format"), phoneNumber: z.string().optional().nullable(), password: z.string().min(4, "Password must be at least 4 characters long"), }); // Login schema const loginSchema = z.object({ email: z.string().nonempty("Email is required"), email: z.string().nonempty("Email is required").email("Invalid email format"), password: z.string().nonempty("Password is required"), }); export { registrationSchema, loginSchema }; // Forgot Password schema const forgotPasswordSchema = z.object({ email: z.string().nonempty("Email is required").email("Invalid email format"), }); export { registrationSchema, loginSchema, forgotPasswordSchema };
hono-postgres-setup/src/user/verification.token.model.ts 0 → 100644 +14 −0 Original line number Diff line number Diff line import { integer, pgTable, serial, text, timestamp } from 'drizzle-orm/pg-core'; export const verificationTokens = pgTable('verification_tokens', { id: serial('id').primaryKey(), userAccountId: integer('userAccountId').notNull(), token: text('token').notNull(), type: text('type').notNull(), notificationTime: timestamp('notificationTime'), expiryTime: timestamp('expiryTime').notNull(), createdAt: timestamp('createdAt').notNull(), updatedAt: timestamp('updatedAt').notNull(), }); No newline at end of file