diff --git a/middleware/clerkAuth.js b/middleware/clerkAuth.js index 0f916283..c0570a09 100644 --- a/middleware/clerkAuth.js +++ b/middleware/clerkAuth.js @@ -1,15 +1,34 @@ -const { ClerkExpressRequireAuth } = require('@clerk/clerk-sdk-node'); +const { ClerkExpressRequireAuth, clerkClient } = require('@clerk/clerk-sdk-node'); -// Simple authentication middleware -const requireAuth = ClerkExpressRequireAuth({ - onError: (error) => { - console.error('Clerk auth error:', error); - return { - status: 401, - message: 'Authentication required. Please sign in.' - }; +// Robust Clerk authentication middleware +// Uses ClerkExpressRequireAuth with proper error handling +const requireAuth = async (req, res, next) => { + try { + // Use ClerkExpressRequireAuth internally + const clerkMiddleware = ClerkExpressRequireAuth(); + + await new Promise((resolve, reject) => { + clerkMiddleware(req, res, (err) => { + if (err) reject(err); + else resolve(); + }); + }); + + // Verify we got a userId + if (!req.auth?.userId) { + return res.status(401).json({ + error: 'Authentication required. Please sign in.' + }); + } + + next(); + } catch (error) { + console.error('Clerk auth error:', error.message || error); + return res.status(401).json({ + error: 'Authentication required. Please sign in.' + }); } -}); +}; // Extract user ID from request const getUserId = (req) => { diff --git a/models/User.js b/models/User.js index 63603fc0..81bcbb98 100644 --- a/models/User.js +++ b/models/User.js @@ -94,6 +94,17 @@ const userSchema = new mongoose.Schema({ type:String, default:null }, + phone:{ + type:String, + trim:true, + default:null + }, + bio:{ + type:String, + trim:true, + maxlength:500, + default:null + }, role:{ type:String, enum:["user","admin"], diff --git a/public/settings.html b/public/settings.html index 93a25000..38ba7e0d 100644 --- a/public/settings.html +++ b/public/settings.html @@ -7,8 +7,506 @@ Settings & Profile - ExpenseFlow + + + + @@ -57,6 +555,143 @@ transform: translate(-50%, -50%) scale(1.3); background: linear-gradient(135deg, #00b4d8 0%, #64ffda 100%) !important; } + + /* Footer */ +.footer { + background: rgba(15, 15, 35, 0.9); + backdrop-filter: blur(20px); + border-top: 1px solid rgba(255, 255, 255, 0.1); + padding: 3rem 0 1rem; + margin-top: 4rem; + animation: fadeInUp 1s ease-out 1.2s both; +} + +.footer-container { + max-width: 1200px; + margin: 0 auto; + padding: 0 2rem; + display: grid; + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + gap: 2rem; +} + +.footer-section { + display: flex; + flex-direction: column; + gap: 1rem; +} + +.footer-logo { + display: flex; + align-items: center; + gap: 0.5rem; + font-size: 1.5rem; + font-weight: 700; + color: var(--accent-primary); + margin-bottom: 0.5rem; +} + +.footer-logo i { + font-size: 2rem; + background: var(--primary-gradient); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +.footer-section p { + color: var(--text-secondary); + line-height: 1.6; +} + +.footer-section h4 { + color: var(--text-primary); + font-weight: 600; + margin-bottom: 0.5rem; +} + +.footer-links { + list-style: none; + display: flex; + flex-direction: column; + gap: 0.5rem; +} + +.footer-links a { + color: var(--text-secondary); + text-decoration: none; + transition: color 0.3s ease; +} + +.footer-links a:hover { + color: var(--accent-primary); +} +.footer-bottom { + margin-top: 2rem; + padding-top: 1rem; + border-top: 1px solid rgba(255, 255, 255, 0.1); + text-align: center; + color: var(--text-secondary); + font-size: 0.9rem; +} +.social-links { + display: flex; + gap: 1rem; +} + +.social-link { + display: flex; + align-items: center; + justify-content: center; + width: 40px; + height: 40px; + background: rgba(255, 255, 255, 0.1); + border-radius: 50%; + color: var(--text-secondary); + text-decoration: none; + transition: all 0.3s ease; +} + +.social-link:hover { + background: var(--accent-primary); + color: var(--bg-primary); + transform: translateY(-2px); +} + +.footer-bottom { + border-top: 1px solid rgba(255, 255, 255, 0.1); + margin-top: 2rem; + padding-top: 1rem; +} + +.footer-bottom .footer-container { + display: flex; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; + gap: 1rem; + grid-template-columns: 1fr; +} + +.footer-bottom p { + color: var(--text-secondary); + font-size: 0.9rem; +} + +.footer-stats { + display: flex; + gap: 1rem; + flex-wrap: wrap; +} + +.footer-stats span { + font-size: 0.8rem; + color: var(--text-secondary); + background: rgba(255, 255, 255, 0.05); + padding: 0.25rem 0.75rem; + border-radius: 15px; +} +
@@ -215,7 +850,56 @@ animateTrail(); })(); + +
+ +
@@ -259,6 +943,7 @@

Settings & Profile

+

John Doe

@@ -620,8 +1305,73 @@

Delete Account

+ + + +