npm package: @rgcodes/app-gateway-connector
Description: React authentication components for App Gateway sub-apps
Latest version: 0.1.1

# app-gateway-connector

React authentication components for App Gateway sub-apps.

## Overview

This package provides authentication components and hooks for building sub-apps that integrate with the App Gateway authentication system. It handles:

- Automatic authentication via one-time tokens
- Automatic session persistence via Supabase
- Redirect to gateway for unauthenticated users
- Pre-built header component with logout functionality

## Installation

### From NPM
```bash
npm install app-gateway-connector
```

### From Git Repository
```bash
npm install git+https://github.com/yourusername/app-gateway-connector.git
```

### Local Development (file: protocol)
```bash
# In your sub-app directory
npm install /path/to/app-gateway-connector

# Or with relative path
npm install ../../app-gateway-connector
```

This creates a symlink and automatically installs the connector's dependencies.

## Usage

### Basic Example

```tsx
import { AppGatewayAuthProvider, AppGatewayHeader } from 'app-gateway-connector';
import { YourApp } from './YourApp';

function App() {
  return (
    <AppGatewayAuthProvider
      appName="Todo App"
      gatewayUrl={import.meta.env.VITE_GATEWAY_URL}
      supabaseUrl={import.meta.env.VITE_SUPABASE_URL}
      supabaseAnonKey={import.meta.env.VITE_SUPABASE_PUBLIC_API_KEY}
    >
      <AppGatewayHeader />
      <YourApp />
    </AppGatewayAuthProvider>
  );
}

export default App;
```

### Environment Variables

Create a `.env` file in your sub-app:

```env
VITE_GATEWAY_URL=https://your-gateway.vercel.app
VITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_PUBLIC_API_KEY=your-public-anon-key
```

## Components

### `AppGatewayAuthProvider`

Wraps your entire app and handles authentication. Shows loading/error states and only renders children when authenticated.

**Props:**
- `appName` (string, required) - Display name of your app
- `gatewayUrl` (string, required) - URL of the gateway hub app
- `supabaseUrl` (string, required) - Your Supabase project URL
- `supabaseAnonKey` (string, required) - Your Supabase public/anon key
- `enableLogging` (boolean, optional) - Enable console logging for debugging (default: false)
- `children` (ReactNode, required) - Your app components

**States:**
- Loading: Shows "Loading..." message
- Error: Shows error message in red
- Unauthenticated: Shows "Redirecting to login..." and redirects to gateway
- Authenticated: Renders children

### `AppGatewayHeader`

Pre-built header component with app branding, navigation, and logout.

**Props:**
- `showBackToHub` (boolean, optional) - Show "← Back to Hub" link (default: true)

**Features:**
- Displays "App Gateway / {appName}"
- Back to hub link
- Current user email
- Logout button

## Hooks

### `useAuthContext`

Access authentication state and methods from child components.

```tsx
import { useAuthContext } from 'app-gateway-connector';

function MyComponent() {
  const { user, logout, appName, gatewayUrl } = useAuthContext();

  return (
    <div>
      <p>Welcome, {user.email}!</p>
      <button onClick={logout}>Log Out</button>
    </div>
  );
}
```

**Returns:**
- `user` (User | null) - Current authenticated user
- `loading` (boolean) - Loading state
- `error` (string | null) - Error message if auth failed
- `logout` (function) - Logout and redirect to gateway
- `appName` (string) - App name from provider
- `gatewayUrl` (string) - Gateway URL from provider

### `useAuth` (Advanced)

Low-level authentication hook for custom implementations.

```tsx
import { useAuth } from 'app-gateway-connector';

const { user, loading, error, logout } = useAuth({
  gatewayUrl: 'https://gateway.vercel.app',
  supabaseUrl: 'https://project.supabase.co',
  supabaseAnonKey: 'your-public-anon-key',
  enableLogging: true,
});
```

## Utilities

### `getSupabase()`

Get the configured Supabase client instance for direct database access.

```tsx
import { getSupabase } from 'app-gateway-connector';

const supabase = getSupabase();
const { data } = await supabase.from('todos').select('*');
```

**Note:** Session management is handled automatically by Supabase. You don't need to manually manage localStorage.

## Authentication Flow

1. User accesses sub-app
2. `AppGatewayAuthProvider` checks for:
   - Existing session (Supabase checks localStorage automatically) → Use it
   - Token in URL (`?token=xyz`) → Exchange for session
   - No auth → Redirect to gateway
3. If redirected to gateway:
   - User logs in
   - Gateway generates one-time token
   - Gateway redirects back: `subapp.com?token=xyz`
4. Sub-app exchanges token for session via edge function
5. Supabase automatically persists session
6. App renders with authenticated user

## TypeScript

Full TypeScript support included. All types are exported:

```tsx
import type {
  AppGatewayConfig,
  AuthState,
  User,
  Session,
} from 'app-gateway-connector';
```

## Development

### Package Structure

This package exports raw TypeScript source files, so there's no build step required. Vite in your sub-app will compile everything together.

### Test Locally

```bash
# In your sub-app directory
npm install /path/to/app-gateway-connector

# Make changes to connector source
# Changes are reflected immediately (no rebuild needed)
```

### Enable Debug Logging

```tsx
<AppGatewayAuthProvider
  enableLogging={true}
  // ... other props
>
```

## Troubleshooting

**"Supabase not initialised" error:**
- Ensure `AppGatewayAuthProvider` wraps your entire app
- Check that all required props are provided

**Infinite redirect loop:**
- Clear localStorage in your browser
- Verify `VITE_GATEWAY_URL` is correct
- Check that gateway is accessible

**Token exchange fails:**
- Verify `VITE_SUPABASE_URL` matches your project
- Ensure Supabase edge function is deployed
- Check browser console for error details

## License

MIT