# Login API Implementation

This document describes the complete implementation of the user login feature for the MaplePress frontend, integrated with the MaplePress backend API.

## Overview

The login feature allows existing users to authenticate with their email and password credentials. Upon successful login, users receive authentication tokens and are automatically logged in to their dashboard.

## Backend API Endpoint

**Endpoint**: `POST /api/v1/login`
**Authentication**: None required (public endpoint)
**Documentation**: `/cloud/maplepress-backend/docs/API.md` (lines 168-228)

### Request Structure

```json
{
  "email": "user@example.com",
  "password": "SecurePassword123!"
}
```

### Response Structure

```json
{
  "user_id": "550e8400-e29b-41d4-a716-446655440000",
  "user_email": "user@example.com",
  "user_name": "John Doe",
  "user_role": "user",
  "tenant_id": "650e8400-e29b-41d4-a716-446655440000",
  "session_id": "750e8400-e29b-41d4-a716-446655440000",
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "access_expiry": "2024-10-24T12:15:00Z",
  "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refresh_expiry": "2024-10-31T00:00:00Z",
  "login_at": "2024-10-24T00:00:00Z"
}
```

### Key Differences from Registration

The login endpoint differs from registration in several ways:
- **Simpler Request**: Only email and password required
- **No Tenant Details in Response**: Tenant name/slug not included
- **Login Timestamp**: Includes `login_at` instead of `created_at`
- **Existing Session**: Authenticates existing user, doesn't create new account

## Frontend Implementation

### 1. LoginService (`src/services/API/LoginService.js`)

Handles direct communication with the backend login API.

**Key Features:**
- Request validation (required fields)
- Request body formatting (snake_case for backend)
- Response transformation (camelCase for frontend)
- User-friendly error message mapping
- Rate limit error handling
- Account lockout detection

**Methods:**
- `login(credentials)` - Main login method

**Usage:**
```javascript
import LoginService from './services/API/LoginService';

const response = await LoginService.login({
  email: "user@example.com",
  password: "SecurePassword123!",
});
```

### 2. AuthManager Enhancement (`src/services/Manager/AuthManager.js`)

Updated to support login functionality while maintaining registration support.

**New/Updated Methods:**
- `login(email, password)` - Login and store auth data
- `storeAuthData(authResponse)` - Updated to handle optional tenant fields

**Key Features:**
- Handles both registration and login responses
- Gracefully handles missing tenant name/slug from login
- Maintains same token storage mechanism
- Consistent session management

**Login Flow:**
```javascript
const authManager = useAuth().authManager;

// Login
await authManager.login("user@example.com", "password123");

// Check authentication
if (authManager.isAuthenticated()) {
  const user = authManager.getUser();
  const tenant = authManager.getTenant();
}
```

### 3. Login Page (`src/pages/Auth/Login.jsx`)

Simple and clean login form ready for production use.

**Form Fields:**
- Email Address (required)
- Password (required)

**Features:**
- Email validation (HTML5 + backend)
- Loading state during submission
- Error message display
- Navigation to registration
- Navigation back to home

## Data Flow

```
User enters credentials
    ↓
Login.jsx validates data
    ↓
AuthManager.login(email, password)
    ↓
LoginService.login(credentials)
    ↓
HTTP POST to /api/v1/login
    ↓
Backend validates credentials
    ↓
Backend returns tokens and user data
    ↓
LoginService transforms response
    ↓
AuthManager stores tokens in localStorage
    ↓
User redirected to /dashboard
```

## Validation Rules

### Frontend Validation

1. **Email**: Required, valid email format (HTML5)
2. **Password**: Required (no client-side length check for login)

### Backend Validation

Backend performs:
- Email format validation
- Email normalization (lowercase, trim)
- Password verification against stored hash
- Rate limiting checks
- Account lockout checks

## Error Handling

### Error Messages

Errors are mapped to user-friendly messages:

| Backend Error | Frontend Message |
|--------------|------------------|
| "Invalid email or password" | "Invalid email or password. Please try again." |
| "X attempts remaining" | Original message with attempt counter |
| "locked" or "Too many" | "Account temporarily locked due to too many failed attempts. Please try again later." |
| "invalid email" | "Invalid email address." |

