From bd17947106cc0c1ce9c9207ff282222fbd5ded9a Mon Sep 17 00:00:00 2001 From: Mohan Ki Date: Mon, 27 Jul 2026 19:16:17 +0530 Subject: [PATCH] feat(auth): Introduce 5-day grace period for email verification before lockout --- api/middleware/auth.js | 14 ++++- api/routes/auth.js | 2 +- client/src/app/dashboard/layout.tsx | 85 ++++++++++++++++++++--------- 3 files changed, 71 insertions(+), 30 deletions(-) diff --git a/api/middleware/auth.js b/api/middleware/auth.js index c36f0d0..a14d58e 100644 --- a/api/middleware/auth.js +++ b/api/middleware/auth.js @@ -30,9 +30,17 @@ const verifyToken = (req, res, next) => { const requireEmailVerification = async (req, res, next) => { try { - const userCheck = await pgPool.query('SELECT is_email_verified FROM users WHERE id = $1', [req.user.id]); - if (userCheck.rows.length === 0 || !userCheck.rows[0].is_email_verified) { - return res.status(403).json({ error: 'Email verification required' }); + const userCheck = await pgPool.query('SELECT is_email_verified, created_at FROM users WHERE id = $1', [req.user.id]); + if (userCheck.rows.length === 0) return res.status(403).json({ error: 'User not found' }); + + const user = userCheck.rows[0]; + if (!user.is_email_verified) { + const createdAt = new Date(user.created_at); + const now = new Date(); + const daysSinceCreation = (now.getTime() - createdAt.getTime()) / (1000 * 60 * 60 * 24); + if (daysSinceCreation > 5) { + return res.status(403).json({ error: 'Email verification grace period expired (5 days)' }); + } } next(); } catch (err) { diff --git a/api/routes/auth.js b/api/routes/auth.js index 7918a8f..e8d3940 100644 --- a/api/routes/auth.js +++ b/api/routes/auth.js @@ -94,7 +94,7 @@ router.post('/login', async (req, res) => { const { verifyToken } = require('../middleware/auth'); router.get('/me', verifyToken, async (req, res) => { try { - const userQuery = await pgPool.query('SELECT id, email, role, is_email_verified FROM users WHERE id = $1', [req.user.id]); + const userQuery = await pgPool.query('SELECT id, email, role, is_email_verified, created_at FROM users WHERE id = $1', [req.user.id]); if (userQuery.rows.length === 0) return res.status(404).json({ error: 'User not found' }); res.json({ user: userQuery.rows[0] }); } catch (err) { diff --git a/client/src/app/dashboard/layout.tsx b/client/src/app/dashboard/layout.tsx index 15ac549..48c4220 100644 --- a/client/src/app/dashboard/layout.tsx +++ b/client/src/app/dashboard/layout.tsx @@ -49,17 +49,25 @@ export default function DashboardLayout({ children }: { children: React.ReactNod
- {user?.is_email_verified === false ? ( - - ) : ( - - - Create New QR Code - - )} + {(() => { + if (user?.is_email_verified === false) { + const daysSinceCreation = (new Date().getTime() - new Date(user.created_at).getTime()) / (1000 * 60 * 60 * 24); + if (daysSinceCreation > 5) { + return ( + + ); + } + } + return ( + + + Create New QR Code + + ); + })()}