Files
Michele bd3e1074a8 docs(01): create phase 1 plans - Foundation & Auth
Phase 01: Foundation & Auth
- 6 plans in 4 execution waves
- Wave 1: Project setup (01) + Database schema (02) [parallel]
- Wave 2: Email/password auth (03) + Google OAuth (04) [parallel]
- Wave 3: Middleware & route protection (05)
- Wave 4: Subscription management UI (06)

Requirements covered: AUTH-01, AUTH-02, AUTH-03
Ready for execution

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 03:12:38 +01:00

14 KiB

phase, plan, type, wave, depends_on, files_modified, autonomous, user_setup, must_haves
phase plan type wave depends_on files_modified autonomous user_setup must_haves
01-foundation-auth 04 execute 2
01-01
01-02
src/components/auth/google-button.tsx
src/app/(auth)/login/page.tsx
src/app/(auth)/register/page.tsx
docs/GOOGLE_OAUTH_SETUP.md
true
service why env_vars dashboard_config
google-cloud Google OAuth for social login
task location
Create OAuth 2.0 Client ID Google Cloud Console -> APIs & Services -> Credentials
task location value
Add authorized JavaScript origins OAuth Client -> Authorized JavaScript origins http://localhost:3000, https://your-domain.com
task location value
Add authorized redirect URI OAuth Client -> Authorized redirect URIs https://<project-ref>.supabase.co/auth/v1/callback
service why env_vars dashboard_config
supabase Enable Google OAuth provider
task location
Enable Google provider Supabase Dashboard -> Authentication -> Providers -> Google
task location
Paste Google Client ID and Secret Same settings page
truths artifacts key_links
User can click 'Accedi con Google' button
User is redirected to Google consent screen
User returns to app authenticated after consent
User session persists after Google login
path provides exports
src/components/auth/google-button.tsx Google Sign-In button component
GoogleSignInButton
path provides contains
docs/GOOGLE_OAUTH_SETUP.md Setup instructions for Google OAuth Google Cloud Console
from to via pattern
src/components/auth/google-button.tsx Supabase Auth signInWithOAuth signInWithOAuth.*google
from to via pattern
Google OAuth src/app/auth/callback/route.ts redirect after consent auth/callback
Implement Google OAuth login allowing users to sign in with their Google account.

Purpose: Enable social login per AUTH-02 requirement. Google OAuth provides frictionless registration/login.

Output: Working Google Sign-In button that authenticates users and creates their profile automatically.

<execution_context> @C:\Users\miche.claude/get-shit-done/workflows/execute-plan.md @C:\Users\miche.claude/get-shit-done/templates/summary.md </execution_context>

@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/phases/01-foundation-auth/01-RESEARCH.md @.planning/phases/01-foundation-auth/01-01-SUMMARY.md @.planning/phases/01-foundation-auth/01-02-SUMMARY.md Task 1: Create Google Sign-In button component src/components/auth/google-button.tsx Create the Google Sign-In button at src/components/auth/google-button.tsx:
```typescript
'use client'

import { createClient } from '@/lib/supabase/client'
import { Button } from '@/components/ui/button'
import { useState } from 'react'

// Simple Google icon SVG
function GoogleIcon({ className }: { className?: string }) {
  return (
    <svg className={className} viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
      <path
        d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"
        fill="#4285F4"
      />
      <path
        d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"
        fill="#34A853"
      />
      <path
        d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"
        fill="#FBBC05"
      />
      <path
        d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"
        fill="#EA4335"
      />
    </svg>
  )
}

export function GoogleSignInButton() {
  const [loading, setLoading] = useState(false)
  const supabase = createClient()

  async function handleGoogleSignIn() {
    setLoading(true)

    const { error } = await supabase.auth.signInWithOAuth({
      provider: 'google',
      options: {
        redirectTo: `${window.location.origin}/auth/callback`,
        queryParams: {
          access_type: 'offline',
          prompt: 'consent',
        },
      },
    })

    if (error) {
      console.error('Google sign-in error:', error)
      setLoading(false)
    }
    // Note: No need to handle success - user is redirected to Google
  }

  return (
    <Button
      type="button"
      variant="outline"
      onClick={handleGoogleSignIn}
      disabled={loading}
      className="w-full flex items-center justify-center gap-2"
    >
      <GoogleIcon className="w-5 h-5" />
      {loading ? 'Reindirizzamento...' : 'Accedi con Google'}
    </Button>
  )
}
```

