npm package: @io-saas/client
Description: Official IO SaaS Authentication Client SDK for JavaScript/TypeScript
Author: IO SaaS
Latest version: 1.0.3

# @io-saas/client

SDK officiel JavaScript/TypeScript pour intégrer l'authentification IO SaaS dans vos applications.

## 🚀 Installation

```bash
npm install @io-saas/client
# ou
yarn add @io-saas/client
# ou
pnpm add @io-saas/client
```

## 📋 Prérequis

1. Créez un compte développeur sur [IO SaaS Dashboard](https://dashboard.io-saas.com)
2. Créez un projet et récupérez votre **API Key**
3. Configurez les méthodes d'authentification autorisées (Email/Password, Google, GitHub, etc.)

## 🔧 Configuration

### Initialisation du Client

```typescript
import { IOSaasClient } from '@io-saas/client';

const auth = new IOSaasClient({
  apiKey: 'io_live_xxxxxxxxxxxxx', // Votre API Key (live ou test)
  projectId: 'your-project-id'      // Votre Project ID
});
```

**Note**: L'URL de l'API est automatiquement détectée selon votre clé :
- `io_test_xxxxx` → `http://localhost:8000/api/v1` (développement)
- `io_live_xxxxx` → `https://api.io-saas.com/api/v1` (production)

## 📚 Utilisation

### 1. Inscription (Email/Password)

```typescript
try {
  const response = await auth.signUp({
    email: 'user@example.com',
    password: 'securepassword123',
    full_name: 'John Doe' // Optionnel
  });

  console.log('User:', response.user);
  console.log('Access Token:', response.access_token);
  console.log('Refresh Token:', response.refresh_token);

  // Sauvegarder les tokens (localStorage, cookies, etc.)
  localStorage.setItem('access_token', response.access_token);
  localStorage.setItem('refresh_token', response.refresh_token);
} catch (error) {
  console.error('Signup failed:', error.message);
}
```

### 2. Connexion (Email/Password)

```typescript
try {
  const response = await auth.signIn({
    email: 'user@example.com',
    password: 'securepassword123'
  });

  console.log('User:', response.user);
  
  // Sauvegarder les tokens
  localStorage.setItem('access_token', response.access_token);
  localStorage.setItem('refresh_token', response.refresh_token);
} catch (error) {
  console.error('Sign in failed:', error.message);
}
```

### 3. Récupérer l'utilisateur actuel

```typescript
try {
  const accessToken = localStorage.getItem('access_token');
  const user = await auth.getCurrentUser(accessToken);

  console.log('Current user:', user);
  console.log('Email:', user.email);
  console.log('Full name:', user.full_name);
  console.log('Is verified:', user.is_verified);
} catch (error) {
  console.error('Failed to get user:', error.message);
  // Token expiré ou invalide, rediriger vers login
}
```

### 4. Rafraîchir le token

```typescript
try {
  const refreshToken = localStorage.getItem('refresh_token');
  const tokens = await auth.refreshToken(refreshToken);

  // Mettre à jour les tokens
  localStorage.setItem('access_token', tokens.access_token);
  localStorage.setItem('refresh_token', tokens.refresh_token);
} catch (error) {
  console.error('Token refresh failed:', error.message);
  // Rediriger vers login
}
```

### 5. Déconnexion

```typescript
try {
  const refreshToken = localStorage.getItem('refresh_token');
  await auth.signOut(refreshToken);

  // Supprimer les tokens
  localStorage.removeItem('access_token');
  localStorage.removeItem('refresh_token');

  // Rediriger vers la page de connexion
  window.location.href = '/login';
} catch (error) {
  console.error('Sign out failed:', error.message);
}
```

### 6. Authentification OAuth

#### Google

```typescript
// Sur la page de login, bouton "Sign in with Google"
async function handleGoogleSignIn() {
  try {
    await auth.signInWithGoogle('https://yourapp.com/auth/callback');
    // L'utilisateur est redirigé vers Google
  } catch (error) {
    console.error('Google sign in failed:', error.message);
  }
}

// Sur la page de callback (/auth/callback)
async function handleCallback() {
  const urlParams = new URLSearchParams(window.location.search);
  const code = urlParams.get('code');
  const state = urlParams.get('state');

  if (code) {
    try {
      const response = await auth.handleOAuthCallback('google', code, state);
      
      // Sauvegarder les tokens
      localStorage.setItem('access_token', response.access_token);
      localStorage.setItem('refresh_token', response.refresh_token);

      // Rediriger vers le dashboard
      window.location.href = '/dashboard';
    } catch (error) {
      console.error('OAuth callback failed:', error.message);
    }
  }
}
```

#### GitHub

```typescript
await auth.signInWithGitHub('https://yourapp.com/auth/callback');
```

#### Facebook

```typescript
await auth.signInWithFacebook('https://yourapp.com/auth/callback');
```

#### Apple

```typescript
await auth.signInWithApple('https://yourapp.com/auth/callback');
```

## 🎨 Exemple Complet (React)

```typescript
import React, { useState, useEffect } from 'react';
import { IOSaasClient } from '@io-saas/client';

const auth = new IOSaasClient({
  apiKey: process.env.REACT_APP_IO_SAAS_API_KEY!,
  projectId: process.env.REACT_APP_IO_SAAS_PROJECT_ID!
});

function App() {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    // Vérifier si l'utilisateur est connecté
    const checkAuth = async () => {
      const accessToken = localStorage.getItem('access_token');
      
      if (accessToken) {
        try {
          const currentUser = await auth.getCurrentUser(accessToken);
          setUser(currentUser);
        } catch (error) {
          // Token invalide, essayer de rafraîchir
          const refreshToken = localStorage.getItem('refresh_token');
          if (refreshToken) {
            try {
              const tokens = await auth.refreshToken(refreshToken);
              localStorage.setItem('access_token', tokens.access_token);
              localStorage.setItem('refresh_token', tokens.refresh_token);
              
              const currentUser = await auth.getCurrentUser(tokens.access_token);
              setUser(currentUser);
            } catch (refreshError) {
              // Rediriger vers login
              localStorage.clear();
            }
          }
        }
      }
      
      setLoading(false);
    };

    checkAuth();
  }, []);

  const handleSignUp = async (email: string, password: string) => {
    try {
      const response = await auth.signUp({ email, password });
      localStorage.setItem('access_token', response.access_token);
      localStorage.setItem('refresh_token', response.refresh_token);
      setUser(response.user);
    } catch (error) {
      alert(error.message);
    }
  };

  const handleSignIn = async (email: string, password: string) => {
    try {
      const response = await auth.signIn({ email, password });
      localStorage.setItem('access_token', response.access_token);
      localStorage.setItem('refresh_token', response.refresh_token);
      setUser(response.user);
    } catch (error) {
      alert(error.message);
    }
  };

  const handleSignOut = async () => {
    try {
      const refreshToken = localStorage.getItem('refresh_token');
      await auth.signOut(refreshToken!);
      localStorage.clear();
      setUser(null);
    } catch (error) {
      alert(error.message);
    }
  };

  if (loading) return <div>Loading...</div>;

  if (!user) {
    return (
      <div>
        <h1>Login</h1>
        <button onClick={() => handleSignIn('user@example.com', 'password')}>
          Sign In
        </button>
        <button onClick={() => auth.signInWithGoogle('http://localhost:3000/callback')}>
          Sign In with Google
        </button>
      </div>
    );
  }

  return (
    <div>
      <h1>Welcome, {user.full_name || user.email}!</h1>
      <button onClick={handleSignOut}>Sign Out</button>
    </div>
  );
}

export default App;
```

## 🔐 Méthodes d'Authentification Supportées

| Méthode | Description | Activation |
|---------|-------------|------------|
| **Email/Password** | Authentification classique avec email et mot de passe | Activé par défaut |
| **Google OAuth** | Connexion avec compte Google | À activer dans le dashboard |
| **GitHub OAuth** | Connexion avec compte GitHub | À activer dans le dashboard |
| **Facebook OAuth** | Connexion avec compte Facebook | À activer dans le dashboard |
| **Apple Sign In** | Connexion avec compte Apple | À activer dans le dashboard |

## 📊 Types TypeScript

```typescript
interface IOSaasConfig {
  apiKey: string;      // Format: io_test_xxxxx ou io_live_xxxxx
  projectId: string;   // UUID de votre projet
}

interface SignUpData {
  email: string;
  password: string;
  full_name?: string;
}

interface SignInData {
  email: string;
  password: string;
}

interface EndUser {
  id: string;
  email: string;
  full_name?: string;
  avatar_url?: string;
  is_verified: boolean;
  created_at: string;
}

interface AuthResponse {
  user: EndUser;
  access_token: string;
  refresh_token: string;
  token_type: string;
}

interface AuthTokens {
  access_token: string;
  refresh_token: string;
  token_type: string;
}

type OAuthProvider = 'google' | 'github' | 'facebook' | 'apple';
```

## 🛡️ Sécurité

### Bonnes Pratiques

1. **Ne jamais exposer votre API Key côté client** si elle est de type `live`
2. **Utilisez HTTPS** en production
3. **Stockez les tokens de manière sécurisée** (httpOnly cookies recommandé)
4. **Rafraîchissez les tokens** avant leur expiration
5. **Validez toujours les tokens côté serveur** pour les opérations sensibles

### Environnements

- **Test**: `io_test_xxxxx` - Pour le développement et les tests
- **Live**: `io_live_xxxxx` - Pour la production

## 🌐 URLs des Endpoints

| Endpoint | Méthode | Description |
|----------|---------|-------------|
| `/client/signup` | POST | Inscription avec email/password |
| `/client/signin` | POST | Connexion avec email/password |
| `/client/me` | GET | Récupérer l'utilisateur actuel |
| `/client/refresh` | POST | Rafraîchir le token |
| `/client/signout` | POST | Déconnexion |
| `/client/oauth/{provider}/authorize` | GET | Obtenir l'URL OAuth |
| `/client/oauth/{provider}/callback` | GET | Callback OAuth |

## 📝 Licence

MIT

## 🤝 Support

- Documentation: https://docs.io-saas.com
- Support: support@io-saas.com
- GitHub: https://github.com/io-saas/client-sdk

---

Créé avec ❤️ par l'équipe IO SaaS