# User Authentication Module (Google OAuth)

This module provides Google OAuth authentication for users in the Buddy Mentor API.

## Features

- ✅ Google OAuth 2.0 authentication
- ✅ ID Token validation
- ✅ Server-side callback handling
- ✅ JWT token generation
- ✅ Refresh token management
- ✅ User profile extraction from Google

## Folder Structure

```
src/modules/users/userAuth/
├── auth.controller.js       ← API endpoints
├── auth.service.js          ← Business logic
├── auth.routes.js           ← Route definitions
├── google.service.js        ← Google OAuth integration
└── README.md                ← This file
```

## Environment Variables

Add to `.env`:

```env
GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=your-client-secret
GOOGLE_REDIRECT_URI=http://localhost:5005/api/v1/auth/google/callback
FRONTEND_REDIRECT_URL=http://localhost:5000/
```

## API Endpoints

### 1. Get Google OAuth URL

**GET** `/api/v1/auth/google/url`

Returns the Google OAuth authorization URL that redirects users to Google's consent screen.

**Response:**
```json
{
  "success": true,
  "message": "Google OAuth URL generated",
  "data": {
    "url": "https://accounts.google.com/o/oauth2/v2/auth?..."
  }
}
```

**Usage:**
```javascript
// Frontend
const response = await fetch('/api/v1/auth/google/url');
const { data } = await response.json();
window.location.href = data.url; // Redirect to Google
```

---

### 2. Google OAuth Callback

**GET** `/api/v1/auth/google/callback`

Callback endpoint that Google redirects to after user grants permission. Handles the authorization code and creates a session.

**Query Parameters:**
- `code` (required): Authorization code from Google
- `state` (optional): State parameter for CSRF protection

**Behavior:**
- Exchanges code for access token
- Validates ID token
- Creates or finds user in database
- Generates JWT tokens
- Redirects to frontend with token in URL

**Redirect URL Format:**
```
http://localhost:5000/?token=...&refreshToken=...&user={"id":"...","email":"...","name":"...","avatar":"...","provider":"google","isEmailVerified":true}&provider=google
```

---

### 3. Sign In with Google (Mobile/Frontend)

**POST** `/api/v1/auth/google/signin`

Alternative endpoint for mobile apps or frontend implementations that handle Google OAuth directly and send the ID token.

**Request Body:**
```json
{
  "idToken": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjEifQ..."
}
```

**Response:**
```json
{
  "success": true,
  "message": "Signed in with Google successfully",
  "data": {
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "user": {
      "id": "google-user-id",
      "email": "user@gmail.com",
      "name": "John Doe",
      "avatar": "https://lh3.googleusercontent.com/...",
      "provider": "google",
      "isEmailVerified": true
    }
  }
}
```

**Usage:**
```javascript
// Frontend (with Google SDK)
import { GoogleLogin } from '@react-oauth/google';

function LoginButton() {
  const handleSuccess = async (credentialResponse) => {
    const response = await fetch('/api/v1/auth/google/signin', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ idToken: credentialResponse.credential })
    });
    const { data } = await response.json();
    localStorage.setItem('token', data.token);
    localStorage.setItem('refreshToken', data.refreshToken);
  };

  return <GoogleLogin onSuccess={handleSuccess} />;
}
```

## Architecture

### GoogleService (`google.service.js`)

Handles all Google OAuth interactions:

```javascript
// Get OAuth URL
const url = googleService.getAuthUrl();

// Exchange code for user data
const userData = await googleService.getGoogleUser(code);

// Validate ID token
const result = await googleService.validateIdToken(idToken);
```

### AuthService (`auth.service.js`)

Handles authentication business logic:

```javascript
// Find or create user from OAuth data
const user = await AuthService.findOrCreateUser(userData);

// Generate tokens
const token = AuthService.generateAccessToken(user, secret, expiresIn);
const refreshToken = AuthService.generateRefreshToken(userId, metadata);

// Generate complete token response
const response = AuthService.generateTokenResponse(user, refreshToken);

// Validate OAuth user data
AuthService.validateOAuthUserData(userData);
```

### AuthController (`auth.controller.js`)

Exposes API endpoints:

```javascript
// GET /auth/google/url
AuthController.getGoogleAuthUrl();

// GET /auth/google/callback
AuthController.googleCallback();

// POST /auth/google/signin
AuthController.signWithGoogle();
```

## Implementation Flow

### Server-Side Flow (Web Apps)

```
1. User clicks "Sign in with Google"
   ↓
2. Frontend calls GET /api/v1/auth/google/url
   ↓
3. Frontend redirects to Google OAuth URL
   ↓
4. User grants permission on Google
   ↓
5. Google redirects to GET /api/v1/auth/google/callback?code=...
   ↓
6. Backend exchanges code for tokens and user data
   ↓
7. Backend creates/finds user in database
   ↓
8. Backend generates JWT tokens
   ↓
9. Backend redirects to frontend with tokens in URL
   ↓
10. Frontend extracts tokens from URL and stores them
```

