@githat/nextjs 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/provider.tsx","../src/config.ts","../src/client.ts","../src/hooks.ts","../src/data.ts","../src/components/SignInForm.tsx","../src/components/SignUpForm.tsx","../src/components/SignInButton.tsx","../src/components/SignUpButton.tsx","../src/components/UserButton.tsx","../src/components/OrgSwitcher.tsx","../src/components/VerifiedBadge.tsx","../src/components/ProtectedRoute.tsx"],"sourcesContent":["'use client';\n\nimport React, { createContext, useState, useEffect, useCallback, useMemo, useRef } from 'react';\nimport type { GitHatConfig, GitHatContextValue, GitHatUser, GitHatOrg, SignUpData, SignUpResult } from './types';\nimport { TOKEN_KEYS, resolveConfig } from './config';\nimport { createClient } from './client';\n\nexport const GitHatContext = createContext<GitHatContextValue | null>(null);\n\ninterface GitHatProviderProps {\n config: GitHatConfig;\n children: React.ReactNode;\n}\n\nexport function GitHatProvider({ config: rawConfig, children }: GitHatProviderProps) {\n const config = useMemo(() => resolveConfig(rawConfig), [rawConfig]);\n const clientRef = useRef(createClient(config.apiUrl, config.publishableKey));\n\n const [user, setUser] = useState<GitHatUser | null>(null);\n const [org, setOrg] = useState<GitHatOrg | null>(null);\n const [isSignedIn, setIsSignedIn] = useState(false);\n const [isLoading, setIsLoading] = useState(true);\n const [authError, setAuthError] = useState<string | null>(null);\n\n // Validate stored token on mount\n useEffect(() => {\n const token = localStorage.getItem(TOKEN_KEYS.accessToken);\n const storedUser = localStorage.getItem(TOKEN_KEYS.user);\n\n if (token && storedUser) {\n clientRef.current.fetchApi<{ user: GitHatUser; currentOrg: GitHatOrg }>('/auth/me')\n .then((data) => {\n const u = data.user || JSON.parse(storedUser);\n setUser(u);\n const storedOrg = localStorage.getItem(TOKEN_KEYS.org);\n setOrg(data.currentOrg || (storedOrg ? JSON.parse(storedOrg) : null));\n setIsSignedIn(true);\n setAuthError(null);\n })\n .catch((err) => {\n if (err.message === 'Session expired') {\n clientRef.current.clearAuth();\n } else {\n // Network error — keep stored auth, surface error\n try { setUser(JSON.parse(storedUser)); } catch {}\n setAuthError(err.message || 'Failed to verify session');\n }\n })\n .finally(() => setIsLoading(false));\n } else {\n setIsLoading(false);\n }\n }, []);\n\n // Listen for auth-changed events\n useEffect(() => {\n const handleAuthChanged = (e: Event) => {\n const detail = (e as CustomEvent).detail;\n if (detail?.signedIn === false) {\n setIsSignedIn(false);\n setUser(null);\n setOrg(null);\n } else if (detail?.signedIn === true && detail?.user) {\n setUser(detail.user);\n setIsSignedIn(true);\n if (detail.org) setOrg(detail.org);\n }\n };\n window.addEventListener('githat:auth-changed', handleAuthChanged);\n return () => window.removeEventListener('githat:auth-changed', handleAuthChanged);\n }, []);\n\n const signIn = useCallback(async (email: string, password: string) => {\n const data = await clientRef.current.fetchApi<{\n accessToken: string;\n refreshToken: string;\n user: GitHatUser;\n org: GitHatOrg;\n }>('/auth/login', {\n method: 'POST',\n body: JSON.stringify({ email, password }),\n });\n\n localStorage.setItem(TOKEN_KEYS.accessToken, data.accessToken);\n localStorage.setItem(TOKEN_KEYS.refreshToken, data.refreshToken);\n localStorage.setItem(TOKEN_KEYS.user, JSON.stringify(data.user));\n if (data.org) localStorage.setItem(TOKEN_KEYS.org, JSON.stringify(data.org));\n\n setUser(data.user);\n setOrg(data.org || null);\n setIsSignedIn(true);\n\n window.dispatchEvent(new CustomEvent('githat:auth-changed', {\n detail: { user: data.user, org: data.org, signedIn: true },\n }));\n }, []);\n\n const signUp = useCallback(async (signUpData: SignUpData): Promise<SignUpResult> => {\n const data = await clientRef.current.fetchApi<{\n accessToken: string;\n refreshToken: string;\n user: GitHatUser;\n org: GitHatOrg;\n }>('/auth/register', {\n method: 'POST',\n body: JSON.stringify(signUpData),\n });\n\n localStorage.setItem(TOKEN_KEYS.accessToken, data.accessToken);\n localStorage.setItem(TOKEN_KEYS.refreshToken, data.refreshToken);\n localStorage.setItem(TOKEN_KEYS.user, JSON.stringify(data.user));\n if (data.org) localStorage.setItem(TOKEN_KEYS.org, JSON.stringify(data.org));\n\n setUser(data.user);\n setOrg(data.org || null);\n setIsSignedIn(true);\n\n window.dispatchEvent(new CustomEvent('githat:auth-changed', {\n detail: { user: data.user, org: data.org, signedIn: true },\n }));\n\n return { requiresVerification: !data.user.emailVerified, email: signUpData.email };\n }, []);\n\n const signOut = useCallback(async () => {\n try {\n await clientRef.current.fetchApi('/auth/logout', { method: 'POST' });\n } catch {}\n clientRef.current.clearAuth();\n setIsSignedIn(false);\n setUser(null);\n setOrg(null);\n if (typeof window !== 'undefined' && config.afterSignOutUrl) {\n window.location.href = config.afterSignOutUrl;\n }\n }, [config.afterSignOutUrl]);\n\n const switchOrg = useCallback(async (orgId: string) => {\n try {\n const data = await clientRef.current.fetchApi<{\n accessToken: string;\n refreshToken: string;\n org: GitHatOrg;\n }>(`/user/orgs/${orgId}/switch`, { method: 'POST' });\n\n if (data.accessToken) localStorage.setItem(TOKEN_KEYS.accessToken, data.accessToken);\n if (data.refreshToken) localStorage.setItem(TOKEN_KEYS.refreshToken, data.refreshToken);\n const orgData = data.org;\n localStorage.setItem(TOKEN_KEYS.org, JSON.stringify(orgData));\n setOrg(orgData);\n\n window.dispatchEvent(new CustomEvent('githat:auth-changed', {\n detail: { user, org: orgData, signedIn: true },\n }));\n } catch (e) {\n console.error('Org switch failed:', e);\n }\n }, [user]);\n\n const value = useMemo<GitHatContextValue>(() => ({\n user, org, isSignedIn, isLoading, authError, config,\n signIn, signUp, signOut, switchOrg,\n }), [user, org, isSignedIn, isLoading, authError, config, signIn, signUp, signOut, switchOrg]);\n\n return (\n <GitHatContext.Provider value={value}>\n {children}\n </GitHatContext.Provider>\n );\n}\n","import type { GitHatConfig } from './types';\n\nexport const DEFAULT_API_URL = 'https://api.githat.io';\n\nexport const TOKEN_KEYS = {\n accessToken: 'githat_access_token',\n refreshToken: 'githat_refresh_token',\n user: 'githat_user',\n org: 'githat_org',\n} as const;\n\nexport function resolveConfig(config: GitHatConfig): Required<GitHatConfig> {\n return {\n publishableKey: config.publishableKey,\n apiUrl: config.apiUrl || DEFAULT_API_URL,\n signInUrl: config.signInUrl || '/sign-in',\n signUpUrl: config.signUpUrl || '/sign-up',\n afterSignInUrl: config.afterSignInUrl || '/dashboard',\n afterSignOutUrl: config.afterSignOutUrl || '/',\n };\n}\n","import { TOKEN_KEYS } from './config';\n\nlet _refreshPromise: Promise<boolean> | null = null;\n\nasync function refreshTokens(apiUrl: string, appKey: string): Promise<boolean> {\n const refreshToken = typeof window !== 'undefined' ? localStorage.getItem(TOKEN_KEYS.refreshToken) : null;\n if (!refreshToken) return false;\n\n let orgId: string | null = null;\n try {\n const orgStr = localStorage.getItem(TOKEN_KEYS.org);\n if (orgStr) orgId = JSON.parse(orgStr).id;\n } catch {}\n\n try {\n const res = await fetch(`${apiUrl}/auth/refresh`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-GitHat-App-Key': appKey,\n },\n body: JSON.stringify({ refreshToken, orgId }),\n });\n if (!res.ok) return false;\n\n const data = await res.json();\n if (data.accessToken) localStorage.setItem(TOKEN_KEYS.accessToken, data.accessToken);\n if (data.refreshToken) localStorage.setItem(TOKEN_KEYS.refreshToken, data.refreshToken);\n if (data.org) localStorage.setItem(TOKEN_KEYS.org, JSON.stringify(data.org));\n return true;\n } catch {\n return false;\n }\n}\n\nfunction clearAuth() {\n if (typeof window === 'undefined') return;\n Object.values(TOKEN_KEYS).forEach(key => localStorage.removeItem(key));\n window.dispatchEvent(new CustomEvent('githat:auth-changed', {\n detail: { user: null, org: null, signedIn: false },\n }));\n}\n\nexport function createClient(apiUrl: string, appKey: string) {\n async function fetchApi<T = any>(endpoint: string, options: RequestInit = {}): Promise<T> {\n const url = `${apiUrl}${endpoint}`;\n const token = typeof window !== 'undefined' ? localStorage.getItem(TOKEN_KEYS.accessToken) : null;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'X-GitHat-App-Key': appKey,\n ...(token && { Authorization: `Bearer ${token}` }),\n ...(options.headers as Record<string, string>),\n };\n\n let response: Response;\n try {\n response = await fetch(url, { ...options, headers });\n } catch (networkError: unknown) {\n // Network errors (CORS blocked, offline, DNS failure) throw TypeError\n if (networkError instanceof TypeError) {\n const isMissingKey = !appKey || !appKey.startsWith('pk_live_');\n const isLocalhost = typeof window !== 'undefined' &&\n (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1');\n\n if (isMissingKey && !isLocalhost) {\n throw new Error(\n 'Missing GitHat API key. Add NEXT_PUBLIC_GITHAT_PUBLISHABLE_KEY to .env.local'\n );\n }\n throw new Error(\n 'Unable to connect to GitHat API. Check your network connection.'\n );\n }\n throw networkError;\n }\n\n if (response.status === 401) {\n // Queue all 401 retries behind a single refresh promise\n if (!_refreshPromise) {\n _refreshPromise = refreshTokens(apiUrl, appKey).finally(() => {\n _refreshPromise = null;\n });\n }\n\n const refreshed = await _refreshPromise;\n\n if (refreshed) {\n const newToken = localStorage.getItem(TOKEN_KEYS.accessToken);\n const retryResponse = await fetch(url, {\n ...options,\n headers: {\n ...headers,\n ...(newToken && { Authorization: `Bearer ${newToken}` }),\n },\n });\n const retryData = await retryResponse.json();\n if (!retryResponse.ok) throw new Error(retryData.error || 'Request failed');\n return retryData as T;\n }\n\n clearAuth();\n throw new Error('Session expired');\n }\n\n const data = await response.json();\n if (!response.ok) throw new Error(data.error || 'Request failed');\n return data as T;\n }\n\n return { fetchApi, clearAuth };\n}\n","'use client';\n\nimport { useContext, useMemo } from 'react';\nimport { GitHatContext } from './provider';\nimport { createClient } from './client';\nimport type { GitHatContextValue, GitHatOrg } from './types';\n\nexport function useAuth(): GitHatContextValue {\n const ctx = useContext(GitHatContext);\n if (!ctx) throw new Error('useAuth must be used within a <GitHatProvider>');\n return ctx;\n}\n\nexport function useGitHat() {\n const ctx = useAuth();\n const client = useMemo(\n () => createClient(ctx.config.apiUrl!, ctx.config.publishableKey),\n [ctx.config.apiUrl, ctx.config.publishableKey]\n );\n\n return {\n fetch: client.fetchApi,\n getUserOrgs: () => client.fetchApi<{ orgs: GitHatOrg[] }>('/user/orgs'),\n verifyMCP: (domain: string) => client.fetchApi<{ verified: boolean }>(`/verify/mcp/${domain}`),\n verifyAgent: (wallet: string) => client.fetchApi<{ verified: boolean }>(`/verify/agent/${wallet}`),\n };\n}\n","'use client';\n\nimport { useMemo } from 'react';\nimport { useAuth } from './hooks';\nimport { createClient } from './client';\n\nexport interface DataItem {\n id: string;\n [key: string]: unknown;\n _createdAt?: string;\n _updatedAt?: string;\n}\n\nexport interface QueryOptions {\n limit?: number;\n cursor?: string;\n filter?: Record<string, unknown>;\n}\n\nexport interface QueryResult<T = DataItem> {\n items: T[];\n collection: string;\n nextCursor: string | null;\n count: number;\n}\n\nexport interface PutResult<T = DataItem> {\n item: T;\n collection: string;\n created: boolean;\n}\n\nexport interface DeleteResult {\n deleted: boolean;\n id: string;\n collection: string;\n}\n\nexport interface BatchOperation {\n type: 'put' | 'delete';\n id: string;\n data?: Record<string, unknown>;\n}\n\nexport interface BatchResult {\n processed: number;\n put: number;\n deleted: number;\n collection: string;\n}\n\n/**\n * Hook for interacting with GitHat's Customer Data API.\n * Provides CRUD operations for storing app data in GitHat's managed DynamoDB.\n *\n * @example\n * ```tsx\n * const { put, get, query, remove, batch } = useData();\n *\n * // Store data\n * await put('orders', { id: 'order_123', amount: 99.99, status: 'pending' });\n *\n * // Get single item\n * const order = await get('orders', 'order_123');\n *\n * // Query collection\n * const { items } = await query('orders', { filter: { status: 'pending' } });\n *\n * // Delete item\n * await remove('orders', 'order_123');\n * ```\n */\nexport function useData() {\n const ctx = useAuth();\n const client = useMemo(\n () => createClient(ctx.config.apiUrl!, ctx.config.publishableKey),\n [ctx.config.apiUrl, ctx.config.publishableKey]\n );\n\n return useMemo(() => ({\n /**\n * Store an item in a collection. If the item exists, it will be updated.\n * @param collection - Collection name (e.g., 'orders', 'users')\n * @param data - Data object with required `id` field\n */\n put: async <T extends DataItem>(collection: string, data: T): Promise<PutResult<T>> => {\n if (!data.id) {\n throw new Error('Data must include an \"id\" field');\n }\n return client.fetchApi<PutResult<T>>(`/data/${collection}/${data.id}`, {\n method: 'PUT',\n body: JSON.stringify(data),\n });\n },\n\n /**\n * Get a single item from a collection.\n * @param collection - Collection name\n * @param id - Item ID\n */\n get: async <T extends DataItem>(collection: string, id: string): Promise<T | null> => {\n try {\n const result = await client.fetchApi<{ item: T }>(`/data/${collection}/${id}`);\n return result.item;\n } catch (err: unknown) {\n if (err instanceof Error && err.message === 'Item not found') {\n return null;\n }\n throw err;\n }\n },\n\n /**\n * Query items from a collection with optional filters and pagination.\n * @param collection - Collection name\n * @param options - Query options (limit, cursor, filter)\n */\n query: async <T extends DataItem>(\n collection: string,\n options: QueryOptions = {}\n ): Promise<QueryResult<T>> => {\n const params = new URLSearchParams();\n if (options.limit) params.set('limit', options.limit.toString());\n if (options.cursor) params.set('cursor', options.cursor);\n if (options.filter) params.set('filter', JSON.stringify(options.filter));\n\n const queryString = params.toString();\n const url = `/data/${collection}${queryString ? `?${queryString}` : ''}`;\n\n return client.fetchApi<QueryResult<T>>(url);\n },\n\n /**\n * Delete an item from a collection.\n * @param collection - Collection name\n * @param id - Item ID\n */\n remove: async (collection: string, id: string): Promise<DeleteResult> => {\n return client.fetchApi<DeleteResult>(`/data/${collection}/${id}`, {\n method: 'DELETE',\n });\n },\n\n /**\n * Batch operations (put/delete) on a collection.\n * Maximum 100 operations per request.\n * @param collection - Collection name\n * @param operations - Array of operations\n */\n batch: async (collection: string, operations: BatchOperation[]): Promise<BatchResult> => {\n return client.fetchApi<BatchResult>(`/data/${collection}/batch`, {\n method: 'POST',\n body: JSON.stringify({ operations }),\n });\n },\n }), [client]);\n}\n","'use client';\n\nimport React, { useState, FormEvent } from 'react';\nimport { useAuth } from '../hooks';\n\ninterface SignInFormProps {\n onSuccess?: () => void;\n signUpUrl?: string;\n forgotPasswordUrl?: string;\n}\n\nexport function SignInForm({ onSuccess, signUpUrl, forgotPasswordUrl }: SignInFormProps) {\n const { signIn, config } = useAuth();\n const [email, setEmail] = useState('');\n const [password, setPassword] = useState('');\n const [error, setError] = useState('');\n const [loading, setLoading] = useState(false);\n\n const emailValid = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(email);\n\n const handleSubmit = async (e: FormEvent) => {\n e.preventDefault();\n if (!emailValid) {\n setError('Please enter a valid email address');\n return;\n }\n setError('');\n setLoading(true);\n try {\n await signIn(email, password);\n if (onSuccess) {\n onSuccess();\n } else if (typeof window !== 'undefined') {\n const params = new URLSearchParams(window.location.search);\n window.location.href = params.get('redirect_url') || config.afterSignInUrl!;\n }\n } catch (err: any) {\n setError(err.message || 'Sign in failed');\n } finally {\n setLoading(false);\n }\n };\n\n return (\n <div className=\"githat-form-container\">\n <div className=\"githat-form-header\">\n <h2 className=\"githat-form-title\">Sign in</h2>\n <p className=\"githat-form-subtitle\">Welcome back to GitHat</p>\n </div>\n {error && <div className=\"githat-alert githat-alert-error\" role=\"alert\" aria-live=\"polite\">{error}</div>}\n <form onSubmit={handleSubmit} className=\"githat-form\" aria-label=\"Sign in form\">\n <div className=\"githat-field\">\n <label className=\"githat-label\" htmlFor=\"githat-signin-email\">Email</label>\n <input\n id=\"githat-signin-email\"\n className=\"githat-input\"\n type=\"email\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n placeholder=\"you@example.com\"\n autoComplete=\"email\"\n required\n />\n </div>\n <div className=\"githat-field\">\n <label className=\"githat-label\" htmlFor=\"githat-signin-password\">Password</label>\n <input\n id=\"githat-signin-password\"\n className=\"githat-input\"\n type=\"password\"\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n placeholder=\"Enter your password\"\n autoComplete=\"current-password\"\n required\n />\n </div>\n {forgotPasswordUrl && (\n <a href={forgotPasswordUrl} className=\"githat-link githat-forgot-link\">Forgot password?</a>\n )}\n <button\n type=\"submit\"\n className=\"githat-button githat-button-primary\"\n disabled={loading || !email || !password || (email.length > 0 && !emailValid)}\n >\n {loading ? 'Signing in...' : 'Sign in'}\n </button>\n </form>\n {signUpUrl && (\n <p className=\"githat-form-footer\">\n Don't have an account? <a href={signUpUrl} className=\"githat-link\">Sign up</a>\n </p>\n )}\n <p className=\"githat-powered-by\">Secured by <strong>GitHat</strong></p>\n </div>\n );\n}\n","'use client';\n\nimport React, { useState, FormEvent } from 'react';\nimport { useAuth } from '../hooks';\n\ninterface SignUpFormProps {\n onSuccess?: (result: { requiresVerification: boolean; email: string }) => void;\n signInUrl?: string;\n}\n\nexport function SignUpForm({ onSuccess, signInUrl }: SignUpFormProps) {\n const { signUp, config } = useAuth();\n const [name, setName] = useState('');\n const [email, setEmail] = useState('');\n const [password, setPassword] = useState('');\n const [error, setError] = useState('');\n const [loading, setLoading] = useState(false);\n\n const emailValid = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(email);\n const passwordValid = password.length >= 8\n && /[A-Z]/.test(password)\n && /[a-z]/.test(password)\n && /\\d/.test(password);\n\n const handleSubmit = async (e: FormEvent) => {\n e.preventDefault();\n if (!emailValid) {\n setError('Please enter a valid email address');\n return;\n }\n if (!passwordValid) {\n setError('Password must be 8+ characters with uppercase, lowercase, number, and special character');\n return;\n }\n setError('');\n setLoading(true);\n try {\n const result = await signUp({ email, password, name });\n if (onSuccess) {\n onSuccess(result);\n } else if (typeof window !== 'undefined') {\n window.location.href = config.afterSignInUrl!;\n }\n } catch (err: any) {\n setError(err.message || 'Sign up failed');\n } finally {\n setLoading(false);\n }\n };\n\n return (\n <div className=\"githat-form-container\">\n <div className=\"githat-form-header\">\n <h2 className=\"githat-form-title\">Create an account</h2>\n <p className=\"githat-form-subtitle\">Get started with GitHat</p>\n </div>\n {error && <div className=\"githat-alert githat-alert-error\" role=\"alert\" aria-live=\"polite\">{error}</div>}\n <form onSubmit={handleSubmit} className=\"githat-form\" aria-label=\"Sign up form\">\n <div className=\"githat-field\">\n <label className=\"githat-label\" htmlFor=\"githat-signup-name\">Full name</label>\n <input\n id=\"githat-signup-name\"\n className=\"githat-input\"\n type=\"text\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder=\"Your name\"\n autoComplete=\"name\"\n required\n />\n </div>\n <div className=\"githat-field\">\n <label className=\"githat-label\" htmlFor=\"githat-signup-email\">Email</label>\n <input\n id=\"githat-signup-email\"\n className=\"githat-input\"\n type=\"email\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n placeholder=\"you@example.com\"\n autoComplete=\"email\"\n required\n />\n </div>\n <div className=\"githat-field\">\n <label className=\"githat-label\" htmlFor=\"githat-signup-password\">Password</label>\n <input\n id=\"githat-signup-password\"\n className=\"githat-input\"\n type=\"password\"\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n placeholder=\"8+ characters\"\n autoComplete=\"new-password\"\n required\n />\n {password && !passwordValid && (\n <p className=\"githat-field-error\">\n Must be 8+ characters with uppercase, lowercase, and number\n </p>\n )}\n </div>\n <button\n type=\"submit\"\n className=\"githat-button githat-button-primary\"\n disabled={loading || !email || !password || !name || !emailValid}\n >\n {loading ? 'Creating account...' : 'Sign up'}\n </button>\n </form>\n {signInUrl && (\n <p className=\"githat-form-footer\">\n Already have an account? <a href={signInUrl} className=\"githat-link\">Sign in</a>\n </p>\n )}\n <p className=\"githat-powered-by\">Secured by <strong>GitHat</strong></p>\n </div>\n );\n}\n","'use client';\n\nimport React, { useContext } from 'react';\nimport { GitHatContext } from '../provider';\n\ninterface SignInButtonProps {\n className?: string;\n children?: React.ReactNode;\n href?: string;\n}\n\nexport function SignInButton({ className, children, href }: SignInButtonProps) {\n const ctx = useContext(GitHatContext);\n const url = href || ctx?.config.signInUrl || '/sign-in';\n return (\n <a href={url} className={className || 'githat-button githat-button-primary'} aria-label=\"Sign in\">\n {children || 'Sign in'}\n </a>\n );\n}\n","'use client';\n\nimport React, { useContext } from 'react';\nimport { GitHatContext } from '../provider';\n\ninterface SignUpButtonProps {\n className?: string;\n children?: React.ReactNode;\n href?: string;\n}\n\nexport function SignUpButton({ className, children, href }: SignUpButtonProps) {\n const ctx = useContext(GitHatContext);\n const url = href || ctx?.config.signUpUrl || '/sign-up';\n return (\n <a href={url} className={className || 'githat-button githat-button-outline'} aria-label=\"Sign up\">\n {children || 'Sign up'}\n </a>\n );\n}\n","'use client';\n\nimport React, { useState, useRef, useEffect } from 'react';\nimport { useAuth } from '../hooks';\n\nexport function UserButton() {\n const { user, org, isSignedIn, signOut } = useAuth();\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const handleClickOutside = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false);\n };\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, []);\n\n if (!isSignedIn || !user) return null;\n\n const initials = user.name\n ? user.name.split(' ').map(n => n[0]).join('').toUpperCase().slice(0, 2)\n : user.email[0].toUpperCase();\n\n return (\n <div className=\"githat-user-button\" ref={ref}>\n <button className=\"githat-avatar-trigger\" onClick={() => setOpen(!open)} aria-label=\"User menu\" aria-expanded={open} aria-haspopup=\"true\">\n {user.avatarUrl ? (\n <img src={user.avatarUrl} alt={user.name || 'User avatar'} className=\"githat-avatar-img\" />\n ) : (\n <span className=\"githat-avatar-initials\">{initials}</span>\n )}\n </button>\n {open && (\n <div className=\"githat-dropdown\" role=\"menu\">\n <div className=\"githat-dropdown-header\">\n <p className=\"githat-dropdown-name\">{user.name}</p>\n <p className=\"githat-dropdown-email\">{user.email}</p>\n {org && <p className=\"githat-dropdown-org\">{org.name}</p>}\n </div>\n <div className=\"githat-dropdown-divider\" />\n <button className=\"githat-dropdown-item\" role=\"menuitem\" onClick={() => { signOut(); setOpen(false); }}>\n Sign out\n </button>\n </div>\n )}\n </div>\n );\n}\n","'use client';\n\nimport React, { useState, useEffect, useRef } from 'react';\nimport { useAuth, useGitHat } from '../hooks';\nimport type { GitHatOrg } from '../types';\n\nexport function OrgSwitcher() {\n const { org, isSignedIn, switchOrg } = useAuth();\n const githat = useGitHat();\n const [orgs, setOrgs] = useState<GitHatOrg[]>([]);\n const [orgsLoading, setOrgsLoading] = useState(false);\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (isSignedIn) {\n setOrgsLoading(true);\n githat.getUserOrgs()\n .then(data => setOrgs(data.orgs || []))\n .catch(() => {})\n .finally(() => setOrgsLoading(false));\n }\n }, [isSignedIn]);\n\n useEffect(() => {\n const handleClickOutside = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false);\n };\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, []);\n\n if (!isSignedIn || !org || (orgs.length < 2 && !orgsLoading)) return null;\n\n return (\n <div className=\"githat-org-switcher\" ref={ref}>\n <button className=\"githat-org-trigger\" onClick={() => setOpen(!open)} aria-label=\"Switch organization\" aria-expanded={open} aria-haspopup=\"true\">\n <span className=\"githat-org-name\">{org.name}</span>\n <span className=\"githat-chevron\">{open ? '\\u25B2' : '\\u25BC'}</span>\n </button>\n {open && (\n <div className=\"githat-dropdown\" role=\"menu\">\n {orgsLoading ? (\n <div className=\"githat-dropdown-item\" aria-busy=\"true\">Loading...</div>\n ) : orgs.map(o => (\n <button\n key={o.id}\n className={`githat-dropdown-item ${o.id === org.id ? 'githat-dropdown-item-active' : ''}`}\n role=\"menuitem\"\n aria-current={o.id === org.id ? 'true' : undefined}\n onClick={() => { switchOrg(o.id); setOpen(false); }}\n >\n {o.name}\n {o.id === org.id && <span className=\"githat-check\">{'\\u2713'}</span>}\n </button>\n ))}\n </div>\n )}\n </div>\n );\n}\n","'use client';\n\nimport React, { useState, useEffect, useRef } from 'react';\nimport { useGitHat } from '../hooks';\n\ninterface VerifiedBadgeProps {\n type: 'mcp' | 'agent';\n identifier: string;\n label?: string;\n}\n\nconst CACHE_TTL = 5 * 60 * 1000; // 5 minutes\nconst cache = new Map<string, { verified: boolean; ts: number }>();\n\nexport function VerifiedBadge({ type, identifier, label }: VerifiedBadgeProps) {\n const githat = useGitHat();\n const [verified, setVerified] = useState<boolean | null>(null);\n const mounted = useRef(true);\n\n useEffect(() => {\n mounted.current = true;\n const key = `${type}:${identifier}`;\n const cached = cache.get(key);\n if (cached && Date.now() - cached.ts < CACHE_TTL) {\n setVerified(cached.verified);\n return;\n }\n\n const verify = type === 'mcp' ? githat.verifyMCP : githat.verifyAgent;\n verify(identifier)\n .then(data => {\n if (mounted.current) {\n setVerified(data.verified);\n cache.set(key, { verified: data.verified, ts: Date.now() });\n }\n })\n .catch(() => { if (mounted.current) setVerified(false); });\n\n return () => { mounted.current = false; };\n }, [type, identifier]);\n\n if (verified === null) return null;\n\n return (\n <span className={`githat-badge ${verified ? 'githat-badge-verified' : 'githat-badge-unverified'}`}>\n {verified ? '\\u2713' : '\\u2717'} {label || (verified ? 'Verified' : 'Unverified')}\n </span>\n );\n}\n","'use client';\n\nimport React from 'react';\nimport { useAuth } from '../hooks';\n\ninterface ProtectedRouteProps {\n children: React.ReactNode;\n fallback?: React.ReactNode;\n}\n\nexport function ProtectedRoute({ children, fallback }: ProtectedRouteProps) {\n const { isSignedIn, isLoading, config } = useAuth();\n\n if (isLoading) {\n return <>{fallback || <div className=\"githat-loading\">Loading...</div>}</>;\n }\n\n if (!isSignedIn) {\n if (typeof window !== 'undefined') {\n window.location.href = config.signInUrl!;\n }\n return null;\n }\n\n return <>{children}</>;\n}\n"],"mappings":"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","names":["useMemo","useMemo","useMemo","useMemo","useState","jsx","useState","useState","jsx","jsxs","useState","useContext","jsx","useContext","useContext","jsx","useContext","useState","useRef","useEffect","jsx","jsxs","useState","useRef","useEffect","useState","useEffect","useRef","jsx","jsxs","useState","useRef","useEffect","useState","useEffect","useRef","jsxs","useState","useRef","useEffect","jsx"]}
1
+ {"version":3,"sources":["../src/provider.tsx","../src/config.ts","../src/client.ts","../src/hooks.ts","../src/data.ts","../src/components/SignInForm.tsx","../src/components/SignUpForm.tsx","../src/components/SignInButton.tsx","../src/components/SignUpButton.tsx","../src/components/UserButton.tsx","../src/components/OrgSwitcher.tsx","../src/components/VerifiedBadge.tsx","../src/components/ProtectedRoute.tsx"],"sourcesContent":["'use client';\n\nimport React, { createContext, useState, useEffect, useCallback, useMemo, useRef } from 'react';\nimport type { GitHatConfig, GitHatContextValue, GitHatUser, GitHatOrg, SignUpData, SignUpResult } from './types';\nimport { TOKEN_KEYS, resolveConfig } from './config';\nimport { createClient } from './client';\n\nexport const GitHatContext = createContext<GitHatContextValue | null>(null);\n\ninterface GitHatProviderProps {\n config: GitHatConfig;\n children: React.ReactNode;\n}\n\nexport function GitHatProvider({ config: rawConfig, children }: GitHatProviderProps) {\n const config = useMemo(() => resolveConfig(rawConfig), [rawConfig]);\n const useCookies = config.tokenStorage === 'cookie';\n\n // Create client with cookie mode awareness\n const clientRef = useRef(createClient(config.apiUrl, config.publishableKey, { useCookies }));\n\n const [user, setUser] = useState<GitHatUser | null>(null);\n const [org, setOrg] = useState<GitHatOrg | null>(null);\n const [isSignedIn, setIsSignedIn] = useState(false);\n const [isLoading, setIsLoading] = useState(true);\n const [authError, setAuthError] = useState<string | null>(null);\n\n // Validate stored token/session on mount\n useEffect(() => {\n const validateSession = async () => {\n try {\n // In cookie mode, we always try to validate (cookies sent automatically)\n // In localStorage mode, only validate if we have a token\n if (!useCookies) {\n const token = localStorage.getItem(TOKEN_KEYS.accessToken);\n const storedUser = localStorage.getItem(TOKEN_KEYS.user);\n if (!token || !storedUser) {\n setIsLoading(false);\n return;\n }\n }\n\n const data = await clientRef.current.fetchApi<{ user: GitHatUser; currentOrg: GitHatOrg }>('/auth/me');\n\n if (data.user) {\n setUser(data.user);\n setOrg(data.currentOrg || null);\n setIsSignedIn(true);\n setAuthError(null);\n\n // Store user info in localStorage for client-side access (even in cookie mode)\n if (!useCookies) {\n localStorage.setItem(TOKEN_KEYS.user, JSON.stringify(data.user));\n if (data.currentOrg) {\n localStorage.setItem(TOKEN_KEYS.org, JSON.stringify(data.currentOrg));\n }\n }\n }\n } catch (err: unknown) {\n const error = err as Error;\n if (error.message === 'Session expired') {\n clientRef.current.clearAuth();\n } else if (!useCookies) {\n // Network error in localStorage mode — try to use stored user\n const storedUser = localStorage.getItem(TOKEN_KEYS.user);\n if (storedUser) {\n try {\n setUser(JSON.parse(storedUser));\n setIsSignedIn(true);\n } catch {}\n }\n setAuthError(error.message || 'Failed to verify session');\n }\n // In cookie mode with error, just stay logged out\n }\n setIsLoading(false);\n };\n\n validateSession();\n }, [useCookies]);\n\n // Listen for auth-changed events\n useEffect(() => {\n const handleAuthChanged = (e: Event) => {\n const detail = (e as CustomEvent).detail;\n if (detail?.signedIn === false) {\n setIsSignedIn(false);\n setUser(null);\n setOrg(null);\n } else if (detail?.signedIn === true && detail?.user) {\n setUser(detail.user);\n setIsSignedIn(true);\n if (detail.org) setOrg(detail.org);\n }\n };\n window.addEventListener('githat:auth-changed', handleAuthChanged);\n return () => window.removeEventListener('githat:auth-changed', handleAuthChanged);\n }, []);\n\n const signIn = useCallback(async (email: string, password: string) => {\n // Build login URL with setCookie param if in cookie mode\n const loginUrl = useCookies ? '/auth/login?setCookie=true' : '/auth/login';\n\n const data = await clientRef.current.fetchApi<{\n accessToken?: string;\n refreshToken?: string;\n user: GitHatUser;\n org: GitHatOrg;\n }>(loginUrl, {\n method: 'POST',\n body: JSON.stringify({ email, password }),\n });\n\n // In localStorage mode, store tokens\n if (!useCookies && data.accessToken && data.refreshToken) {\n localStorage.setItem(TOKEN_KEYS.accessToken, data.accessToken);\n localStorage.setItem(TOKEN_KEYS.refreshToken, data.refreshToken);\n localStorage.setItem(TOKEN_KEYS.user, JSON.stringify(data.user));\n if (data.org) localStorage.setItem(TOKEN_KEYS.org, JSON.stringify(data.org));\n }\n\n setUser(data.user);\n setOrg(data.org || null);\n setIsSignedIn(true);\n\n window.dispatchEvent(new CustomEvent('githat:auth-changed', {\n detail: { user: data.user, org: data.org, signedIn: true },\n }));\n }, [useCookies]);\n\n const signUp = useCallback(async (signUpData: SignUpData): Promise<SignUpResult> => {\n // Build register URL with setCookie param if in cookie mode\n const registerUrl = useCookies ? '/auth/register?setCookie=true' : '/auth/register';\n\n const data = await clientRef.current.fetchApi<{\n accessToken?: string;\n refreshToken?: string;\n user: GitHatUser;\n org: GitHatOrg;\n }>(registerUrl, {\n method: 'POST',\n body: JSON.stringify(signUpData),\n });\n\n // In localStorage mode, store tokens\n if (!useCookies && data.accessToken && data.refreshToken) {\n localStorage.setItem(TOKEN_KEYS.accessToken, data.accessToken);\n localStorage.setItem(TOKEN_KEYS.refreshToken, data.refreshToken);\n localStorage.setItem(TOKEN_KEYS.user, JSON.stringify(data.user));\n if (data.org) localStorage.setItem(TOKEN_KEYS.org, JSON.stringify(data.org));\n }\n\n setUser(data.user);\n setOrg(data.org || null);\n setIsSignedIn(true);\n\n window.dispatchEvent(new CustomEvent('githat:auth-changed', {\n detail: { user: data.user, org: data.org, signedIn: true },\n }));\n\n return { requiresVerification: !data.user.emailVerified, email: signUpData.email };\n }, [useCookies]);\n\n const signOut = useCallback(async () => {\n try {\n // In cookie mode, logout endpoint clears cookies\n const logoutUrl = useCookies ? '/auth/logout?setCookie=true' : '/auth/logout';\n await clientRef.current.fetchApi(logoutUrl, { method: 'POST' });\n } catch {}\n clientRef.current.clearAuth();\n setIsSignedIn(false);\n setUser(null);\n setOrg(null);\n if (typeof window !== 'undefined' && config.afterSignOutUrl) {\n window.location.href = config.afterSignOutUrl;\n }\n }, [config.afterSignOutUrl, useCookies]);\n\n const switchOrg = useCallback(async (orgId: string) => {\n try {\n const switchUrl = useCookies\n ? `/user/orgs/${orgId}/switch?setCookie=true`\n : `/user/orgs/${orgId}/switch`;\n\n const data = await clientRef.current.fetchApi<{\n accessToken?: string;\n refreshToken?: string;\n org: GitHatOrg;\n }>(switchUrl, { method: 'POST' });\n\n // In localStorage mode, store new tokens\n if (!useCookies) {\n if (data.accessToken) localStorage.setItem(TOKEN_KEYS.accessToken, data.accessToken);\n if (data.refreshToken) localStorage.setItem(TOKEN_KEYS.refreshToken, data.refreshToken);\n localStorage.setItem(TOKEN_KEYS.org, JSON.stringify(data.org));\n }\n\n setOrg(data.org);\n\n window.dispatchEvent(new CustomEvent('githat:auth-changed', {\n detail: { user, org: data.org, signedIn: true },\n }));\n } catch (e) {\n console.error('Org switch failed:', e);\n }\n }, [user, useCookies]);\n\n const value = useMemo<GitHatContextValue>(() => ({\n user, org, isSignedIn, isLoading, authError, config,\n signIn, signUp, signOut, switchOrg,\n }), [user, org, isSignedIn, isLoading, authError, config, signIn, signUp, signOut, switchOrg]);\n\n return (\n <GitHatContext.Provider value={value}>\n {children}\n </GitHatContext.Provider>\n );\n}\n","import type { GitHatConfig } from './types';\n\nexport const DEFAULT_API_URL = 'https://api.githat.io';\n\nexport const TOKEN_KEYS = {\n accessToken: 'githat_access_token',\n refreshToken: 'githat_refresh_token',\n user: 'githat_user',\n org: 'githat_org',\n} as const;\n\nexport const COOKIE_NAMES = {\n accessToken: 'githat_access',\n refreshToken: 'githat_refresh',\n} as const;\n\nexport function resolveConfig(config: GitHatConfig): Required<GitHatConfig> {\n return {\n publishableKey: config.publishableKey,\n apiUrl: config.apiUrl || DEFAULT_API_URL,\n signInUrl: config.signInUrl || '/sign-in',\n signUpUrl: config.signUpUrl || '/sign-up',\n afterSignInUrl: config.afterSignInUrl || '/dashboard',\n afterSignOutUrl: config.afterSignOutUrl || '/',\n tokenStorage: config.tokenStorage || 'localStorage',\n };\n}\n","import { TOKEN_KEYS } from './config';\n\ninterface ClientOptions {\n /**\n * When true, use credentials: 'include' for all requests\n * and don't send Authorization header (cookies handle auth)\n */\n useCookies?: boolean;\n}\n\nlet _refreshPromise: Promise<boolean> | null = null;\n\nasync function refreshTokens(\n apiUrl: string,\n appKey: string,\n useCookies: boolean\n): Promise<boolean> {\n // In cookie mode, refresh token comes from cookie\n // In localStorage mode, we need to send it in the body\n const refreshToken =\n typeof window !== 'undefined' && !useCookies\n ? localStorage.getItem(TOKEN_KEYS.refreshToken)\n : null;\n\n // In localStorage mode, we need a refresh token\n if (!useCookies && !refreshToken) return false;\n\n let orgId: string | null = null;\n try {\n const orgStr = localStorage.getItem(TOKEN_KEYS.org);\n if (orgStr) orgId = JSON.parse(orgStr).id;\n } catch {}\n\n try {\n const refreshUrl = useCookies\n ? `${apiUrl}/auth/refresh?setCookie=true`\n : `${apiUrl}/auth/refresh`;\n\n const res = await fetch(refreshUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-GitHat-App-Key': appKey,\n },\n credentials: useCookies ? 'include' : 'same-origin',\n body: JSON.stringify(useCookies ? { orgId } : { refreshToken, orgId }),\n });\n\n if (!res.ok) return false;\n\n const data = await res.json();\n\n // In localStorage mode, store the new tokens\n if (!useCookies) {\n if (data.accessToken) localStorage.setItem(TOKEN_KEYS.accessToken, data.accessToken);\n if (data.refreshToken) localStorage.setItem(TOKEN_KEYS.refreshToken, data.refreshToken);\n }\n\n if (data.org) localStorage.setItem(TOKEN_KEYS.org, JSON.stringify(data.org));\n return true;\n } catch {\n return false;\n }\n}\n\nfunction clearAuth() {\n if (typeof window === 'undefined') return;\n Object.values(TOKEN_KEYS).forEach((key) => localStorage.removeItem(key));\n window.dispatchEvent(\n new CustomEvent('githat:auth-changed', {\n detail: { user: null, org: null, signedIn: false },\n })\n );\n}\n\nexport function createClient(\n apiUrl: string,\n appKey: string,\n options: ClientOptions = {}\n) {\n const { useCookies = false } = options;\n\n async function fetchApi<T = unknown>(\n endpoint: string,\n fetchOptions: RequestInit = {}\n ): Promise<T> {\n const url = `${apiUrl}${endpoint}`;\n\n // In localStorage mode, get token from storage\n // In cookie mode, cookies are sent automatically with credentials: 'include'\n const token =\n typeof window !== 'undefined' && !useCookies\n ? localStorage.getItem(TOKEN_KEYS.accessToken)\n : null;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'X-GitHat-App-Key': appKey,\n ...(token && { Authorization: `Bearer ${token}` }),\n ...(fetchOptions.headers as Record<string, string>),\n };\n\n let response: Response;\n try {\n response = await fetch(url, {\n ...fetchOptions,\n headers,\n credentials: useCookies ? 'include' : 'same-origin',\n });\n } catch (networkError: unknown) {\n // Network errors (CORS blocked, offline, DNS failure) throw TypeError\n if (networkError instanceof TypeError) {\n const isMissingKey = !appKey || !appKey.startsWith('pk_live_');\n const isLocalhost =\n typeof window !== 'undefined' &&\n (window.location.hostname === 'localhost' ||\n window.location.hostname === '127.0.0.1');\n\n if (isMissingKey && !isLocalhost) {\n throw new Error(\n 'Missing GitHat API key. Add NEXT_PUBLIC_GITHAT_PUBLISHABLE_KEY to .env.local'\n );\n }\n throw new Error('Unable to connect to GitHat API. Check your network connection.');\n }\n throw networkError;\n }\n\n if (response.status === 401) {\n // Queue all 401 retries behind a single refresh promise\n if (!_refreshPromise) {\n _refreshPromise = refreshTokens(apiUrl, appKey, useCookies).finally(() => {\n _refreshPromise = null;\n });\n }\n\n const refreshed = await _refreshPromise;\n\n if (refreshed) {\n // Get the new token (only needed in localStorage mode)\n const newToken =\n !useCookies && typeof window !== 'undefined'\n ? localStorage.getItem(TOKEN_KEYS.accessToken)\n : null;\n\n const retryResponse = await fetch(url, {\n ...fetchOptions,\n headers: {\n ...headers,\n ...(newToken && { Authorization: `Bearer ${newToken}` }),\n },\n credentials: useCookies ? 'include' : 'same-origin',\n });\n\n const retryData = await retryResponse.json();\n if (!retryResponse.ok) throw new Error(retryData.error || 'Request failed');\n return retryData as T;\n }\n\n clearAuth();\n throw new Error('Session expired');\n }\n\n const data = await response.json();\n if (!response.ok) throw new Error(data.error || 'Request failed');\n return data as T;\n }\n\n return { fetchApi, clearAuth };\n}\n","'use client';\n\nimport { useContext, useMemo, useCallback } from 'react';\nimport { GitHatContext } from './provider';\nimport { createClient } from './client';\nimport type { GitHatContextValue, GitHatOrg } from './types';\n\nexport interface OrgMetadata {\n [key: string]: unknown;\n}\n\nexport function useAuth(): GitHatContextValue {\n const ctx = useContext(GitHatContext);\n if (!ctx) throw new Error('useAuth must be used within a <GitHatProvider>');\n return ctx;\n}\n\nexport function useGitHat() {\n const ctx = useAuth();\n const client = useMemo(\n () => createClient(ctx.config.apiUrl!, ctx.config.publishableKey),\n [ctx.config.apiUrl, ctx.config.publishableKey]\n );\n\n /**\n * Get the current organization's metadata.\n * Requires the user to be signed in with an active organization.\n *\n * @example\n * ```tsx\n * const { getOrgMetadata } = useGitHat();\n * const meta = await getOrgMetadata();\n * console.log(meta.stripeAccountId);\n * ```\n */\n const getOrgMetadata = useCallback(async (): Promise<OrgMetadata> => {\n if (!ctx.org?.id) {\n throw new Error('No active organization');\n }\n const response = await client.fetchApi<{ metadata: OrgMetadata }>(\n `/orgs/${ctx.org.id}/metadata`\n );\n return response.metadata || {};\n }, [client, ctx.org?.id]);\n\n /**\n * Update the current organization's metadata.\n * Merges the provided object with existing metadata.\n * Set a key to null to delete it.\n * Requires admin or owner role.\n *\n * @example\n * ```tsx\n * const { updateOrgMetadata } = useGitHat();\n * // Set values\n * await updateOrgMetadata({ stripeAccountId: 'acct_xxx', features: ['pos'] });\n * // Delete a key\n * await updateOrgMetadata({ oldKey: null });\n * ```\n */\n const updateOrgMetadata = useCallback(\n async (updates: OrgMetadata): Promise<OrgMetadata> => {\n if (!ctx.org?.id) {\n throw new Error('No active organization');\n }\n const response = await client.fetchApi<{ metadata: OrgMetadata }>(\n `/orgs/${ctx.org.id}/metadata`,\n {\n method: 'PATCH',\n body: JSON.stringify(updates),\n }\n );\n return response.metadata || {};\n },\n [client, ctx.org?.id]\n );\n\n return {\n fetch: client.fetchApi,\n getUserOrgs: () => client.fetchApi<{ orgs: GitHatOrg[] }>('/user/orgs'),\n verifyMCP: (domain: string) => client.fetchApi<{ verified: boolean }>(`/verify/mcp/${domain}`),\n verifyAgent: (wallet: string) => client.fetchApi<{ verified: boolean }>(`/verify/agent/${wallet}`),\n getOrgMetadata,\n updateOrgMetadata,\n };\n}\n","'use client';\n\nimport { useMemo } from 'react';\nimport { useAuth } from './hooks';\nimport { createClient } from './client';\n\nexport interface DataItem {\n id: string;\n [key: string]: unknown;\n _createdAt?: string;\n _updatedAt?: string;\n}\n\nexport interface QueryOptions {\n limit?: number;\n cursor?: string;\n filter?: Record<string, unknown>;\n}\n\nexport interface QueryResult<T = DataItem> {\n items: T[];\n collection: string;\n nextCursor: string | null;\n count: number;\n}\n\nexport interface PutResult<T = DataItem> {\n item: T;\n collection: string;\n created: boolean;\n}\n\nexport interface DeleteResult {\n deleted: boolean;\n id: string;\n collection: string;\n}\n\nexport interface BatchOperation {\n type: 'put' | 'delete';\n id: string;\n data?: Record<string, unknown>;\n}\n\nexport interface BatchResult {\n processed: number;\n put: number;\n deleted: number;\n collection: string;\n}\n\n/**\n * Hook for interacting with GitHat's Customer Data API.\n * Provides CRUD operations for storing app data in GitHat's managed DynamoDB.\n *\n * @example\n * ```tsx\n * const { put, get, query, remove, batch } = useData();\n *\n * // Store data\n * await put('orders', { id: 'order_123', amount: 99.99, status: 'pending' });\n *\n * // Get single item\n * const order = await get('orders', 'order_123');\n *\n * // Query collection\n * const { items } = await query('orders', { filter: { status: 'pending' } });\n *\n * // Delete item\n * await remove('orders', 'order_123');\n * ```\n */\nexport function useData() {\n const ctx = useAuth();\n const client = useMemo(\n () => createClient(ctx.config.apiUrl!, ctx.config.publishableKey),\n [ctx.config.apiUrl, ctx.config.publishableKey]\n );\n\n return useMemo(() => ({\n /**\n * Store an item in a collection. If the item exists, it will be updated.\n * @param collection - Collection name (e.g., 'orders', 'users')\n * @param data - Data object with required `id` field\n */\n put: async <T extends DataItem>(collection: string, data: T): Promise<PutResult<T>> => {\n if (!data.id) {\n throw new Error('Data must include an \"id\" field');\n }\n return client.fetchApi<PutResult<T>>(`/data/${collection}/${data.id}`, {\n method: 'PUT',\n body: JSON.stringify(data),\n });\n },\n\n /**\n * Get a single item from a collection.\n * @param collection - Collection name\n * @param id - Item ID\n */\n get: async <T extends DataItem>(collection: string, id: string): Promise<T | null> => {\n try {\n const result = await client.fetchApi<{ item: T }>(`/data/${collection}/${id}`);\n return result.item;\n } catch (err: unknown) {\n if (err instanceof Error && err.message === 'Item not found') {\n return null;\n }\n throw err;\n }\n },\n\n /**\n * Query items from a collection with optional filters and pagination.\n * @param collection - Collection name\n * @param options - Query options (limit, cursor, filter)\n */\n query: async <T extends DataItem>(\n collection: string,\n options: QueryOptions = {}\n ): Promise<QueryResult<T>> => {\n const params = new URLSearchParams();\n if (options.limit) params.set('limit', options.limit.toString());\n if (options.cursor) params.set('cursor', options.cursor);\n if (options.filter) params.set('filter', JSON.stringify(options.filter));\n\n const queryString = params.toString();\n const url = `/data/${collection}${queryString ? `?${queryString}` : ''}`;\n\n return client.fetchApi<QueryResult<T>>(url);\n },\n\n /**\n * Delete an item from a collection.\n * @param collection - Collection name\n * @param id - Item ID\n */\n remove: async (collection: string, id: string): Promise<DeleteResult> => {\n return client.fetchApi<DeleteResult>(`/data/${collection}/${id}`, {\n method: 'DELETE',\n });\n },\n\n /**\n * Batch operations (put/delete) on a collection.\n * Maximum 100 operations per request.\n * @param collection - Collection name\n * @param operations - Array of operations\n */\n batch: async (collection: string, operations: BatchOperation[]): Promise<BatchResult> => {\n return client.fetchApi<BatchResult>(`/data/${collection}/batch`, {\n method: 'POST',\n body: JSON.stringify({ operations }),\n });\n },\n }), [client]);\n}\n","'use client';\n\nimport React, { useState, FormEvent } from 'react';\nimport { useAuth } from '../hooks';\n\ninterface SignInFormProps {\n onSuccess?: () => void;\n signUpUrl?: string;\n forgotPasswordUrl?: string;\n}\n\nexport function SignInForm({ onSuccess, signUpUrl, forgotPasswordUrl }: SignInFormProps) {\n const { signIn, config } = useAuth();\n const [email, setEmail] = useState('');\n const [password, setPassword] = useState('');\n const [error, setError] = useState('');\n const [loading, setLoading] = useState(false);\n\n const emailValid = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(email);\n\n const handleSubmit = async (e: FormEvent) => {\n e.preventDefault();\n if (!emailValid) {\n setError('Please enter a valid email address');\n return;\n }\n setError('');\n setLoading(true);\n try {\n await signIn(email, password);\n if (onSuccess) {\n onSuccess();\n } else if (typeof window !== 'undefined') {\n const params = new URLSearchParams(window.location.search);\n window.location.href = params.get('redirect_url') || config.afterSignInUrl!;\n }\n } catch (err: any) {\n setError(err.message || 'Sign in failed');\n } finally {\n setLoading(false);\n }\n };\n\n return (\n <div className=\"githat-form-container\">\n <div className=\"githat-form-header\">\n <h2 className=\"githat-form-title\">Sign in</h2>\n <p className=\"githat-form-subtitle\">Welcome back to GitHat</p>\n </div>\n {error && <div className=\"githat-alert githat-alert-error\" role=\"alert\" aria-live=\"polite\">{error}</div>}\n <form onSubmit={handleSubmit} className=\"githat-form\" aria-label=\"Sign in form\">\n <div className=\"githat-field\">\n <label className=\"githat-label\" htmlFor=\"githat-signin-email\">Email</label>\n <input\n id=\"githat-signin-email\"\n className=\"githat-input\"\n type=\"email\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n placeholder=\"you@example.com\"\n autoComplete=\"email\"\n required\n />\n </div>\n <div className=\"githat-field\">\n <label className=\"githat-label\" htmlFor=\"githat-signin-password\">Password</label>\n <input\n id=\"githat-signin-password\"\n className=\"githat-input\"\n type=\"password\"\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n placeholder=\"Enter your password\"\n autoComplete=\"current-password\"\n required\n />\n </div>\n {forgotPasswordUrl && (\n <a href={forgotPasswordUrl} className=\"githat-link githat-forgot-link\">Forgot password?</a>\n )}\n <button\n type=\"submit\"\n className=\"githat-button githat-button-primary\"\n disabled={loading || !email || !password || (email.length > 0 && !emailValid)}\n >\n {loading ? 'Signing in...' : 'Sign in'}\n </button>\n </form>\n {signUpUrl && (\n <p className=\"githat-form-footer\">\n Don't have an account? <a href={signUpUrl} className=\"githat-link\">Sign up</a>\n </p>\n )}\n <p className=\"githat-powered-by\">Secured by <strong>GitHat</strong></p>\n </div>\n );\n}\n","'use client';\n\nimport React, { useState, FormEvent } from 'react';\nimport { useAuth } from '../hooks';\n\ninterface SignUpFormProps {\n onSuccess?: (result: { requiresVerification: boolean; email: string }) => void;\n signInUrl?: string;\n}\n\nexport function SignUpForm({ onSuccess, signInUrl }: SignUpFormProps) {\n const { signUp, config } = useAuth();\n const [name, setName] = useState('');\n const [email, setEmail] = useState('');\n const [password, setPassword] = useState('');\n const [error, setError] = useState('');\n const [loading, setLoading] = useState(false);\n\n const emailValid = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(email);\n const passwordValid = password.length >= 8\n && /[A-Z]/.test(password)\n && /[a-z]/.test(password)\n && /\\d/.test(password);\n\n const handleSubmit = async (e: FormEvent) => {\n e.preventDefault();\n if (!emailValid) {\n setError('Please enter a valid email address');\n return;\n }\n if (!passwordValid) {\n setError('Password must be 8+ characters with uppercase, lowercase, number, and special character');\n return;\n }\n setError('');\n setLoading(true);\n try {\n const result = await signUp({ email, password, name });\n if (onSuccess) {\n onSuccess(result);\n } else if (typeof window !== 'undefined') {\n window.location.href = config.afterSignInUrl!;\n }\n } catch (err: any) {\n setError(err.message || 'Sign up failed');\n } finally {\n setLoading(false);\n }\n };\n\n return (\n <div className=\"githat-form-container\">\n <div className=\"githat-form-header\">\n <h2 className=\"githat-form-title\">Create an account</h2>\n <p className=\"githat-form-subtitle\">Get started with GitHat</p>\n </div>\n {error && <div className=\"githat-alert githat-alert-error\" role=\"alert\" aria-live=\"polite\">{error}</div>}\n <form onSubmit={handleSubmit} className=\"githat-form\" aria-label=\"Sign up form\">\n <div className=\"githat-field\">\n <label className=\"githat-label\" htmlFor=\"githat-signup-name\">Full name</label>\n <input\n id=\"githat-signup-name\"\n className=\"githat-input\"\n type=\"text\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder=\"Your name\"\n autoComplete=\"name\"\n required\n />\n </div>\n <div className=\"githat-field\">\n <label className=\"githat-label\" htmlFor=\"githat-signup-email\">Email</label>\n <input\n id=\"githat-signup-email\"\n className=\"githat-input\"\n type=\"email\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n placeholder=\"you@example.com\"\n autoComplete=\"email\"\n required\n />\n </div>\n <div className=\"githat-field\">\n <label className=\"githat-label\" htmlFor=\"githat-signup-password\">Password</label>\n <input\n id=\"githat-signup-password\"\n className=\"githat-input\"\n type=\"password\"\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n placeholder=\"8+ characters\"\n autoComplete=\"new-password\"\n required\n />\n {password && !passwordValid && (\n <p className=\"githat-field-error\">\n Must be 8+ characters with uppercase, lowercase, and number\n </p>\n )}\n </div>\n <button\n type=\"submit\"\n className=\"githat-button githat-button-primary\"\n disabled={loading || !email || !password || !name || !emailValid}\n >\n {loading ? 'Creating account...' : 'Sign up'}\n </button>\n </form>\n {signInUrl && (\n <p className=\"githat-form-footer\">\n Already have an account? <a href={signInUrl} className=\"githat-link\">Sign in</a>\n </p>\n )}\n <p className=\"githat-powered-by\">Secured by <strong>GitHat</strong></p>\n </div>\n );\n}\n","'use client';\n\nimport React, { useContext } from 'react';\nimport { GitHatContext } from '../provider';\n\ninterface SignInButtonProps {\n className?: string;\n children?: React.ReactNode;\n href?: string;\n}\n\nexport function SignInButton({ className, children, href }: SignInButtonProps) {\n const ctx = useContext(GitHatContext);\n const url = href || ctx?.config.signInUrl || '/sign-in';\n return (\n <a href={url} className={className || 'githat-button githat-button-primary'} aria-label=\"Sign in\">\n {children || 'Sign in'}\n </a>\n );\n}\n","'use client';\n\nimport React, { useContext } from 'react';\nimport { GitHatContext } from '../provider';\n\ninterface SignUpButtonProps {\n className?: string;\n children?: React.ReactNode;\n href?: string;\n}\n\nexport function SignUpButton({ className, children, href }: SignUpButtonProps) {\n const ctx = useContext(GitHatContext);\n const url = href || ctx?.config.signUpUrl || '/sign-up';\n return (\n <a href={url} className={className || 'githat-button githat-button-outline'} aria-label=\"Sign up\">\n {children || 'Sign up'}\n </a>\n );\n}\n","'use client';\n\nimport React, { useState, useRef, useEffect } from 'react';\nimport { useAuth } from '../hooks';\n\nexport function UserButton() {\n const { user, org, isSignedIn, signOut } = useAuth();\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const handleClickOutside = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false);\n };\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, []);\n\n if (!isSignedIn || !user) return null;\n\n const initials = user.name\n ? user.name.split(' ').map(n => n[0]).join('').toUpperCase().slice(0, 2)\n : user.email[0].toUpperCase();\n\n return (\n <div className=\"githat-user-button\" ref={ref}>\n <button className=\"githat-avatar-trigger\" onClick={() => setOpen(!open)} aria-label=\"User menu\" aria-expanded={open} aria-haspopup=\"true\">\n {user.avatarUrl ? (\n <img src={user.avatarUrl} alt={user.name || 'User avatar'} className=\"githat-avatar-img\" />\n ) : (\n <span className=\"githat-avatar-initials\">{initials}</span>\n )}\n </button>\n {open && (\n <div className=\"githat-dropdown\" role=\"menu\">\n <div className=\"githat-dropdown-header\">\n <p className=\"githat-dropdown-name\">{user.name}</p>\n <p className=\"githat-dropdown-email\">{user.email}</p>\n {org && <p className=\"githat-dropdown-org\">{org.name}</p>}\n </div>\n <div className=\"githat-dropdown-divider\" />\n <button className=\"githat-dropdown-item\" role=\"menuitem\" onClick={() => { signOut(); setOpen(false); }}>\n Sign out\n </button>\n </div>\n )}\n </div>\n );\n}\n","'use client';\n\nimport React, { useState, useEffect, useRef } from 'react';\nimport { useAuth, useGitHat } from '../hooks';\nimport type { GitHatOrg } from '../types';\n\nexport function OrgSwitcher() {\n const { org, isSignedIn, switchOrg } = useAuth();\n const githat = useGitHat();\n const [orgs, setOrgs] = useState<GitHatOrg[]>([]);\n const [orgsLoading, setOrgsLoading] = useState(false);\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (isSignedIn) {\n setOrgsLoading(true);\n githat.getUserOrgs()\n .then(data => setOrgs(data.orgs || []))\n .catch(() => {})\n .finally(() => setOrgsLoading(false));\n }\n }, [isSignedIn]);\n\n useEffect(() => {\n const handleClickOutside = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false);\n };\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, []);\n\n if (!isSignedIn || !org || (orgs.length < 2 && !orgsLoading)) return null;\n\n return (\n <div className=\"githat-org-switcher\" ref={ref}>\n <button className=\"githat-org-trigger\" onClick={() => setOpen(!open)} aria-label=\"Switch organization\" aria-expanded={open} aria-haspopup=\"true\">\n <span className=\"githat-org-name\">{org.name}</span>\n <span className=\"githat-chevron\">{open ? '\\u25B2' : '\\u25BC'}</span>\n </button>\n {open && (\n <div className=\"githat-dropdown\" role=\"menu\">\n {orgsLoading ? (\n <div className=\"githat-dropdown-item\" aria-busy=\"true\">Loading...</div>\n ) : orgs.map(o => (\n <button\n key={o.id}\n className={`githat-dropdown-item ${o.id === org.id ? 'githat-dropdown-item-active' : ''}`}\n role=\"menuitem\"\n aria-current={o.id === org.id ? 'true' : undefined}\n onClick={() => { switchOrg(o.id); setOpen(false); }}\n >\n {o.name}\n {o.id === org.id && <span className=\"githat-check\">{'\\u2713'}</span>}\n </button>\n ))}\n </div>\n )}\n </div>\n );\n}\n","'use client';\n\nimport React, { useState, useEffect, useRef } from 'react';\nimport { useGitHat } from '../hooks';\n\ninterface VerifiedBadgeProps {\n type: 'mcp' | 'agent';\n identifier: string;\n label?: string;\n}\n\nconst CACHE_TTL = 5 * 60 * 1000; // 5 minutes\nconst cache = new Map<string, { verified: boolean; ts: number }>();\n\nexport function VerifiedBadge({ type, identifier, label }: VerifiedBadgeProps) {\n const githat = useGitHat();\n const [verified, setVerified] = useState<boolean | null>(null);\n const mounted = useRef(true);\n\n useEffect(() => {\n mounted.current = true;\n const key = `${type}:${identifier}`;\n const cached = cache.get(key);\n if (cached && Date.now() - cached.ts < CACHE_TTL) {\n setVerified(cached.verified);\n return;\n }\n\n const verify = type === 'mcp' ? githat.verifyMCP : githat.verifyAgent;\n verify(identifier)\n .then(data => {\n if (mounted.current) {\n setVerified(data.verified);\n cache.set(key, { verified: data.verified, ts: Date.now() });\n }\n })\n .catch(() => { if (mounted.current) setVerified(false); });\n\n return () => { mounted.current = false; };\n }, [type, identifier]);\n\n if (verified === null) return null;\n\n return (\n <span className={`githat-badge ${verified ? 'githat-badge-verified' : 'githat-badge-unverified'}`}>\n {verified ? '\\u2713' : '\\u2717'} {label || (verified ? 'Verified' : 'Unverified')}\n </span>\n );\n}\n","'use client';\n\nimport React from 'react';\nimport { useAuth } from '../hooks';\n\ninterface ProtectedRouteProps {\n children: React.ReactNode;\n fallback?: React.ReactNode;\n}\n\nexport function ProtectedRoute({ children, fallback }: ProtectedRouteProps) {\n const { isSignedIn, isLoading, config } = useAuth();\n\n if (isLoading) {\n return <>{fallback || <div className=\"githat-loading\">Loading...</div>}</>;\n }\n\n if (!isSignedIn) {\n if (typeof window !== 'undefined') {\n window.location.href = config.signInUrl!;\n }\n return null;\n }\n\n return <>{children}</>;\n}\n"],"mappings":"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","names":["useMemo","useCallback","useMemo","useCallback","useMemo","useMemo","useState","jsx","useState","useState","jsx","jsxs","useState","useContext","jsx","useContext","useContext","jsx","useContext","useState","useRef","useEffect","jsx","jsxs","useState","useRef","useEffect","useState","useEffect","useRef","jsx","jsxs","useState","useRef","useEffect","useState","useEffect","useRef","jsxs","useState","useRef","useEffect","jsx"]}
@@ -1,10 +1,79 @@
1
1
  import { NextRequest, NextResponse } from 'next/server';
2
2
 
3
- interface AuthMiddlewareOptions {
3
+ interface AuthHandlerOptions {
4
+ /**
5
+ * Routes that don't require authentication.
6
+ * Supports exact paths ('/') and path prefixes ('/public/*').
7
+ */
4
8
  publicRoutes?: string[];
9
+ /**
10
+ * URL to redirect to when authentication is required but not present.
11
+ * @default '/sign-in'
12
+ */
5
13
  signInUrl?: string;
6
- tokenKey?: string;
14
+ /**
15
+ * Cookie name for the access token.
16
+ * @default 'githat_access'
17
+ */
18
+ tokenCookie?: string;
19
+ /**
20
+ * Legacy localStorage token cookie name (for backward compatibility).
21
+ * @default 'githat_access_token'
22
+ */
23
+ legacyTokenCookie?: string;
24
+ /**
25
+ * When true, decode the JWT and inject x-githat-* headers into the request.
26
+ * This allows downstream API routes to access user/org info without re-verifying.
27
+ *
28
+ * Injected headers:
29
+ * - x-githat-user-id: User's unique ID
30
+ * - x-githat-email: User's email address
31
+ * - x-githat-org-id: Current org ID (if any)
32
+ * - x-githat-org-slug: Current org slug (if any)
33
+ * - x-githat-role: User's role in the org (owner/admin/member)
34
+ *
35
+ * @default false
36
+ */
37
+ injectHeaders?: boolean;
38
+ /**
39
+ * Secret key for local JWT verification when injectHeaders is true.
40
+ * If not provided, headers are populated from the decoded (unverified) token payload.
41
+ * For production, always provide the secret key for full verification.
42
+ */
43
+ secretKey?: string;
7
44
  }
8
- declare function authMiddleware(options?: AuthMiddlewareOptions): (request: NextRequest) => NextResponse<unknown>;
9
45
 
10
- export { authMiddleware };
46
+ /**
47
+ * Options for the authMiddleware function.
48
+ * @see AuthHandlerOptions for detailed property documentation.
49
+ */
50
+ interface AuthMiddlewareOptions extends AuthHandlerOptions {
51
+ }
52
+ /**
53
+ * Creates an auth middleware handler for Next.js 14/15.
54
+ *
55
+ * @deprecated For Next.js 16+, use `authProxy` from `@githat/nextjs/proxy` instead.
56
+ * Next.js 16 renamed middleware.ts to proxy.ts. This export continues to work
57
+ * for Next.js 14/15 applications.
58
+ *
59
+ * @example
60
+ * ```typescript
61
+ * // middleware.ts (Next.js 14/15)
62
+ * import { authMiddleware } from '@githat/nextjs/middleware';
63
+ *
64
+ * export default authMiddleware({
65
+ * publicRoutes: ['/', '/about', '/pricing'],
66
+ * signInUrl: '/sign-in',
67
+ * });
68
+ *
69
+ * export const config = {
70
+ * matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
71
+ * };
72
+ * ```
73
+ *
74
+ * @param options - Configuration options for the auth middleware
75
+ * @returns A middleware function compatible with Next.js 14/15 middleware.ts convention
76
+ */
77
+ declare function authMiddleware(options?: AuthMiddlewareOptions): (request: NextRequest) => Promise<NextResponse>;
78
+
79
+ export { type AuthHandlerOptions, type AuthMiddlewareOptions as AuthMiddlewareConfig, type AuthMiddlewareOptions, authMiddleware };
@@ -1,10 +1,79 @@
1
1
  import { NextRequest, NextResponse } from 'next/server';
2
2
 
3
- interface AuthMiddlewareOptions {
3
+ interface AuthHandlerOptions {
4
+ /**
5
+ * Routes that don't require authentication.
6
+ * Supports exact paths ('/') and path prefixes ('/public/*').
7
+ */
4
8
  publicRoutes?: string[];
9
+ /**
10
+ * URL to redirect to when authentication is required but not present.
11
+ * @default '/sign-in'
12
+ */
5
13
  signInUrl?: string;
6
- tokenKey?: string;
14
+ /**
15
+ * Cookie name for the access token.
16
+ * @default 'githat_access'
17
+ */
18
+ tokenCookie?: string;
19
+ /**
20
+ * Legacy localStorage token cookie name (for backward compatibility).
21
+ * @default 'githat_access_token'
22
+ */
23
+ legacyTokenCookie?: string;
24
+ /**
25
+ * When true, decode the JWT and inject x-githat-* headers into the request.
26
+ * This allows downstream API routes to access user/org info without re-verifying.
27
+ *
28
+ * Injected headers:
29
+ * - x-githat-user-id: User's unique ID
30
+ * - x-githat-email: User's email address
31
+ * - x-githat-org-id: Current org ID (if any)
32
+ * - x-githat-org-slug: Current org slug (if any)
33
+ * - x-githat-role: User's role in the org (owner/admin/member)
34
+ *
35
+ * @default false
36
+ */
37
+ injectHeaders?: boolean;
38
+ /**
39
+ * Secret key for local JWT verification when injectHeaders is true.
40
+ * If not provided, headers are populated from the decoded (unverified) token payload.
41
+ * For production, always provide the secret key for full verification.
42
+ */
43
+ secretKey?: string;
7
44
  }
8
- declare function authMiddleware(options?: AuthMiddlewareOptions): (request: NextRequest) => NextResponse<unknown>;
9
45
 
10
- export { authMiddleware };
46
+ /**
47
+ * Options for the authMiddleware function.
48
+ * @see AuthHandlerOptions for detailed property documentation.
49
+ */
50
+ interface AuthMiddlewareOptions extends AuthHandlerOptions {
51
+ }
52
+ /**
53
+ * Creates an auth middleware handler for Next.js 14/15.
54
+ *
55
+ * @deprecated For Next.js 16+, use `authProxy` from `@githat/nextjs/proxy` instead.
56
+ * Next.js 16 renamed middleware.ts to proxy.ts. This export continues to work
57
+ * for Next.js 14/15 applications.
58
+ *
59
+ * @example
60
+ * ```typescript
61
+ * // middleware.ts (Next.js 14/15)
62
+ * import { authMiddleware } from '@githat/nextjs/middleware';
63
+ *
64
+ * export default authMiddleware({
65
+ * publicRoutes: ['/', '/about', '/pricing'],
66
+ * signInUrl: '/sign-in',
67
+ * });
68
+ *
69
+ * export const config = {
70
+ * matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
71
+ * };
72
+ * ```
73
+ *
74
+ * @param options - Configuration options for the auth middleware
75
+ * @returns A middleware function compatible with Next.js 14/15 middleware.ts convention
76
+ */
77
+ declare function authMiddleware(options?: AuthMiddlewareOptions): (request: NextRequest) => Promise<NextResponse>;
78
+
79
+ export { type AuthHandlerOptions, type AuthMiddlewareOptions as AuthMiddlewareConfig, type AuthMiddlewareOptions, authMiddleware };
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
 
20
30
  // src/middleware/index.ts
@@ -23,28 +33,102 @@ __export(middleware_exports, {
23
33
  authMiddleware: () => authMiddleware
24
34
  });
25
35
  module.exports = __toCommonJS(middleware_exports);
36
+
37
+ // src/lib/auth-handler.ts
26
38
  var import_server = require("next/server");
27
- function authMiddleware(options = {}) {
39
+ var jose = __toESM(require("jose"));
40
+ function decodeJwtPayload(token) {
41
+ try {
42
+ const parts = token.split(".");
43
+ if (parts.length !== 3) return null;
44
+ const payload = JSON.parse(atob(parts[1]));
45
+ return payload;
46
+ } catch {
47
+ return null;
48
+ }
49
+ }
50
+ async function verifyJwt(token, secretKey) {
51
+ try {
52
+ const secret = new TextEncoder().encode(secretKey);
53
+ const { payload } = await jose.jwtVerify(token, secret, {
54
+ algorithms: ["HS256"]
55
+ });
56
+ return payload;
57
+ } catch {
58
+ return null;
59
+ }
60
+ }
61
+ async function handleAuthRequest(request, options = {}) {
28
62
  const {
29
63
  publicRoutes = ["/"],
30
64
  signInUrl = "/sign-in",
31
- tokenKey = "githat_access_token"
65
+ tokenCookie = "githat_access",
66
+ legacyTokenCookie = "githat_access_token",
67
+ injectHeaders = false,
68
+ secretKey
32
69
  } = options;
33
- return function middleware(request) {
34
- const { pathname } = request.nextUrl;
35
- if (publicRoutes.some((route) => pathname === route || pathname.startsWith(route + "/"))) {
36
- return import_server.NextResponse.next();
37
- }
38
- if (pathname.startsWith("/_next") || pathname.startsWith("/api") || pathname.includes(".")) {
39
- return import_server.NextResponse.next();
70
+ const { pathname } = request.nextUrl;
71
+ const isPublic = publicRoutes.some((route) => {
72
+ if (route.endsWith("/*")) {
73
+ const prefix = route.slice(0, -1);
74
+ return pathname === prefix.slice(0, -1) || pathname.startsWith(prefix);
40
75
  }
41
- const token = request.cookies.get(tokenKey)?.value;
42
- if (!token) {
76
+ return pathname === route;
77
+ });
78
+ if (isPublic) {
79
+ return import_server.NextResponse.next();
80
+ }
81
+ if (pathname.startsWith("/_next") || pathname.startsWith("/api") || pathname.includes(".")) {
82
+ return import_server.NextResponse.next();
83
+ }
84
+ let token = request.cookies.get(tokenCookie)?.value;
85
+ if (!token) {
86
+ token = request.cookies.get(legacyTokenCookie)?.value;
87
+ }
88
+ if (!token) {
89
+ const signInUrlObj = new URL(signInUrl, request.url);
90
+ signInUrlObj.searchParams.set("redirect_url", pathname);
91
+ return import_server.NextResponse.redirect(signInUrlObj);
92
+ }
93
+ if (!injectHeaders) {
94
+ return import_server.NextResponse.next();
95
+ }
96
+ let payload = null;
97
+ if (secretKey) {
98
+ payload = await verifyJwt(token, secretKey);
99
+ if (!payload) {
43
100
  const signInUrlObj = new URL(signInUrl, request.url);
44
101
  signInUrlObj.searchParams.set("redirect_url", pathname);
45
102
  return import_server.NextResponse.redirect(signInUrlObj);
46
103
  }
47
- return import_server.NextResponse.next();
104
+ } else {
105
+ payload = decodeJwtPayload(token);
106
+ }
107
+ const response = import_server.NextResponse.next();
108
+ if (payload) {
109
+ if (payload.userId) {
110
+ response.headers.set("x-githat-user-id", String(payload.userId));
111
+ }
112
+ if (payload.email) {
113
+ response.headers.set("x-githat-email", String(payload.email));
114
+ }
115
+ if (payload.orgId) {
116
+ response.headers.set("x-githat-org-id", String(payload.orgId));
117
+ }
118
+ if (payload.orgSlug) {
119
+ response.headers.set("x-githat-org-slug", String(payload.orgSlug));
120
+ }
121
+ if (payload.orgRole) {
122
+ response.headers.set("x-githat-role", String(payload.orgRole));
123
+ }
124
+ }
125
+ return response;
126
+ }
127
+
128
+ // src/middleware/index.ts
129
+ function authMiddleware(options = {}) {
130
+ return async function middleware(request) {
131
+ return handleAuthRequest(request, options);
48
132
  };
49
133
  }
50
134
  // Annotate the CommonJS export names for ESM import in node:
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/middleware/index.ts"],"sourcesContent":["import { NextResponse } from 'next/server';\nimport type { NextRequest } from 'next/server';\n\ninterface AuthMiddlewareOptions {\n publicRoutes?: string[];\n signInUrl?: string;\n tokenKey?: string;\n}\n\nexport function authMiddleware(options: AuthMiddlewareOptions = {}) {\n const {\n publicRoutes = ['/'],\n signInUrl = '/sign-in',\n tokenKey = 'githat_access_token',\n } = options;\n\n return function middleware(request: NextRequest) {\n const { pathname } = request.nextUrl;\n\n // Allow public routes\n if (publicRoutes.some(route => pathname === route || pathname.startsWith(route + '/'))) {\n return NextResponse.next();\n }\n\n // Allow static files and API routes\n if (pathname.startsWith('/_next') || pathname.startsWith('/api') || pathname.includes('.')) {\n return NextResponse.next();\n }\n\n // Check for token in cookies (set by client-side localStorage bridge)\n // Note: since tokens are in localStorage (not cookies), middleware can only\n // do a presence check. Real validation happens on API calls.\n const token = request.cookies.get(tokenKey)?.value;\n if (!token) {\n const signInUrlObj = new URL(signInUrl, request.url);\n signInUrlObj.searchParams.set('redirect_url', pathname);\n return NextResponse.redirect(signInUrlObj);\n }\n\n return NextResponse.next();\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAA6B;AAStB,SAAS,eAAe,UAAiC,CAAC,GAAG;AAClE,QAAM;AAAA,IACJ,eAAe,CAAC,GAAG;AAAA,IACnB,YAAY;AAAA,IACZ,WAAW;AAAA,EACb,IAAI;AAEJ,SAAO,SAAS,WAAW,SAAsB;AAC/C,UAAM,EAAE,SAAS,IAAI,QAAQ;AAG7B,QAAI,aAAa,KAAK,WAAS,aAAa,SAAS,SAAS,WAAW,QAAQ,GAAG,CAAC,GAAG;AACtF,aAAO,2BAAa,KAAK;AAAA,IAC3B;AAGA,QAAI,SAAS,WAAW,QAAQ,KAAK,SAAS,WAAW,MAAM,KAAK,SAAS,SAAS,GAAG,GAAG;AAC1F,aAAO,2BAAa,KAAK;AAAA,IAC3B;AAKA,UAAM,QAAQ,QAAQ,QAAQ,IAAI,QAAQ,GAAG;AAC7C,QAAI,CAAC,OAAO;AACV,YAAM,eAAe,IAAI,IAAI,WAAW,QAAQ,GAAG;AACnD,mBAAa,aAAa,IAAI,gBAAgB,QAAQ;AACtD,aAAO,2BAAa,SAAS,YAAY;AAAA,IAC3C;AAEA,WAAO,2BAAa,KAAK;AAAA,EAC3B;AACF;","names":[]}
1
+ {"version":3,"sources":["../src/middleware/index.ts","../src/lib/auth-handler.ts"],"sourcesContent":["import type { NextRequest } from 'next/server';\nimport type { NextResponse } from 'next/server';\nimport { handleAuthRequest, AuthHandlerOptions } from '../lib/auth-handler';\n\n/**\n * Options for the authMiddleware function.\n * @see AuthHandlerOptions for detailed property documentation.\n */\nexport interface AuthMiddlewareOptions extends AuthHandlerOptions {}\n\n/**\n * Creates an auth middleware handler for Next.js 14/15.\n *\n * @deprecated For Next.js 16+, use `authProxy` from `@githat/nextjs/proxy` instead.\n * Next.js 16 renamed middleware.ts to proxy.ts. This export continues to work\n * for Next.js 14/15 applications.\n *\n * @example\n * ```typescript\n * // middleware.ts (Next.js 14/15)\n * import { authMiddleware } from '@githat/nextjs/middleware';\n *\n * export default authMiddleware({\n * publicRoutes: ['/', '/about', '/pricing'],\n * signInUrl: '/sign-in',\n * });\n *\n * export const config = {\n * matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],\n * };\n * ```\n *\n * @param options - Configuration options for the auth middleware\n * @returns A middleware function compatible with Next.js 14/15 middleware.ts convention\n */\nexport function authMiddleware(options: AuthMiddlewareOptions = {}) {\n return async function middleware(request: NextRequest): Promise<NextResponse> {\n return handleAuthRequest(request, options);\n };\n}\n\n// Re-export types for convenience\nexport type { AuthMiddlewareOptions as AuthMiddlewareConfig };\nexport type { AuthHandlerOptions };\n","import { NextResponse } from 'next/server';\nimport type { NextRequest } from 'next/server';\nimport * as jose from 'jose';\n\nexport interface AuthHandlerOptions {\n /**\n * Routes that don't require authentication.\n * Supports exact paths ('/') and path prefixes ('/public/*').\n */\n publicRoutes?: string[];\n\n /**\n * URL to redirect to when authentication is required but not present.\n * @default '/sign-in'\n */\n signInUrl?: string;\n\n /**\n * Cookie name for the access token.\n * @default 'githat_access'\n */\n tokenCookie?: string;\n\n /**\n * Legacy localStorage token cookie name (for backward compatibility).\n * @default 'githat_access_token'\n */\n legacyTokenCookie?: string;\n\n /**\n * When true, decode the JWT and inject x-githat-* headers into the request.\n * This allows downstream API routes to access user/org info without re-verifying.\n *\n * Injected headers:\n * - x-githat-user-id: User's unique ID\n * - x-githat-email: User's email address\n * - x-githat-org-id: Current org ID (if any)\n * - x-githat-org-slug: Current org slug (if any)\n * - x-githat-role: User's role in the org (owner/admin/member)\n *\n * @default false\n */\n injectHeaders?: boolean;\n\n /**\n * Secret key for local JWT verification when injectHeaders is true.\n * If not provided, headers are populated from the decoded (unverified) token payload.\n * For production, always provide the secret key for full verification.\n */\n secretKey?: string;\n}\n\n/**\n * Decode a JWT without verifying the signature.\n * Used when secretKey is not provided but we still want header injection.\n */\nfunction decodeJwtPayload(token: string): Record<string, unknown> | null {\n try {\n const parts = token.split('.');\n if (parts.length !== 3) return null;\n const payload = JSON.parse(atob(parts[1]));\n return payload;\n } catch {\n return null;\n }\n}\n\n/**\n * Verify a JWT and return the payload.\n * Uses jose for proper signature verification.\n */\nasync function verifyJwt(\n token: string,\n secretKey: string\n): Promise<Record<string, unknown> | null> {\n try {\n const secret = new TextEncoder().encode(secretKey);\n const { payload } = await jose.jwtVerify(token, secret, {\n algorithms: ['HS256'],\n });\n return payload as Record<string, unknown>;\n } catch {\n return null;\n }\n}\n\n/**\n * Shared auth handling logic for both middleware (Next.js 14/15) and proxy (Next.js 16+).\n * Validates authentication tokens and optionally injects headers with user/org info.\n */\nexport async function handleAuthRequest(\n request: NextRequest,\n options: AuthHandlerOptions = {}\n): Promise<NextResponse> {\n const {\n publicRoutes = ['/'],\n signInUrl = '/sign-in',\n tokenCookie = 'githat_access',\n legacyTokenCookie = 'githat_access_token',\n injectHeaders = false,\n secretKey,\n } = options;\n\n const { pathname } = request.nextUrl;\n\n // Allow public routes (exact match or prefix with /*)\n const isPublic = publicRoutes.some((route) => {\n if (route.endsWith('/*')) {\n const prefix = route.slice(0, -1); // Remove the *\n return pathname === prefix.slice(0, -1) || pathname.startsWith(prefix);\n }\n return pathname === route;\n });\n\n if (isPublic) {\n return NextResponse.next();\n }\n\n // Allow static files, Next.js internals, and API routes\n if (\n pathname.startsWith('/_next') ||\n pathname.startsWith('/api') ||\n pathname.includes('.')\n ) {\n return NextResponse.next();\n }\n\n // Check for token in cookies (try new httpOnly cookie first, then legacy)\n let token = request.cookies.get(tokenCookie)?.value;\n if (!token) {\n token = request.cookies.get(legacyTokenCookie)?.value;\n }\n\n // No token redirect to sign-in\n if (!token) {\n const signInUrlObj = new URL(signInUrl, request.url);\n signInUrlObj.searchParams.set('redirect_url', pathname);\n return NextResponse.redirect(signInUrlObj);\n }\n\n // If not injecting headers, just let the request through\n if (!injectHeaders) {\n return NextResponse.next();\n }\n\n // Decode or verify the token to inject headers\n let payload: Record<string, unknown> | null = null;\n\n if (secretKey) {\n // Full verification with secret key\n payload = await verifyJwt(token, secretKey);\n if (!payload) {\n // Token verification failed — redirect to sign-in\n const signInUrlObj = new URL(signInUrl, request.url);\n signInUrlObj.searchParams.set('redirect_url', pathname);\n return NextResponse.redirect(signInUrlObj);\n }\n } else {\n // Decode without verification (less secure, but works without secret)\n payload = decodeJwtPayload(token);\n }\n\n // Create a new response with injected headers\n const response = NextResponse.next();\n\n if (payload) {\n // Inject user/org info as headers\n if (payload.userId) {\n response.headers.set('x-githat-user-id', String(payload.userId));\n }\n if (payload.email) {\n response.headers.set('x-githat-email', String(payload.email));\n }\n if (payload.orgId) {\n response.headers.set('x-githat-org-id', String(payload.orgId));\n }\n if (payload.orgSlug) {\n response.headers.set('x-githat-org-slug', String(payload.orgSlug));\n }\n if (payload.orgRole) {\n response.headers.set('x-githat-role', String(payload.orgRole));\n }\n }\n\n return response;\n}\n"],"mappings":"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","names":[]}