npm package: @stavbl/web-client-sdk
Description: A specialized web client SDK for secure frontend authentication URL validation, designed to work seamlessly with the Glide Backend SDK. Supports React, Vue, and Angular frameworks.
Latest version: 2.2.0-alpha.5

# Glide-Web-Client-SDK

A specialized web client SDK for secure frontend authentication URL validation, designed to work seamlessly with the Glide Backend SDK. Supports React, Vue, and Angular frameworks.

## Features

- 🔒 Client-side authentication URL validation
- 🌐 Multiple authentication methods:
  - Invisible iframe integration
  - Popup window authentication
  - Redirect-based flow
- 📱 Secure Phone Authentication:
  - Digital Credentials API integration
  - Secure phone number retrieval
  - Phone number verification
  - Carrier eligibility detection
  - Comprehensive error handling
  - Real-time user feedback
- ⚛️ React hooks integration
- 💚 Vue 3 composition API support
- 🅰️ Angular service integration
- 🔧 Vanilla JavaScript/TypeScript support
- 📦 TypeScript support out of the box

## Installation

```bash
npm install glide-web-client-sdk
```

### CDN Usage

You can also include the SDK directly in your HTML file using the CDN:

```html
<script src="https://unpkg.com/web-client-sdk@1.0.15/dist/browser/web-client-sdk.min.js"></script>
```

## Purpose

The Glide-Web-Client-SDK is designed to enhance security by providing client-side validation of authentication URLs received from the backend SDK. This additional layer of security ensures that authentication processes are verified on both server and client sides.

## NEW: Secure Phone Authentication

The SDK now includes support for secure phone authentication using the device's built-in security features. This enables secure phone number retrieval and verification directly from the browser with comprehensive error handling for carrier eligibility.

### Quick Example (React)

```typescript
import { usePhoneAuth } from 'glide-web-client-sdk/react';

function CheckoutForm() {
  const { getPhoneNumber, isLoading, error, result } = usePhoneAuth({
    endpoints: {
      prepare: '/api/phone-auth/prepare',
      process: '/api/phone-auth/process'
    }
  });
  
  const handleVerify = async () => {
    try {
      const result = await getPhoneNumber();
      console.log('Phone:', result.phoneNumber);
    } catch (error) {
      if (error.code === 'NOT_ELIGIBLE') {
        // Handle carrier not supported
        alert(`Your carrier (${error.details?.carrierName}) doesn't support phone verification.`);
      } else {
        console.error('Phone verification failed:', error.message);
      }
    }
  };
  
  return (
    <div>
      <button onClick={handleVerify} disabled={isLoading}>
        {isLoading ? 'Verifying...' : 'Verify with Phone'}
      </button>
      {error && (
        <div>
          Error: {error.message}
          {error.code === 'NOT_ELIGIBLE' && (
            <p>Try an alternative verification method.</p>
          )}
        </div>
      )}
    </div>
  );
}
```

### Error Handling

The SDK provides detailed error information with specific handling for carrier eligibility:

- **`NOT_ELIGIBLE`**: User's carrier doesn't support phone verification
- **`API_ERROR`**: Backend API errors with endpoint details
- **`USER_DENIED`**: User declined the verification prompt
- **`BROWSER_NOT_SUPPORTED`**: Browser doesn't support required APIs
- **`NETWORK_ERROR`**: Network connectivity issues

### Framework Support

Phone authentication is available across all supported frameworks:

```typescript
// React
import { usePhoneAuth } from 'glide-web-client-sdk/react';

// Vue 3
import { usePhoneAuth } from 'glide-web-client-sdk/vue';

// Angular
import { PhoneAuthService } from 'glide-web-client-sdk/angular';

