diff --git a/src/app/api/auth/google/callback/route.js b/src/app/api/auth/google/callback/route.js
index b90a74b..8a5bdf4 100644
--- a/src/app/api/auth/google/callback/route.js
+++ b/src/app/api/auth/google/callback/route.js
@@ -175,7 +175,7 @@ export async function GET(req) {
console.log('Authorization code:', code);
- const redirectUri = 'https://your-production-domain.com/api/auth/google/callback';
+ const redirectUri = 'https://inboxiq-seven.vercel.app/api/auth/google/callback';
const oauth2Client = new google.auth.OAuth2(
process.env.GOOGLE_CLIENT_ID,
diff --git a/src/app/api/auth/google/route.js b/src/app/api/auth/google/route.js
index 10fe345..b474245 100644
--- a/src/app/api/auth/google/route.js
+++ b/src/app/api/auth/google/route.js
@@ -1,162 +1,10 @@
-// import { google } from 'googleapis';
-
-// export async function GET(req) {
-// try {
-// console.log('Redirecting to Google OAuth consent screen');
-
-// const oauth2Client = new google.auth.OAuth2(
-// process.env.GOOGLE_CLIENT_ID,
-// process.env.GOOGLE_CLIENT_SECRET,
-// 'https://localhost:3000/api/auth/google/callback' // The same URL should be set in your Google Cloud console
-// );
-
-// const authUrl = oauth2Client.generateAuthUrl({
-// access_type: 'offline',
-// scope: [
-// 'https://www.googleapis.com/auth/gmail.readonly',
-// 'https://www.googleapis.com/auth/userinfo.profile', // User profile scope
-// 'https://www.googleapis.com/auth/userinfo.email', // User email scope
-// 'https://www.googleapis.com/auth/gmail.modify',
-// 'https://www.googleapis.com/auth/gmail.compose',
-// 'https://www.googleapis.com/auth/gmail.send',
-// 'https://www.googleapis.com/auth/gmail.labels',
-// 'https://www.googleapis.com/auth/gmail.compose',
-// 'https://www.googleapis.com/auth/gmail.modify',
-// 'https://mail.google.com/'
-// ],
-// prompt: 'consent',
-// });
-
-// // Redirect the user to the Google OAuth URL
-// return new Response(null, {
-// status: 302,
-// headers: {
-// Location: authUrl,
-// },
-// });
-// } catch (error) {
-// console.error('Error during Google OAuth redirection:', error);
-// return new Response(JSON.stringify({ error: 'Internal server error' }), {
-// status: 500,
-// headers: { 'Content-Type': 'application/json' },
-// });
-// }
-// }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-// import { google } from 'googleapis';
-
-// export async function GET(req) {
-// try {
-// console.log('Redirecting to Google OAuth consent screen');
-
-// const redirectUri =
-// process.env.NODE_ENV === 'development'
-// ? 'http://localhost:3000/api/auth/google/callback' // Development redirect URI
-// : 'https://https://inboxiq-seven.vercel.app/api/auth/google/callback'; // Production redirect URI
-
-// const oauth2Client = new google.auth.OAuth2(
-// process.env.GOOGLE_CLIENT_ID,
-// process.env.GOOGLE_CLIENT_SECRET,
-// redirectUri
-// );
-
-// const authUrl = oauth2Client.generateAuthUrl({
-// access_type: 'offline',
-// scope: [
-// 'https://www.googleapis.com/auth/gmail.readonly',
-// 'https://www.googleapis.com/auth/userinfo.profile',
-// 'https://www.googleapis.com/auth/userinfo.email',
-// 'https://www.googleapis.com/auth/gmail.modify',
-// 'https://www.googleapis.com/auth/gmail.compose',
-// 'https://www.googleapis.com/auth/gmail.send',
-// 'https://www.googleapis.com/auth/gmail.labels',
-// 'https://mail.google.com/'
-// ],
-// prompt: 'consent',
-// });
-// return new Response(null, {
-// status: 302,
-// headers: {
-// Location: authUrl,
-// },
-// });
-// } catch (error) {
-// console.error('Error during Google OAuth redirection:', error);
-// return new Response(JSON.stringify({ error: 'Internal server error' }), {
-// status: 500,
-// headers: { 'Content-Type': 'application/json' },
-// });
-// }
-// }
-
-
-
-
-
-
-
-// import { google } from 'googleapis';
-
-// export async function GET(req) {
-// try {
-// const redirectUri =
-// process.env.NODE_ENV === 'development'
-// ? 'http://localhost:3000/api/auth/google/callback'
-// : 'https://inboxiq-seven.vercel.app/api/auth/google/callback';
-
-// const oauth2Client = new google.auth.OAuth2(
-// process.env.GOOGLE_CLIENT_ID,
-// process.env.GOOGLE_CLIENT_SECRET,
-// redirectUri
-// );
-
-// const authUrl = oauth2Client.generateAuthUrl({
-// access_type: 'offline',
-// scope: [
-// 'https://www.googleapis.com/auth/gmail.readonly',
-// 'https://www.googleapis.com/auth/userinfo.profile',
-// 'https://www.googleapis.com/auth/userinfo.email',
-// ],
-// prompt: 'consent',
-// });
-
-// return new Response(null, {
-// status: 302,
-// headers: {
-// Location: authUrl,
-// },
-// });
-// } catch (error) {
-// console.error('Error during Google OAuth redirection:', error);
-// return new Response(JSON.stringify({ error: 'Internal server error' }), {
-// status: 500,
-// headers: { 'Content-Type': 'application/json' },
-// });
-// }
-// }
-
-
-
-
import { google } from 'googleapis';
export async function GET(req) {
try {
- const redirectUri = 'http://inboxiq-seven.vercel.app/api/auth/google/callback';
+ const redirectUri = 'https://inboxiq-seven.vercel.app/api/auth/google/callback';
+
const oauth2Client = new google.auth.OAuth2(
diff --git a/src/app/components/header.js b/src/app/components/header.js
index 3a9a8c5..1a7caf7 100644
--- a/src/app/components/header.js
+++ b/src/app/components/header.js
@@ -149,11 +149,12 @@ const Navbar = () => {
) : (
Login
+
)}
diff --git a/src/middleware.js b/src/middleware.js
index 21063be..d2a99c8 100644
--- a/src/middleware.js
+++ b/src/middleware.js
@@ -147,9 +147,171 @@
+// import { NextResponse } from 'next/server';
+// import { Redis } from '@upstash/redis';
+// import { withMiddlewareAuthRequired } from '@auth0/nextjs-auth0/edge';
+
+// /* ------------------------------------
+// * 1. Initialize Redis client
+// * ---------------------------------- */
+// let redis;
+// try {
+// redis = new Redis({
+// url: process.env.UPSTASH_REDIS_URL,
+// token: process.env.UPSTASH_REDIS_TOKEN,
+// });
+// console.log('Redis initialized successfully');
+// } catch (error) {
+// console.error('Error initializing Redis:', error);
+// // You could set `redis = null` here to handle fallback if needed
+// }
+
+// /* ------------------------------------
+// * 2. Helper to safely get client IP
+// * ---------------------------------- */
+// function getClientIp(req) {
+// const forwardedFor = req.headers.get('x-forwarded-for');
+// if (forwardedFor) {
+// // Typically, x-forwarded-for can contain multiple IPs, take the first
+// return forwardedFor.split(',')[0].trim();
+// }
+// // Fallback to req.ip or localhost
+// return req.ip || '127.0.0.1';
+// }
+
+// /* --------------------------------------------------
+// * 3. Rate-Limiting Middleware (Fixed Window Example)
+// * ------------------------------------------------- */
+// async function rateLimitMiddleware(req) {
+// // If no Redis client is available, decide your fallback:
+// // - Throw a 500
+// // - Or skip rate limiting and proceed
+// if (!redis) {
+// console.error('Redis client is not initialized. Skipping rate limiting.');
+// return null; // null = no response, continue chain
+// }
+
+// // Identify user route and IP
+// const ip = getClientIp(req);
+// const path = req.nextUrl.pathname;
+// const rateLimitKey = `rate_limit:${ip}:${path}`;
+
+// // Configure your rate limit window and max requests
+// const limit = 10; // max requests
+// const window = 60; // time window in seconds
+
+// // Increment the request count in Redis
+// try {
+// const current = await redis.incr(rateLimitKey);
+
+// // If first request, set expiration
+// if (current === 1) {
+// await redis.expire(rateLimitKey, window);
+// }
+
+// // If user exceeded the limit, return 429
+// if (current > limit) {
+// // Optionally log the event
+// try {
+// await redis.lpush('rate_limit_exceeded_logs', JSON.stringify({
+// ip,
+// path,
+// timestamp: Date.now(),
+// }));
+// } catch (logError) {
+// console.error('Error logging rate-limit exceed:', logError);
+// }
+
+// return NextResponse.json(
+// {
+// error: {
+// message: 'Rate limit exceeded. Try again later.',
+// code: 'RATE_LIMIT_EXCEEDED',
+// },
+// },
+// {
+// status: 429,
+// headers: {
+// 'Retry-After': String(window), // Time (in s) until limit resets
+// 'X-RateLimit-Limit': String(limit), // Total allowed requests
+// 'X-RateLimit-Remaining': '0', // None remaining
+// 'X-RateLimit-Reset': String(Date.now() + (window * 1000)), // or just window
+// },
+// }
+// );
+// }
+
+// // Within limit, attach rate-limit headers for user’s reference
+// return NextResponse.next({
+// headers: {
+// 'X-RateLimit-Limit': String(limit),
+// 'X-RateLimit-Remaining': String(limit - current),
+// 'X-RateLimit-Reset': String(Date.now() + (window * 1000)),
+// },
+// });
+
+// } catch (error) {
+// // If something went wrong in Redis calls, return 500 or skip
+// console.error('Rate limiting error:', error);
+// return NextResponse.json(
+// { error: 'Internal server error while rate limiting.' },
+// { status: 500 }
+// );
+// }
+// }
+
+// /* ------------------------------------
+// * 4. Auth0 Middleware
+// * ------------------------------------
+// * This wraps next-edge-auth0’s `withMiddlewareAuthRequired`
+// * to ensure users are authenticated before accessing the matched routes.
+// */
+// function authMiddleware(req) {
+// return withMiddlewareAuthRequired()(req);
+// }
+
+// /* ------------------------------------
+// * 5. Combined Middleware
+// * ------------------------------------
+// * We first run the rateLimitMiddleware. If it returns a response
+// * (429 or 500), we bail out. Otherwise, we proceed to Auth0 checks.
+// */
+// export async function middleware(req) {
+// // 1) Rate-limiting
+// const rateLimitResponse = await rateLimitMiddleware(req);
+// if (rateLimitResponse) {
+// // If rateLimitMiddleware returned a response, block further handling
+// return rateLimitResponse;
+// }
+
+// // 2) Auth0 Protected Routes
+// return authMiddleware(req);
+// }
+
+// /* ------------------------------------
+// * 6. Configure Matching Routes
+// * ------------------------------------
+// * Adjust the matcher as needed.
+// * For example, apply to all API routes, your dashboard, etc.
+// */
+// export const config = {
+// matcher: ['/dashboard/:path*', '/api/:path*', '/rules/:path*', '/settings'],
+// };
+
+
+
+
+
+
+
+
+
+
+
import { NextResponse } from 'next/server';
import { Redis } from '@upstash/redis';
-import { withMiddlewareAuthRequired } from '@auth0/nextjs-auth0/edge';
+import { withMiddlewareAuthRequired, getSession } from '@auth0/nextjs-auth0/edge';
+import { connectToDatabase } from './lib/mongodb';
/* ------------------------------------
* 1. Initialize Redis client
@@ -261,17 +423,55 @@ async function rateLimitMiddleware(req) {
}
/* ------------------------------------
- * 4. Auth0 Middleware
+ * 4. Database Helper: Check User Email
+ * ---------------------------------- */
+async function checkUserEmailInDatabase(email) {
+ try {
+ const db = await connectToDatabase();
+ const user = await db.collection('users').findOne({ email });
+ return user !== null; // Return true if email exists, false otherwise
+ } catch (error) {
+ console.error('Database query error:', error);
+ return false; // Treat as not found if there's an error
+ }
+}
+
+/* ------------------------------------
+ * 5. Auth0 Middleware
* ------------------------------------
* This wraps next-edge-auth0’s `withMiddlewareAuthRequired`
* to ensure users are authenticated before accessing the matched routes.
*/
-function authMiddleware(req) {
- return withMiddlewareAuthRequired()(req);
+async function authMiddleware(req) {
+ // Ensure the user is authenticated using Auth0
+ const res = await withMiddlewareAuthRequired()(req);
+
+ if (!res) {
+ return NextResponse.redirect('/api/auth/login'); // Redirect unauthenticated users
+ }
+
+ // Extract user session
+ const session = await getSession(req, res);
+ const email = session?.user?.email;
+
+ if (!email) {
+ console.error('No email found in session.');
+ return NextResponse.redirect('/api/auth/login'); // Redirect if no email
+ }
+
+ // Check if the email exists in the database
+ const emailExists = await checkUserEmailInDatabase(email);
+
+ if (!emailExists) {
+ // Redirect to Google OAuth flow if email is not in database
+ return NextResponse.redirect('/api/auth/google');
+ }
+
+ return null; // Continue the middleware chain
}
/* ------------------------------------
- * 5. Combined Middleware
+ * 6. Combined Middleware
* ------------------------------------
* We first run the rateLimitMiddleware. If it returns a response
* (429 or 500), we bail out. Otherwise, we proceed to Auth0 checks.
@@ -284,12 +484,19 @@ export async function middleware(req) {
return rateLimitResponse;
}
- // 2) Auth0 Protected Routes
- return authMiddleware(req);
+ // 2) Auth0 Authentication and Database Check
+ const authResponse = await authMiddleware(req);
+ if (authResponse) {
+ // If authMiddleware returned a response, block further handling
+ return authResponse;
+ }
+
+ // 3) Proceed to the next middleware or route
+ return NextResponse.next();
}
/* ------------------------------------
- * 6. Configure Matching Routes
+ * 7. Configure Matching Routes
* ------------------------------------
* Adjust the matcher as needed.
* For example, apply to all API routes, your dashboard, etc.