### Client-Side Flow (Mobile Apps / Frontend SDKs)

```
1. Frontend integrates Google SDK
   ↓
2. User clicks "Sign in with Google"
   ↓
3. Google SDK handles OAuth flow directly
   ↓
4. SDK returns ID token to frontend
   ↓
5. Frontend sends POST /api/v1/auth/google/signin with idToken
   ↓
6. Backend validates token and creates/finds user
   ↓
7. Backend generates JWT tokens
   ↓
8. Backend returns tokens and user data
   ↓
9. Frontend stores tokens locally
```

## Data Models

### User Data from Google

```javascript
{
  provider: 'google',
  providerId: 'google-user-id',
  email: 'user@gmail.com',
  name: 'John Doe',
  avatar: 'https://lh3.googleusercontent.com/...',
  isEmailVerified: true
}
```

### Token Response

```javascript
{
  token: 'jwt-token...',
  refreshToken: 'jwt-token...',
  user: {
    id: 'user-id',
    email: 'user@gmail.com',
    name: 'John Doe',
    avatar: 'https://lh3.googleusercontent.com/...',
    provider: 'google',
    isEmailVerified: true
  }
}
```

## Error Handling

All endpoints use the centralized `asyncHandler` for error handling.

**Common Errors:**

| Status | Error | Cause |
|--------|-------|-------|
| 400 | Authorization code is required | Missing `code` query parameter |
| 400 | ID token is required | Missing `idToken` in request body |
| 401 | Google token validation failed | Invalid or expired ID token |
| 503 | Google OAuth is not configured | Missing env variables |

## Security Considerations

1. **CSRF Protection**: Use `state` parameter in OAuth flow
2. **Token Validation**: Always verify ID tokens with Google
3. **HTTPS**: Use HTTPS in production (required by Google)
4. **Redirect URL**: Configure `GOOGLE_REDIRECT_URI` to match Google Console settings
5. **Secrets**: Never expose `GOOGLE_CLIENT_SECRET` to frontend
6. **Token Storage**: Store tokens securely (httpOnly cookies recommended)

## Setup Instructions

### 1. Create Google OAuth Credentials

1. Go to [Google Cloud Console](https://console.cloud.google.com/)
2. Create a new project
3. Enable Google+ API
4. Create OAuth 2.0 credentials (Web application)
5. Add authorized redirect URIs:
   - Development: `http://localhost:5005/api/v1/auth/google/callback`
   - Production: `https://yourdomain.com/api/v1/auth/google/callback`
6. Copy Client ID and Client Secret

### 2. Configure Environment

```bash
# .env
GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=your-client-secret
GOOGLE_REDIRECT_URI=http://localhost:5005/api/v1/auth/google/callback
FRONTEND_REDIRECT_URL=http://localhost:5000/
```

### 3. Install Dependencies

```bash
npm install google-auth-library
```

### 4. Update Database (Future Implementation)

Add OAuth user fields to User model:
- `provider` (string): OAuth provider name
- `providerId` (string): Provider-specific user ID
- `refreshTokens` (array): Array of refresh token documents

### 5. Test Endpoints

```bash
# Get OAuth URL
curl http://localhost:5005/api/v1/auth/google/url

# Sign in with ID Token (mobile flow)
curl -X POST http://localhost:5005/api/v1/auth/google/signin \
  -H "Content-Type: application/json" \
  -d '{"idToken":"your-id-token"}'
```

## Future Enhancements

- [ ] Database integration for user persistence
- [ ] Refresh token rotation
- [ ] OAuth state parameter for CSRF protection
- [ ] Social account linking
- [ ] Multiple OAuth providers (GitHub, Facebook, etc.)
- [ ] Role-based access control after OAuth
- [ ] Email verification handling
- [ ] Account linking for existing users

## Testing

### Unit Tests

```javascript
// Test GoogleService
describe('GoogleService', () => {
  it('should generate valid OAuth URL', () => {
    const url = googleService.getAuthUrl();
    expect(url).toContain('https://accounts.google.com');
  });

  it('should validate ID token', async () => {
    const result = await googleService.validateIdToken(validToken);
    expect(result.valid).toBe(true);
  });
});
```

### Integration Tests

```javascript
// Test API endpoints
describe('Auth Routes', () => {
  it('GET /auth/google/url should return OAuth URL', async () => {
    const response = await request(app).get('/api/v1/auth/google/url');
    expect(response.status).toBe(200);
    expect(response.body.data.url).toContain('accounts.google.com');
  });
});
```

## Support

For issues or questions:
1. Check Google OAuth [documentation](https://developers.google.com/identity/protocols/oauth2)
2. Review error messages in server logs
3. Verify environment variables are set correctly
4. Test with Google's [OAuth Playground](https://developers.google.com/oauthplayground)