// Vanilla JS/TS
import { PhoneAuthManager } from 'glide-web-client-sdk/vanilla';
```

For complete Phone Authentication documentation, see [docs/phone-auth.md](docs/phone-auth.md).

## Authentication Methods

### 1. Invisible iframe
Performs authentication in a hidden iframe, providing a seamless user experience without visible UI changes.

```typescript
const { authenticate } = useAuth('https://auth.example.com', {
  method: 'iframe',
  onComplete: (token) => {
    console.log('Authentication completed:', token);
  }
});
```

### 2. Popup Window
Opens a popup window for authentication, suitable for scenarios requiring user interaction.

```typescript
const { authenticate } = useAuth('https://auth.example.com', {
  method: 'popup',
  onComplete: (token) => {
    console.log('Authentication completed:', token);
  }
});
```

### 3. Redirect
Redirects the user to the authentication page and returns to the application afterward.

```typescript
const { authenticate } = useAuth('https://auth.example.com', {
  method: 'redirect',
  redirectUri: 'https://your-app.com/callback',
  onComplete: (token) => {
    console.log('Authentication completed:', token);
  }
});
```

## Framework Integrations

### Vue 3

```typescript
import { useClient } from 'glide-web-client-sdk/vue';

// In your setup function
const { useAuth } = useClient();

const { token, loading, error, authenticate } = useAuth('https://auth.example.com', {
  method: 'popup', // or 'iframe' or 'redirect'
  onTokenReceived: (token) => {
    console.log('Token received:', token);
  }
});

// Example template usage
<template>
  <button @click="authenticate" :disabled="authLoading">
    {{ authLoading ? 'Authenticating...' : 'Login' }}
  </button>

  <div v-if="token">
    Authenticated with token: {{ token }}
  </div>

  <div v-if="authError">
    {{ authError.message }}
  </div>
</template>
```

### React

```typescript
import { useClient } from 'glide-web-client-sdk/react';

function MyComponent() {
  const { useAuth } = useClient();

  const { 
    token,
    loading,
    error,
    authenticate
  } = useAuth({
    authUrl: 'https://auth.example.com',
    method: 'popup' // or 'iframe' or 'redirect'
  });

  const handleLogin = async () => {
    try {
      await authenticate('https://auth.example.com', {
        method: 'popup', // or 'iframe' or 'redirect'
        onTokenReceived: (token) => {
          // Handle intermediate token updates
        },
        onComplete: (token) => {
          // Handle authentication completion
        }
      });
    } catch (err) {
      // Handle authentication error
    }
  };

  // Making API calls
  const { data, loading: queryLoading, error: queryError, refetch } = useQuery('/data');
}
```

### Angular

```typescript
import { ClientService } from 'glide-web-client-sdk/angular';

@Component({
  // ...
})
export class MyComponent {
  constructor(private clientService: ClientService) {
    this.clientService.authenticate({
      authUrl: 'https://auth.example.com',
      method: 'popup'
    });
  }
}
```

## Configuration

### ClientConfig Options

```typescript
interface ClientConfig {
  baseURL?: string;        // Optional - only needed for custom API calls
  apiKey?: string;         // Optional - API key (for future use)
  timeout?: number;        // Request timeout in milliseconds (default: 10000)
  phoneAuthEndpoints?: {   // Phone auth endpoints (with defaults)
    prepareRequest: string;
    processResponse: string;
  };
  debug?: boolean;         // Enable debug logging (default: false)
}
```

**Note:** `baseURL` is only required if you plan to use:
- `useQuery()` hook for custom API calls
- Direct `client.get()` methods
- It's NOT required for phone authentication

### Backend Setup Required

For phone authentication to work, you need to set up backend endpoints using the Glide Node SDK:

```javascript
// Example Express.js backend
app.post('/api/phone-auth/prepare', async (req, res) => {
  const response = await glide.magicAuth.prepare({
    use_case: req.body.useCase,
    phone_number: req.body.phoneNumber,
    plmn: req.body.plmn
  });
  
  // Returns either:
  // { eligible: false, carrier_name, reason } - when carrier not supported
  // { protocol, data, session } - when carrier is eligible
  res.json(response);
});

app.post('/api/phone-auth/process', async (req, res) => {
  const result = await glide.magicAuth.processCredential(
    req.body.response,
    req.body.session,
    req.body.phoneNumber
  );
  
  // Returns: { success: true/false, phone_number, verified, error? }
  res.json(result);
});
```

Configure the SDK with authentication-specific options:

```typescript
interface AuthConfig {
  method: 'iframe' | 'popup' | 'redirect';
  redirectUri?: string;
  popupOptions?: {
    width: number;
    height: number;
  };
  timeout?: number;
}
```

## License

MIT

## Contributing

Contributions are welcome! Please read our contributing guidelines for details.

## Basic Usage

```typescript
import { SDKClient } from 'glide-web-client-sdk';
```