open-index/open-npm huggingface dataset:
npm package: @q3assets/auth
Description: Shared authentication package for SHIRE project dashboards. Published to npm as `@q3assets/auth`.
Latest version: 0.2.5

# @q3assets/auth

Shared authentication package for SHIRE project dashboards. Published to npm as `@q3assets/auth`.

## What's included

| Export | Type | Description |
|--------|------|-------------|
| `Login` | Component | OTP email login form |
| `AuthConfirm` | Component | M365-safe confirmation page (user must click to proceed) |
| `AuthCallback` | Component | Exchanges auth code for session |
| `createBrowserClient` | Function | PKCE-enabled Supabase client for browser |
| `createServiceClient` | Function | Service-role client for admin API routes |
| `createAuthMiddleware` | Function | Next.js middleware factory for route protection |
| `requireAdmin` | Function | Validates bearer token + admin check |
| `inviteUser` | Function | Sends invite emails routed through /auth/confirm |

## Consuming from a project dashboard

**1. Install:**

```bash
npm install @q3assets/auth
```

**2. Add `transpilePackages` to `next.config.ts`:**

```typescript
const nextConfig = {
  transpilePackages: ["@q3assets/auth"],
}
```

This is required because the package ships TypeScript source. One line, standard Next.js pattern.

**3. Import:**

```typescript
import { Login } from "@q3assets/auth/login"
import { AuthConfirm } from "@q3assets/auth/confirm"
import { AuthCallback } from "@q3assets/auth/callback"
import { createAuthMiddleware } from "@q3assets/auth/middleware"
import { createBrowserClient } from "@q3assets/auth/clients"
```

### Pages and middleware

Create three pages and a middleware. Reference implementation: `SHIRE/projects/Q3/dashboard/src/`

```
app/login/page.tsx          → Login component
app/auth/confirm/page.tsx   → AuthConfirm component
app/auth/callback/page.tsx  → AuthCallback component
middleware.ts               → createAuthMiddleware
```

### Environment variables (`.env.local`)

```
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
```

## Why the confirm page exists

Microsoft 365 email security pre-clicks links in emails to scan for threats. This kills magic link tokens before the user sees them. The `/auth/confirm` page is a landing page that requires a human click — M365 hits the page but won't click the button, so the token survives for the real user.

## Auth flow

```
User enters email on /login
  → Supabase sends magic link pointing to /auth/confirm
  → M365 scanner hits /auth/confirm, sees a button, leaves
  → User clicks "Continue to dashboard"
  → Redirects to /auth/callback with token
  → AuthCallback exchanges code for session
  → Redirects to /
```