Key points:
- Uses 'use client' since it needs browser APIs
- Uses createClient from lib/supabase/client.ts (browser client)
- redirectTo points to /auth/callback which handles the code exchange
- access_type: 'offline' requests refresh token
- prompt: 'consent' ensures user always sees consent screen (good for debugging)
- Italian button text per project requirement
- Component file exists - No TypeScript errors - Button renders with Google icon Google Sign-In button component created with proper OAuth configuration. Task 2: Add Google button to login and register pages src/app/(auth)/login/page.tsx src/app/(auth)/register/page.tsx src/components/auth/login-form.tsx src/components/auth/register-form.tsx Update login page to include Google button. Modify src/app/(auth)/login/page.tsx:
```typescript
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { LoginForm } from '@/components/auth/login-form'
import { GoogleSignInButton } from '@/components/auth/google-button'

export default function LoginPage() {
  return (
    <Card>
      <CardHeader className="text-center">
        <CardTitle>Accedi a Leopost</CardTitle>
        <CardDescription>
          Inserisci le tue credenziali per continuare
        </CardDescription>
      </CardHeader>
      <CardContent className="space-y-4">
        <GoogleSignInButton />

        <div className="relative">
          <div className="absolute inset-0 flex items-center">
            <span className="w-full border-t border-gray-300" />
          </div>
          <div className="relative flex justify-center text-xs uppercase">
            <span className="bg-white px-2 text-gray-500">oppure</span>
          </div>
        </div>

        <LoginForm />
      </CardContent>
    </Card>
  )
}
```

Update register page similarly. Modify src/app/(auth)/register/page.tsx:

```typescript
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { RegisterForm } from '@/components/auth/register-form'
import { GoogleSignInButton } from '@/components/auth/google-button'

export default function RegisterPage() {
  return (
    <Card>
      <CardHeader className="text-center">
        <CardTitle>Crea il tuo account</CardTitle>
        <CardDescription>
          Inizia a usare Leopost gratuitamente
        </CardDescription>
      </CardHeader>
      <CardContent className="space-y-4">
        <GoogleSignInButton />

        <div className="relative">
          <div className="absolute inset-0 flex items-center">
            <span className="w-full border-t border-gray-300" />
          </div>
          <div className="relative flex justify-center text-xs uppercase">
            <span className="bg-white px-2 text-gray-500">oppure</span>
          </div>
        </div>

        <RegisterForm />
      </CardContent>
    </Card>
  )
}
```

