npm package: @phila/sso-react
Description: React adapter for @phila/sso-core
Author: City of Philadelphia
Latest version: 0.0.9

# @phila/sso-react

React adapter for `@phila/sso-core`. Provides context providers and hooks for Azure AD B2C authentication.

## Installation

```bash
pnpm add @phila/sso-react @phila/sso-core @azure/msal-browser
```

## Quick Start (Vite + B2C)

The `B2CSSOProvider` reads `VITE_SSO_*` environment variables automatically:

```env
VITE_SSO_CLIENT_ID=your-client-id
VITE_SSO_TENANT=YourTenant
VITE_SSO_AUTHORITY_DOMAIN=YourTenant.b2clogin.com
VITE_SSO_REDIRECT_URI=http://localhost:3000
```

```tsx
// App.tsx
import { B2CSSOProvider, useAuth } from "@phila/sso-react";

function AuthContent() {
  const { isAuthenticated, userName, authReady, signIn, signOut } = useAuth();

  if (!authReady) return <div>Loading...</div>;

  if (isAuthenticated) {
    return (
      <div>
        <p>Welcome, {userName}</p>
        <button onClick={() => signOut()}>Sign out</button>
      </div>
    );
  }

  return <button onClick={() => signIn()}>Sign in</button>;
}

export default function App() {
  return (
    <B2CSSOProvider>
      <AuthContent />
    </B2CSSOProvider>
  );
}
```

## Advanced Setup

For full control over the provider configuration:

```tsx
import { SSOProvider } from "@phila/sso-react";
import { B2CProvider } from "@phila/sso-core";

function App() {
  return (
    <SSOProvider
      config={{
        provider: new B2CProvider({
          clientId: "your-client-id",
          b2cEnvironment: "YourTenant",
          authorityDomain: "YourTenant.b2clogin.com",
          redirectUri: "http://localhost:3000",
          apiScopes: ["https://YourTenant.onmicrosoft.com/api/read"],
          policies: {
            signUpSignIn: "B2C_1A_SIGNUP_SIGNIN",
            signInOnly: "B2C_1A_AD_SIGNIN_ONLY",
            resetPassword: "B2C_1A_PASSWORDRESET",
          },
        }),
        debug: true,
      }}
    >
      <AuthContent />
    </SSOProvider>
  );
}
```

### `SSOProvider` Props

```ts
interface SSOProviderProps {
  config: SSOClientConfig;
  children: ReactNode;
}
```

### `B2CSSOProvider` Props

```ts
interface B2CSSOProviderProps {
  children: ReactNode;
  signInPolicy?: string; // default: "B2C_1A_AD_SIGNIN_ONLY"
  resetPasswordPolicy?: string; // default: "B2C_1A_PASSWORDRESET"
  debug?: boolean; // default: import.meta.env.DEV
}
```

## Hooks

### `useAuth()`

Primary hook for authentication. Must be called within an `SSOProvider` or `B2CSSOProvider`.

**State:**

| Property          | Type                  | Description                    |
| ----------------- | --------------------- | ------------------------------ |
| `isAuthenticated` | `boolean`             | User is signed in              |
| `isLoading`       | `boolean`             | Auth operation in progress     |
| `user`            | `AccountInfo \| null` | MSAL account info              |
| `token`           | `string \| null`      | Current access token           |
| `error`           | `Error \| null`       | Last auth error                |
| `activePolicy`    | `string \| null`      | Active B2C policy              |
| `authReady`       | `boolean`             | Initialization complete        |
| `userName`        | `string \| null`      | Display name from token claims |

**Actions:**

| Method                         | Returns                   | Description                      |
| ------------------------------ | ------------------------- | -------------------------------- |
| `signIn(options?)`             | `Promise<void>`           | Start sign-in flow               |
| `signInCityEmployee(options?)` | `Promise<void>`           | Sign in with sign-in-only policy |
| `signOut(options?)`            | `Promise<void>`           | Sign out                         |
| `forgotPassword()`             | `Promise<void>`           | Start password reset             |
| `acquireToken(options?)`       | `Promise<string \| null>` | Get access token                 |

**Utilities:**

| Method          | Returns   | Description                                             |
| --------------- | --------- | ------------------------------------------------------- |
| `hasRole(role)` | `boolean` | Check user role from `roles` or `extension_Roles` claim |

### `useSSOClient()`

Returns the raw `SSOClient` instance for advanced use cases.

```ts
const client = useSSOClient();
client.events.on("auth:tokenAcquired", token => {
  /* ... */
});
```

## License

MIT