### Rate Limiting & Account Lockout

The backend implements sophisticated rate limiting:

**Per-IP Rate Limiting:**
- Limit: Multiple attempts per 15 minutes
- Response: `429 Too Many Requests`
- Header: `Retry-After: 900` (15 minutes)

**Per-Account Rate Limiting:**
- Limit: 5 failed attempts
- Lockout: 30 minutes after 5 failures
- Response: `429 Too Many Requests`
- Header: `Retry-After: 1800` (30 minutes)
- Warning: Shows remaining attempts when ≤ 3

**Behavior:**
1. First 2 failures: Generic error message
2. 3rd-5th failure: Shows remaining attempts
3. After 5th failure: Account locked for 30 minutes
4. Successful login: Resets all counters

### Security Event Logging

Backend logs security events for:
- Failed login attempts (with email hash)
- Successful logins (with email hash)
- IP rate limit exceeded
- Account lockouts

## Security Features

1. **Token Storage**: Tokens stored in localStorage
2. **Token Expiry**: Automatic expiry checking
3. **Rate Limiting**: Backend enforces rate limits
4. **Account Lockout**: Protects against brute force
5. **Email Normalization**: Prevents bypass via casing
6. **Secure Logging**: PII never logged, only hashes
7. **Password Hash Verification**: Uses bcrypt on backend

## Token Lifetime

- **Access Token**: 15 minutes
- **Refresh Token**: 7 days
- **Session**: 14 days (max inactivity)

## Testing the Login Flow

### 1. Prerequisites

Ensure you have a registered user. If not, register first:

```bash
# Navigate to registration
http://localhost:5173/register

# Or use curl to register via backend
curl -X POST http://localhost:8000/api/v1/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "test@example.com",
    "password": "SecurePass123!",
    "name": "Test User",
    "tenant_name": "Test Corp",
    "tenant_slug": "test-corp",
    "agree_terms_of_service": true
  }'
```

### 2. Start Services

```bash
# Backend
cd cloud/maplepress-backend
task dev

# Frontend
cd web/maplepress-frontend
npm run dev
```

### 3. Navigate to Login

Open browser to: `http://localhost:5173/login`

### 4. Fill Form

- **Email**: test@example.com
- **Password**: SecurePass123!

### 5. Submit

Click "Sign In" button

### 6. Expected Result

- Loading state appears ("Signing in...")
- Request sent to backend
- Tokens stored in localStorage
- User redirected to `/dashboard`
- Dashboard shows user information

### 7. Verify in Browser Console

```javascript
// Check stored tokens
localStorage.getItem('maplepress_access_token')
localStorage.getItem('maplepress_user')
localStorage.getItem('maplepress_tenant')

// Check service instance
window.maplePressServices.authManager.isAuthenticated() // true
window.maplePressServices.authManager.getUser()
// Returns: { id: "...", email: "test@example.com", name: "Test User", role: "..." }

window.maplePressServices.authManager.getTenant()
// Returns: { id: "...", name: null, slug: null }
// Note: name/slug are null because login endpoint doesn't provide them
```

## Error Testing

### Test Invalid Credentials

```javascript
// In login form, enter:
Email: test@example.com
Password: WrongPassword123

// Expected: "Invalid email or password. Please try again."
```

### Test Rate Limiting

```javascript
// Attempt login 3 times with wrong password
// Expected on 3rd attempt: "Invalid email or password. 2 attempts remaining before account lockout."

// Attempt 2 more times
// Expected on 5th attempt: "Account temporarily locked due to too many failed attempts. Please try again later."
```

### Test Missing Fields

```javascript
// Leave email blank
// Expected: Browser validation error (HTML5 required)

// Leave password blank
// Expected: Browser validation error (HTML5 required)
```

## Differences from Registration

| Feature | Registration | Login |
|---------|-------------|-------|
| Request Fields | 10+ fields | 2 fields only |
| Response Fields | Includes tenant name/slug | No tenant name/slug |
| Timestamp | `created_at` | `login_at` |
| Creates User | Yes | No |
| Creates Tenant | Yes | No |
| Terms Agreement | Required | Not needed |
| Organization Info | Required | Not needed |