The divider uses "oppure" (Italian for "or") to separate social login from email form.
Google button appears FIRST (above the form) as it's the faster option.
- Login page shows Google button above email form - Register page shows Google button above email form - "oppure" divider separates the two methods - Pages render without errors Google Sign-In button integrated into login and registration pages. Task 3: Document Google OAuth setup process docs/GOOGLE_OAUTH_SETUP.md Create comprehensive setup documentation at docs/GOOGLE_OAUTH_SETUP.md:
```markdown
# Google OAuth Setup Guide

This guide explains how to configure Google OAuth for Leopost.

## Prerequisites

- Google Cloud account
- Supabase project created
- Access to Supabase Dashboard

## Step 1: Google Cloud Console Setup

1. Go to [Google Cloud Console](https://console.cloud.google.com/)

2. Create a new project or select existing one

3. Navigate to **APIs & Services > Credentials**

4. Click **Create Credentials > OAuth client ID**

5. If prompted, configure the OAuth consent screen:
   - User Type: External
   - App name: Leopost
   - User support email: your email
   - Developer contact: your email
   - Scopes: email, profile, openid (default)

6. Create OAuth Client ID:
   - Application type: **Web application**
   - Name: Leopost Web Client

7. Add **Authorized JavaScript origins**:
   ```
   http://localhost:3000
   https://your-production-domain.com
   ```

8. Add **Authorized redirect URIs**:
   ```
   https://<your-project-ref>.supabase.co/auth/v1/callback
   ```

   Find your project ref in Supabase Dashboard > Project Settings > General

9. Click **Create** and save the **Client ID** and **Client Secret**

## Step 2: Supabase Configuration

1. Go to [Supabase Dashboard](https://supabase.com/dashboard)

2. Select your project

3. Navigate to **Authentication > Providers**

4. Find **Google** and click to enable

5. Enter:
   - **Client ID**: From Google Cloud Console
   - **Client Secret**: From Google Cloud Console

6. Copy the **Callback URL** shown (should match what you entered in Google)

7. Click **Save**

## Step 3: Environment Variables

No additional environment variables needed for Google OAuth.
The configuration is stored in Supabase Dashboard.

Your existing `.env.local` should have:
```
NEXT_PUBLIC_SUPABASE_URL=your-project-url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
```

## Step 4: Test the Integration

1. Start development server: `npm run dev`

2. Go to http://localhost:3000/login

3. Click "Accedi con Google"

4. You should be redirected to Google consent screen

5. After consent, you should return to the app authenticated

6. Check Supabase Dashboard > Authentication > Users to verify user was created

## Troubleshooting

### "redirect_uri_mismatch" error

The redirect URI in Google Console doesn't match Supabase's callback URL.
- Verify the exact URL in Supabase Auth Providers matches Google Console
- Check for trailing slashes
- Ensure using HTTPS for Supabase callback

### "Access blocked: This app's request is invalid"

OAuth consent screen not configured or not published.
- Configure OAuth consent screen in Google Cloud Console
- For testing, add your email as a test user
- For production, submit for verification

### User created but profile missing

The database trigger might not have fired.
- Check if `on_auth_user_created` trigger exists
- Verify `handle_new_user` function has correct permissions
- Check Supabase logs for errors

### Session not persisting

Middleware might not be refreshing sessions.
- Ensure middleware.ts is in project root
- Check middleware matcher includes auth routes
- Verify cookies are being set correctly

## Security Notes

- Never commit Client Secret to version control
- For production, publish OAuth consent screen for verification
- Use a separate OAuth client for production vs development
- Regularly rotate Client Secrets

## Local Development vs Production

| Setting | Local | Production |
|---------|-------|------------|
| JavaScript origins | http://localhost:3000 | https://your-domain.com |
| Redirect URI | Same Supabase callback | Same Supabase callback |
| Consent screen | Testing mode | Published/Verified |
| Test users | Your email added | Not needed |
```

This documentation helps future developers (or the user) configure Google OAuth correctly.
- File exists at docs/GOOGLE_OAUTH_SETUP.md - Contains step-by-step instructions - Includes troubleshooting section - Covers both Google Cloud and Supabase configuration Google OAuth setup documentation created. After all tasks complete: 1. Google button appears on /login and /register pages 2. Clicking button redirects to Google (or shows error if not configured) 3. Documentation provides clear setup steps 4. No TypeScript or build errors

<success_criteria>

  • GoogleSignInButton component exists and renders
  • Login/register pages show Google option prominently
  • Setup documentation is comprehensive
  • OAuth flow uses correct callback URL (/auth/callback)
  • Italian text used throughout UI </success_criteria>
After completion, create `.planning/phases/01-foundation-auth/01-04-SUMMARY.md`