From abbdce2e37b8620115ff25d9a1826ff4d312bd5c Mon Sep 17 00:00:00 2001 From: Ashad Qureshi Date: Mon, 30 Jun 2025 19:15:47 +0500 Subject: [PATCH 1/2] config update and oauth guide --- .../docs/system/authentication.md | 275 +++--------------- auto-analyst-frontend/lib/credits-config.ts | 6 +- 2 files changed, 47 insertions(+), 234 deletions(-) diff --git a/auto-analyst-frontend/docs/system/authentication.md b/auto-analyst-frontend/docs/system/authentication.md index 86b12e1c..66a49c01 100644 --- a/auto-analyst-frontend/docs/system/authentication.md +++ b/auto-analyst-frontend/docs/system/authentication.md @@ -1,248 +1,61 @@ -# Authentication System Documentation - -Auto-Analyst uses NextAuth.js for comprehensive authentication management. - -## Authentication Overview - -### Supported Providers -- **Google OAuth** - Primary authentication method -- **Credentials** - Admin temporary login -- **Guest Mode** - Limited trial access - -### NextAuth Configuration -```typescript -// app/api/auth/[...nextauth]/route.ts -const handler = NextAuth({ - providers: [ - GoogleProvider({ - clientId: process.env.GOOGLE_CLIENT_ID, - clientSecret: process.env.GOOGLE_CLIENT_SECRET, - }), - CredentialsProvider({ - name: "Temporary Login", - credentials: { - password: { label: "Temporary Code", type: "password" }, - }, - async authorize(credentials) { - if (credentials?.password === process.env.NEXT_PUBLIC_ANALYTICS_ADMIN_PASSWORD) { - return { - id: "admin", - name: "Administrator", - email: "admin@example.com", - } - } - return null - } - }) - ], - callbacks: { - async signIn({ user }) { - // Save user profile to Redis on first login - await profileUtils.saveUserProfile(user.id, { - email: user.email, - name: user.name, - image: user.image, - joinedDate: new Date().toISOString(), - role: 'Free' - }) - return true - } - } -}) -``` +# Google OAuth Setup Guide -## Session Management +This project uses Google OAuth 2.0 for authentication. Follow these steps to set it up on your own Google Cloud account. -### Client-Side Sessions -```typescript -// Using useSession hook -const { data: session, status } = useSession() +--- -if (status === "loading") return -if (status === "unauthenticated") return +## Prerequisites -// Authenticated user -return -``` +- A Google Account +- Access to [Google Cloud Console](https://console.cloud.google.com/) +- Local environment or deployed domain (e.g., `localhost:3000`, `yourdomain.com`) -### Server-Side Sessions -```typescript -// API routes authentication -export async function GET(request: NextRequest) { - const token = await getToken({ req: request }) - - if (!token?.sub) { - return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }) - } - - // Proceed with authenticated request -} -``` +--- -## User Profile Management - -### Profile Storage (Redis) -```typescript -// lib/redis.ts -export const profileUtils = { - async saveUserProfile(userId: string, profile: UserProfile) { - await redis.hset(KEYS.USER_PROFILE(userId), { - email: profile.email, - name: profile.name || '', - image: profile.image || '', - joinedDate: profile.joinedDate || new Date().toISOString(), - role: profile.role || 'Free' - }) - }, - - async getUserProfile(userId: string) { - return await redis.hgetall(KEYS.USER_PROFILE(userId)) - } -} -``` +## Setup Instructions -### Profile Context -```typescript -// lib/contexts/user-context.tsx -const UserProvider = ({ children }) => { - const { data: session } = useSession() - const [userProfile, setUserProfile] = useState(null) - - useEffect(() => { - if (session?.user) { - fetchUserProfile(session.user.id) - } - }, [session]) - - return ( - - {children} - - ) -} -``` +### 1. Create a Google Cloud Project -## Authentication Flow +- Visit [Google Cloud Console](https://console.cloud.google.com/) +- Click "Select a project" → "New Project" +- Name your project and click **Create** -### 1. Login Process -``` -User clicks "Sign in with Google" - ↓ -Google OAuth consent - ↓ -NextAuth callback processing - ↓ -Profile saved to Redis - ↓ -Session created - ↓ -User redirected to dashboard -``` +--- -### 2. Logout Process -```typescript -const handleLogout = async () => { - // Clear local state - clearMessages() - clearCredits() - - // Sign out from NextAuth - await signOut({ callbackUrl: '/' }) -} -``` +### 2. Configure OAuth Consent Screen -## Protected Routes - -### Page Protection -```typescript -// app/admin/page.tsx -export default function AdminPage() { - const { data: session, status } = useSession() - - if (status === "loading") return - - if (!session?.user?.isAdmin) { - redirect('/login') - } - - return -} -``` +- Go to `APIs & Services → OAuth consent screen` +- Choose **"External"** → Continue +- Fill in app details (name, email, etc.) +- Add test users for development use -### API Protection -```typescript -// Middleware for protected API routes -export async function authMiddleware(request: NextRequest) { - const token = await getToken({ req: request }) - - if (!token) { - return new Response('Unauthorized', { status: 401 }) - } - - // Add user info to request - request.userId = token.sub -} -``` +--- + +### 3. Create OAuth Credentials + +- Go to `APIs & Services → Credentials` +- Click `+ CREATE CREDENTIALS → OAuth client ID` +- Select: + - **Application type**: `Web Application` +- Add **authorized redirect URIs**, e.g.: -## Security Features - -### CSRF Protection -- Built-in NextAuth CSRF protection -- Secure cookie configuration -- SameSite cookie policies - -### Session Security -```typescript -// nextauth configuration -export default NextAuth({ - session: { - strategy: "jwt", - maxAge: 30 * 24 * 60 * 60, // 30 days - }, - jwt: { - secret: process.env.NEXTAUTH_SECRET, - }, - cookies: { - sessionToken: { - name: "next-auth.session-token", - options: { - httpOnly: true, - sameSite: "lax", - path: "/", - secure: process.env.NODE_ENV === "production", - }, - }, - }, -}) +```bash +http://localhost:3000/api/auth/callback/google +http://localhost:3000/auth/signin ``` -## Guest User Support - -### Anonymous Access -```typescript -// lib/store/freeTrialStore.ts -const useFreeTrialStore = create( - persist( - (set, get) => ({ - queriesUsed: 0, - maxQueries: 5, - - hasFreeTrial: () => get().queriesUsed < get().maxQueries, - }), - { name: 'free-trial-storage' } - ) -) +```bash +https://yourdomain.com/api/auth/callback/google +https://yourdomain.com/auth/signin ``` +- Click **Create** + +--- + +### 4. Set Environment Variables + +Create a `.env.local` file in your project root and add: -### Guest Session Handling -```typescript -// Guest users get temporary session IDs -const getGuestId = () => { - let guestId = localStorage.getItem('guestUserId') - if (!guestId) { - guestId = `guest-${Date.now()}` - localStorage.setItem('guestUserId', guestId) - } - return guestId -} -``` \ No newline at end of file +```env +GOOGLE_CLIENT_ID=your-client-id-here +GOOGLE_CLIENT_SECRET=your-client-secret-here \ No newline at end of file diff --git a/auto-analyst-frontend/lib/credits-config.ts b/auto-analyst-frontend/lib/credits-config.ts index 719659d0..1be559bc 100644 --- a/auto-analyst-frontend/lib/credits-config.ts +++ b/auto-analyst-frontend/lib/credits-config.ts @@ -49,9 +49,9 @@ export interface TrialConfig { * Trial period configuration - Change here to update across the entire app */ export const TRIAL_CONFIG: TrialConfig = { - duration: 15, - unit: 'minutes', - displayText: '15-Minute Free Trial', + duration: 2, + unit: 'days', + displayText: '2-Day Free Trial', credits: 500 } From 348f550a1c7c3c51f8df8e9aa51b04810fc3348f Mon Sep 17 00:00:00 2001 From: Ashad Qureshi Date: Mon, 30 Jun 2025 19:16:05 +0500 Subject: [PATCH 2/2] typo fix --- auto-analyst-frontend/docs/system/authentication.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/auto-analyst-frontend/docs/system/authentication.md b/auto-analyst-frontend/docs/system/authentication.md index 66a49c01..482d7c95 100644 --- a/auto-analyst-frontend/docs/system/authentication.md +++ b/auto-analyst-frontend/docs/system/authentication.md @@ -58,4 +58,5 @@ Create a `.env.local` file in your project root and add: ```env GOOGLE_CLIENT_ID=your-client-id-here -GOOGLE_CLIENT_SECRET=your-client-secret-here \ No newline at end of file +GOOGLE_CLIENT_SECRET=your-client-secret-here +``` \ No newline at end of file