## Token Storage Compatibility

Both registration and login use the same storage mechanism:

```javascript
// Storage Keys (7 total)
maplepress_access_token     // JWT access token
maplepress_refresh_token    // JWT refresh token
maplepress_access_expiry    // ISO date string
maplepress_refresh_expiry   // ISO date string
maplepress_user            // JSON: {id, email, name, role}
maplepress_tenant          // JSON: {id, name, slug}
maplepress_session_id      // Session UUID
```

**Note**: After login, `tenant.name` and `tenant.slug` will be `null`. This is expected behavior. If needed, fetch tenant details separately using the `/api/v1/tenants/{id}` endpoint.

## Session Persistence

Authentication state persists across:
- Page refreshes
- Browser restarts (if localStorage not cleared)
- Tab changes

Session is cleared on:
- User logout
- Token expiry detection
- Manual localStorage clear

## Integration with Dashboard

The dashboard automatically checks authentication:

```javascript
// Dashboard.jsx
useEffect(() => {
  if (!authManager.isAuthenticated()) {
    navigate("/login");
    return;
  }

  const userData = authManager.getUser();
  setUser(userData);
}, [authManager, navigate]);
```

## API Client Configuration

The `ApiClient` automatically handles:
- JSON content-type headers
- Request/response transformation
- Error parsing
- Authentication headers (for protected endpoints)

**Note**: Login endpoint doesn't require authentication headers, but subsequent API calls will use the stored access token.

## Future Enhancements

### Planned Features

- [ ] "Remember Me" checkbox (longer session)
- [ ] "Forgot Password" link
- [ ] Social authentication (Google, GitHub)
- [ ] Two-factor authentication (2FA/TOTP)
- [ ] Session management (view active sessions)
- [ ] Device fingerprinting
- [ ] Suspicious login detection

### Security Improvements

- [ ] CSRF token implementation
- [ ] HTTP-only cookie option
- [ ] Session fingerprinting
- [ ] Geolocation tracking
- [ ] Email notification on new login
- [ ] Passwordless login option

## Troubleshooting

### "Invalid email or password" but credentials are correct

**Possible causes:**
1. Email case sensitivity - backend normalizes to lowercase
2. Extra whitespace in password field
3. User not yet registered
4. Account locked due to previous failed attempts

**Solution:**
- Wait 30 minutes if account is locked
- Try registering if user doesn't exist
- Check browser console for detailed errors

### Tokens not being stored

**Possible causes:**
1. localStorage disabled in browser
2. Private/Incognito mode restrictions
3. Browser extension blocking storage

**Solution:**
- Enable localStorage in browser settings
- Use regular browser window
- Disable blocking extensions temporarily

### Redirected back to login after successful login

**Possible causes:**
1. Token expiry detection triggered
2. Token format invalid
3. localStorage cleared between operations

**Solution:**
- Check browser console for errors
- Verify localStorage contains tokens
- Check token expiry dates

## Related Files

### Created Files
```
src/services/API/LoginService.js
```

### Modified Files
```
src/services/Manager/AuthManager.js
src/pages/Auth/Login.jsx
```

### Backend Reference Files
```
cloud/maplepress-backend/docs/API.md
cloud/maplepress-backend/internal/interface/http/dto/gateway/login_dto.go
cloud/maplepress-backend/internal/interface/http/handler/gateway/login_handler.go
```

## Related Documentation

- [REGISTRATION_API.md](./REGISTRATION_API.md) - Registration implementation
- [ARCHITECTURE.md](./ARCHITECTURE.md) - Frontend architecture overview
- [README.md](./README.md) - Getting started guide
- [Backend API Documentation](../../cloud/maplepress-backend/docs/API.md) - Complete API reference

## Support

For issues:
1. Check backend logs: `docker logs mapleopentech_backend`
2. Check browser console for errors
3. Verify backend is running on port 8000
4. Test backend endpoint directly with curl
5. Check rate limiting status (wait 30 minutes if locked)
