@stackwright-pro/auth 0.1.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.
- package/README.md +33 -0
- package/dist/index.d.mts +1009 -0
- package/dist/index.d.ts +1009 -0
- package/dist/index.js +1182 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1124 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/schemas/auth-schemas.ts","../src/utils/cert-parser.ts","../src/providers/pki-provider.ts","../src/oidc/discovery.ts","../src/oidc/token-exchange.ts","../src/oidc/providers/keycloak-adapter.ts","../src/providers/oidc-provider.ts","../src/session/session-manager.ts","../src/session/cookie-helpers.ts","../src/rbac/rbac-engine.ts","../src/context/AuthContext.tsx","../src/context/AuthProvider.tsx","../src/profiles/dod-cac.ts","../src/decorators/withAuth.tsx","../src/registration.ts"],"names":["z","X509Certificate","jose","jose2","createContext","useContext","useMemo","jsx"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Zod Schemas for Runtime Validation\n * \n * These schemas provide runtime validation for all auth-related data structures.\n * They mirror the TypeScript types but enforce validation at runtime.\n */\n\nimport { z } from 'zod';\n\n// ============================================================================\n// Provider Configuration Schemas\n// ============================================================================\n\n/**\n * PKI Configuration Schema\n * Validates PKI auth config with sensible defaults\n */\nexport const pkiConfigSchema = z.object({\n type: z.literal('pki'),\n profile: z.enum(['dod_cac', 'piv', 'custom']),\n source: z.enum(['gateway_headers', 'direct_tls']),\n headerPrefix: z.string().optional().default('x-client-cert-'),\n verifiedHeader: z.string().optional().default('x-client-cert-verified'),\n requiredValue: z.string().optional().default('SUCCESS'),\n caChain: z.string().optional(),\n requiredOU: z.array(z.string()).optional(),\n allowedIssuers: z.array(z.string()).optional(),\n});\n\n/**\n * OIDC Configuration Schema\n * Validates OIDC provider config including claims mapping and quirks\n */\nexport const oidcConfigSchema = z.object({\n type: z.literal('oidc'),\n provider: z.enum([\n 'cognito',\n 'azure_ad',\n 'authentik',\n 'keycloak',\n 'okta',\n 'auth0',\n 'custom',\n ]),\n discoveryUrl: z.string().url(),\n clientId: z.string(),\n clientSecret: z.string(),\n redirectUri: z.string().optional(),\n claimsMapping: z\n .object({\n user_id: z.string().optional(),\n email: z.string().optional(),\n name: z.string().optional(),\n roles: z.string().optional(),\n })\n .optional(),\n quirks: z\n .object({\n skipIssuerCheck: z.boolean().optional(),\n useRefreshTokenRotation: z.boolean().optional(),\n })\n .optional(),\n});\n\n/**\n * Discriminated Union Schema\n * Auto-discriminates based on 'type' field for type-safe validation\n */\nexport const authConfigSchema = z.discriminatedUnion('type', [\n pkiConfigSchema,\n oidcConfigSchema,\n]);\n\n// ============================================================================\n// Component-Level Auth Schema\n// ============================================================================\n\n/**\n * Component Auth Configuration Schema\n * Validates YAML-based component auth requirements\n */\nexport const componentAuthSchema = z\n .object({\n required_roles: z.array(z.string()).optional(),\n required_permissions: z.array(z.string()).optional(),\n fallback: z.enum(['hide', 'placeholder', 'message']).optional().default('hide'),\n fallback_message: z.string().optional(),\n })\n .optional();\n\n// ============================================================================\n// RBAC Configuration Schema\n// ============================================================================\n\n/**\n * RBAC Configuration Schema\n * Validates role definitions, permissions, and route protection rules\n */\nexport const rbacConfigSchema = z.object({\n roles: z.array(\n z.object({\n name: z.string(),\n permissions: z.array(z.string()).optional(),\n })\n ),\n protected_routes: z\n .array(\n z.object({\n path: z.string(),\n roles: z.array(z.string()),\n })\n )\n .optional(),\n public_routes: z.array(z.string()).optional(),\n});\n\n// ============================================================================\n// User & Session Schemas\n// ============================================================================\n\n/**\n * Auth User Schema\n * Validates user objects with required id and roles\n */\nexport const authUserSchema = z.object({\n id: z.string(),\n email: z.string().email().optional(),\n name: z.string().optional(),\n roles: z.array(z.string()),\n permissions: z.array(z.string()).optional(),\n metadata: z.record(z.string(), z.any()).optional(),\n});\n\n/**\n * Auth Session Schema\n * Validates session structure including expiration timestamps\n */\nexport const authSessionSchema = z.object({\n user: authUserSchema,\n expiresAt: z.number(),\n issuedAt: z.number(),\n refreshToken: z.string().optional(),\n});\n","/**\n * X.509 Certificate Parser\n * \n * Utilities for parsing and validating X.509 certificates.\n * Supports both PEM/DER formats and gateway header extraction.\n */\n\nimport { X509Certificate } from '@peculiar/x509';\n\nexport interface ParsedCertificate {\n subject: {\n commonName?: string;\n email?: string;\n organizationalUnit?: string[];\n organization?: string;\n country?: string;\n };\n issuer: {\n commonName?: string;\n organization?: string;\n };\n serialNumber: string;\n notBefore: Date;\n notAfter: Date;\n isValid: boolean;\n}\n\n/**\n * Parse X.509 certificate from PEM string or DER buffer\n */\nexport function parseCertificate(pemOrDer: string | ArrayBuffer): ParsedCertificate {\n // Handle both PEM and DER formats\n const cert = new X509Certificate(pemOrDer);\n \n // Extract fields from subject name\n const subjectAttrs = cert.subject.split(',').map(s => s.trim());\n const issuerAttrs = cert.issuer.split(',').map(s => s.trim());\n \n return {\n subject: parseNameAttributes(subjectAttrs),\n issuer: {\n commonName: extractAttribute(issuerAttrs, 'CN'),\n organization: extractAttribute(issuerAttrs, 'O'),\n },\n serialNumber: cert.serialNumber,\n notBefore: cert.notBefore,\n notAfter: cert.notAfter,\n isValid: Date.now() >= cert.notBefore.getTime() && Date.now() <= cert.notAfter.getTime(),\n };\n}\n\n/**\n * Extract attribute value from name attributes array\n */\nfunction extractAttribute(attrs: string[], key: string): string | undefined {\n for (const attr of attrs) {\n const [attrKey, ...valueParts] = attr.split('=');\n if (attrKey.trim().toUpperCase() === key.toUpperCase()) {\n return valueParts.join('=').trim();\n }\n }\n return undefined;\n}\n\n/**\n * Extract all attributes with a given key (for multi-valued attributes like OU)\n */\nfunction extractAttributes(attrs: string[], key: string): string[] {\n const results: string[] = [];\n for (const attr of attrs) {\n const [attrKey, ...valueParts] = attr.split('=');\n if (attrKey.trim().toUpperCase() === key.toUpperCase()) {\n results.push(valueParts.join('=').trim());\n }\n }\n return results;\n}\n\n/**\n * Parse name attributes into structured subject object\n */\nfunction parseNameAttributes(attrs: string[]): ParsedCertificate['subject'] {\n return {\n commonName: extractAttribute(attrs, 'CN'),\n email: extractAttribute(attrs, 'E') || extractAttribute(attrs, 'emailAddress'),\n organizationalUnit: extractAttributes(attrs, 'OU'),\n organization: extractAttribute(attrs, 'O'),\n country: extractAttribute(attrs, 'C'),\n };\n}\n\n/**\n * Extract EDIPI from DoD CAC certificate\n * EDIPI is stored in OID 2.16.840.1.101.2.1.11.42\n */\nexport function extractEDIPI(cert: X509Certificate): string | undefined {\n const EDIPI_OID = '2.16.840.1.101.2.1.11.42';\n \n // Try to find EDIPI in certificate extensions\n for (const ext of cert.extensions) {\n if (ext.type === EDIPI_OID) {\n // Parse the extension value (it's ASN.1 encoded)\n const value = ext.value;\n // For now, return as hex string - can parse ASN.1 later if needed\n return Buffer.from(value).toString('hex');\n }\n }\n \n return undefined;\n}\n\n/**\n * Validate certificate against DoD CAC requirements\n */\nexport function validateDoDCAC(parsed: ParsedCertificate): boolean {\n // Check OU contains DOD or DoD\n const hasDoDOU = parsed.subject.organizationalUnit?.some(ou => \n ou.toUpperCase().includes('DOD') || ou === 'DoD'\n );\n \n // Check certificate is still valid\n if (!parsed.isValid) {\n return false;\n }\n \n // Must have DoD in OU\n if (!hasDoDOU) {\n return false;\n }\n \n return true;\n}\n\n/**\n * Parse certificate from gateway headers (x-client-cert-* pattern)\n */\nexport function parseCertFromHeaders(headers: Record<string, string>, prefix = 'x-client-cert-'): ParsedCertificate | null {\n const dnHeader = headers[`${prefix}dn`] || headers[`${prefix}subject-dn`];\n const serialHeader = headers[`${prefix}serial`];\n const verifiedHeader = headers[`${prefix}verified`];\n \n if (!dnHeader) {\n return null;\n }\n \n // Parse DN string (format: CN=John Doe,OU=DOD,O=U.S. Government,C=US)\n const subject = parseDN(dnHeader);\n \n // Note: Gateway headers don't give us full cert, so we construct minimal info\n return {\n subject,\n issuer: {}, // Not available from headers\n serialNumber: serialHeader || 'unknown',\n notBefore: new Date(0), // Not available from headers\n notAfter: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000), // Assume valid for a year\n isValid: verifiedHeader?.toUpperCase() === 'SUCCESS',\n };\n}\n\n/**\n * Parse Distinguished Name (DN) string into structured object\n */\nfunction parseDN(dn: string): ParsedCertificate['subject'] {\n const parts = dn.split(',').map(p => p.trim());\n const result: ParsedCertificate['subject'] = {\n organizationalUnit: [],\n };\n \n for (const part of parts) {\n const [key, ...valueParts] = part.split('=');\n const value = valueParts.join('='); // Handle values with = in them\n \n switch (key.toUpperCase()) {\n case 'CN':\n result.commonName = value;\n break;\n case 'E':\n case 'EMAILADDRESS':\n result.email = value;\n break;\n case 'OU':\n result.organizationalUnit?.push(value);\n break;\n case 'O':\n result.organization = value;\n break;\n case 'C':\n result.country = value;\n break;\n }\n }\n \n return result;\n}\n","/**\n * PKI Authentication Provider\n * \n * Implements certificate-based authentication supporting:\n * - Gateway header extraction (e.g., from NGINX, HAProxy)\n * - Direct TLS termination\n * - DoD CAC profile validation\n * - Custom PKI deployments\n */\n\nimport type { AuthProvider, AuthUser, AuthSession, AuthContext, PKIConfig } from '../types/index.js';\nimport { parseCertificate, parseCertFromHeaders, validateDoDCAC, extractEDIPI, type ParsedCertificate } from '../utils/cert-parser.js';\n\nexport class PKIProvider implements AuthProvider {\n constructor(private config: PKIConfig) {}\n\n async authenticate(context: AuthContext): Promise<AuthUser | null> {\n let parsed: ParsedCertificate | null = null;\n\n // Determine source of certificate data\n if (this.config.source === 'gateway_headers') {\n if (!context.headers) {\n return null;\n }\n parsed = parseCertFromHeaders(context.headers, this.config.headerPrefix);\n } else {\n // direct_tls - expect certificate in context\n // This would be set by server that terminates TLS\n const certData = context.headers?.['x-client-cert'];\n if (!certData) {\n return null;\n }\n parsed = parseCertificate(certData);\n }\n\n if (!parsed) {\n return null;\n }\n\n // Validate certificate is still valid\n if (!parsed.isValid) {\n return null;\n }\n\n // Apply profile-specific validation\n if (this.config.profile === 'dod_cac') {\n if (!validateDoDCAC(parsed)) {\n return null;\n }\n }\n\n // Check required OU if specified\n if (this.config.requiredOU) {\n const hasRequiredOU = this.config.requiredOU.some(required =>\n parsed!.subject.organizationalUnit?.some(ou => ou.includes(required))\n );\n if (!hasRequiredOU) {\n return null;\n }\n }\n\n // Check allowed issuers if specified\n if (this.config.allowedIssuers) {\n const issuerCN = parsed.issuer.commonName;\n if (!issuerCN || !this.config.allowedIssuers.includes(issuerCN)) {\n return null;\n }\n }\n\n // Extract user claims from certificate\n const user: AuthUser = {\n id: parsed.serialNumber, // Use serial as unique ID\n name: parsed.subject.commonName,\n email: parsed.subject.email,\n roles: this.extractRolesFromCertificate(parsed),\n metadata: {\n organizationalUnit: parsed.subject.organizationalUnit,\n organization: parsed.subject.organization,\n country: parsed.subject.country,\n issuer: parsed.issuer.commonName,\n notBefore: parsed.notBefore.toISOString(),\n notAfter: parsed.notAfter.toISOString(),\n },\n };\n\n return user;\n }\n\n async validate(session: AuthSession): Promise<boolean> {\n // Check session hasn't expired\n if (Date.now() > session.expiresAt) {\n return false;\n }\n\n // For PKI, we could re-validate the certificate here\n // But that requires storing cert data in session metadata\n // For now, trust the session if it hasn't expired\n\n return true;\n }\n\n /**\n * Extract roles from certificate based on organizational units\n * Can be customized per deployment via subclassing\n */\n private extractRolesFromCertificate(parsed: ParsedCertificate): string[] {\n const roles: string[] = [];\n\n // For DoD CAC, we might derive roles from OU\n const ous = parsed.subject.organizationalUnit || [];\n\n // Example role mapping (customize per deployment)\n if (ous.some(ou => ou.includes('ADMIN') || ou.includes('ADMINISTRATOR'))) {\n roles.push('ADMIN');\n } else if (ous.some(ou => ou.includes('ANALYST'))) {\n roles.push('ANALYST');\n } else {\n roles.push('VIEWER'); // Default role\n }\n\n return roles;\n }\n}\n","/**\n * OIDC Discovery Client\n * \n * Handles OIDC provider discovery and authorization URL generation.\n * Follows the OpenID Connect Discovery 1.0 specification.\n */\n\n/**\n * OIDC Provider Metadata (from .well-known/openid-configuration)\n */\nexport interface OIDCMetadata {\n issuer: string;\n authorization_endpoint: string;\n token_endpoint: string;\n jwks_uri: string;\n userinfo_endpoint?: string;\n end_session_endpoint?: string;\n scopes_supported?: string[];\n response_types_supported?: string[];\n}\n\n/**\n * Discover OIDC provider configuration\n * \n * Fetches the OIDC discovery document from the well-known endpoint.\n * This is the first step in any OIDC flow.\n * \n * @param discoveryUrl - Full URL to .well-known/openid-configuration\n * @returns OIDC metadata with endpoints and capabilities\n * @throws Error if discovery fails or metadata is invalid\n */\nexport async function discoverOIDC(discoveryUrl: string): Promise<OIDCMetadata> {\n const response = await fetch(discoveryUrl);\n \n if (!response.ok) {\n throw new Error(`OIDC discovery failed: ${response.statusText}`);\n }\n \n const metadata = await response.json() as any;\n \n // Validate required fields per OIDC spec\n if (!metadata.issuer || !metadata.authorization_endpoint || !metadata.token_endpoint || !metadata.jwks_uri) {\n throw new Error('Invalid OIDC metadata: missing required fields');\n }\n \n return metadata as OIDCMetadata;\n}\n\n/**\n * Generate authorization URL for OIDC login\n * \n * Builds the URL to redirect users to for authentication.\n * Follows OAuth 2.0 authorization code flow.\n * \n * @param metadata - OIDC provider metadata from discovery\n * @param clientId - OAuth client ID\n * @param redirectUri - Where to redirect after authentication\n * @param state - CSRF protection token (recommended)\n * @param scopes - OAuth scopes to request\n * @returns Authorization URL to redirect user to\n */\nexport function buildAuthorizationUrl(\n metadata: OIDCMetadata,\n clientId: string,\n redirectUri: string,\n state?: string,\n scopes: string[] = ['openid', 'profile', 'email']\n): string {\n const url = new URL(metadata.authorization_endpoint);\n url.searchParams.set('client_id', clientId);\n url.searchParams.set('redirect_uri', redirectUri);\n url.searchParams.set('response_type', 'code');\n url.searchParams.set('scope', scopes.join(' '));\n \n if (state) {\n url.searchParams.set('state', state);\n }\n \n return url.toString();\n}\n","/**\n * OIDC Token Exchange & Validation\n * \n * Handles OAuth2 token exchange, refresh, and JWT validation.\n * Uses jose for secure JWT operations.\n */\n\nimport * as jose from 'jose';\nimport type { OIDCMetadata } from './discovery.js';\n\nexport interface TokenSet {\n access_token: string;\n id_token: string;\n refresh_token?: string;\n expires_in: number;\n token_type: string;\n}\n\n/**\n * Exchange authorization code for tokens\n * \n * This is step 2 of the OAuth2 authorization code flow.\n * The authorization code is exchanged for access/ID/refresh tokens.\n * \n * @param metadata - OIDC provider metadata\n * @param code - Authorization code from callback\n * @param clientId - OAuth client ID\n * @param clientSecret - OAuth client secret\n * @param redirectUri - Must match the redirect_uri used in authorization\n * @returns Token set with access_token, id_token, and optionally refresh_token\n * @throws Error if token exchange fails\n */\nexport async function exchangeCodeForTokens(\n metadata: OIDCMetadata,\n code: string,\n clientId: string,\n clientSecret: string,\n redirectUri: string\n): Promise<TokenSet> {\n const response = await fetch(metadata.token_endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n 'Authorization': `Basic ${Buffer.from(`${clientId}:${clientSecret}`).toString('base64')}`,\n },\n body: new URLSearchParams({\n grant_type: 'authorization_code',\n code,\n redirect_uri: redirectUri,\n }),\n });\n \n if (!response.ok) {\n const error = await response.text();\n throw new Error(`Token exchange failed: ${error}`);\n }\n \n return await response.json() as TokenSet;\n}\n\n/**\n * Refresh access token using refresh token\n * \n * When access tokens expire, use the refresh token to get new ones\n * without requiring user to re-authenticate.\n * \n * @param metadata - OIDC provider metadata\n * @param refreshToken - Refresh token from initial token exchange\n * @param clientId - OAuth client ID\n * @param clientSecret - OAuth client secret\n * @returns New token set\n * @throws Error if refresh fails\n */\nexport async function refreshAccessToken(\n metadata: OIDCMetadata,\n refreshToken: string,\n clientId: string,\n clientSecret: string\n): Promise<TokenSet> {\n const response = await fetch(metadata.token_endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n 'Authorization': `Basic ${Buffer.from(`${clientId}:${clientSecret}`).toString('base64')}`,\n },\n body: new URLSearchParams({\n grant_type: 'refresh_token',\n refresh_token: refreshToken,\n }),\n });\n \n if (!response.ok) {\n throw new Error('Token refresh failed');\n }\n \n return await response.json() as TokenSet;\n}\n\n/**\n * Validate ID token JWT and extract claims\n * \n * Verifies the JWT signature using the provider's JWKS and validates\n * standard claims (issuer, audience, expiration).\n * \n * This is critical for security - never trust an ID token without validation!\n * \n * @param idToken - JWT ID token from token exchange\n * @param jwksUri - JWKS URI from OIDC metadata\n * @param issuer - Expected issuer (should match token's iss claim)\n * @param clientId - Expected audience (should match token's aud claim)\n * @param skipIssuerCheck - Skip issuer validation (use for Keycloak quirks)\n * @returns Validated JWT payload with user claims\n * @throws Error if JWT validation fails\n */\nexport async function validateIdToken(\n idToken: string,\n jwksUri: string,\n issuer: string,\n clientId: string,\n skipIssuerCheck = false\n): Promise<Record<string, any>> {\n // Fetch JWKS for signature validation\n const JWKS = jose.createRemoteJWKSet(new URL(jwksUri));\n \n // Verify JWT signature and claims\n const { payload } = await jose.jwtVerify(idToken, JWKS, {\n issuer: skipIssuerCheck ? undefined : issuer,\n audience: clientId,\n });\n \n return payload as Record<string, any>;\n}\n","/**\n * Keycloak-specific OIDC Adapter\n * \n * Keycloak has several quirks in its OIDC implementation that require\n * special handling. This adapter normalizes Keycloak behavior.\n * \n * Known Issues:\n * 1. Issuer in token doesn't always match discovery URL\n * 2. Refresh token rotation is inconsistent\n * 3. Claims structure differs from standard OIDC\n * 4. Role mapping is non-standard (realm_access.roles)\n */\n\n/**\n * Keycloak-specific OIDC adapter\n * \n * Use this when working with Keycloak to handle its many quirks.\n * Tested with Keycloak 19.x - 23.x\n */\nexport class KeycloakAdapter {\n /**\n * Normalize Keycloak issuer (remove /auth prefix if present)\n * \n * Keycloak's issuer URLs changed between versions:\n * - Pre-17: https://keycloak.example.com/auth/realms/myrealm\n * - Post-17: https://keycloak.example.com/realms/myrealm\n * \n * This normalizes to the post-17 format.\n * \n * @param issuer - Issuer from token or metadata\n * @returns Normalized issuer\n */\n static normalizeIssuer(issuer: string): string {\n return issuer.replace('/auth/realms/', '/realms/');\n }\n \n /**\n * Map Keycloak-specific claims to standard format\n * \n * Keycloak stores roles and groups in non-standard locations:\n * - Roles: realm_access.roles (not standard)\n * - Groups: groups array (sometimes, if configured)\n * - Username: preferred_username (not always 'name')\n * \n * @param tokenPayload - Raw JWT payload from Keycloak\n * @returns Normalized claims matching AuthUser interface\n */\n static mapClaims(tokenPayload: Record<string, any>): Record<string, any> {\n return {\n user_id: tokenPayload.sub,\n email: tokenPayload.email,\n name: tokenPayload.name || tokenPayload.preferred_username,\n roles: tokenPayload.realm_access?.roles || [],\n groups: tokenPayload.groups || [],\n // Keep original payload for advanced use cases\n ...tokenPayload,\n };\n }\n \n /**\n * Keycloak refresh tokens should be refreshed earlier than spec suggests\n * \n * Keycloak's refresh token rotation is buggy and sometimes fails if you\n * wait too long. Refresh aggressively when less than 10 minutes remain.\n * \n * @param expiresIn - Seconds until token expires\n * @returns true if token should be refreshed now\n */\n static shouldRefreshToken(expiresIn: number): boolean {\n // Refresh when less than 10 minutes remaining (Keycloak's rotation is buggy)\n return expiresIn < 600;\n }\n}\n","/**\n * OIDC Authentication Provider\n * \n * Implements the AuthProvider interface for OAuth2/OIDC authentication.\n * Supports major providers (Cognito, Azure AD, Keycloak, etc.) with\n * configurable claims mapping and provider-specific quirks handling.\n */\n\nimport type { AuthProvider, AuthUser, AuthSession, AuthContext, OIDCConfig } from '../types/index.js';\nimport { discoverOIDC, buildAuthorizationUrl, type OIDCMetadata } from '../oidc/discovery.js';\nimport { exchangeCodeForTokens, validateIdToken, refreshAccessToken } from '../oidc/token-exchange.js';\nimport { KeycloakAdapter } from '../oidc/providers/keycloak-adapter.js';\n\n/**\n * OIDC Provider\n * \n * Handles OAuth2/OIDC authentication flows including:\n * - Discovery of OIDC configuration\n * - Authorization code exchange\n * - JWT validation\n * - Session refresh\n * - Provider-specific quirks (Keycloak, Cognito, etc.)\n */\nexport class OIDCProvider implements AuthProvider {\n private metadata: OIDCMetadata | null = null;\n \n constructor(private config: OIDCConfig) {}\n \n /**\n * Initialize provider by discovering OIDC configuration\n * \n * Call this during app startup to pre-fetch OIDC metadata.\n * If not called, metadata will be lazily loaded on first use.\n */\n async initialize(): Promise<void> {\n this.metadata = await discoverOIDC(this.config.discoveryUrl);\n }\n \n /**\n * Get metadata (lazy load if not initialized)\n * \n * @returns OIDC metadata\n */\n private async getMetadata(): Promise<OIDCMetadata> {\n if (!this.metadata) {\n await this.initialize();\n }\n return this.metadata!;\n }\n \n /**\n * Authenticate user by exchanging authorization code for tokens\n * \n * This is called after the user is redirected back from the OIDC provider\n * with an authorization code in the query parameters.\n * \n * @param context - Auth context with query params containing authorization code\n * @returns Authenticated user or null if no code present\n * @throws Error if token exchange or validation fails\n */\n async authenticate(context: AuthContext): Promise<AuthUser | null> {\n const code = context.query?.code;\n const redirectUri = this.config.redirectUri || '/api/auth/callback';\n \n if (!code) {\n return null;\n }\n \n const metadata = await this.getMetadata();\n \n // Exchange code for tokens\n const tokens = await exchangeCodeForTokens(\n metadata,\n code,\n this.config.clientId,\n this.config.clientSecret,\n redirectUri\n );\n \n // Validate ID token and extract claims\n const issuer = this.config.quirks?.skipIssuerCheck \n ? undefined \n : (this.config.provider === 'keycloak' \n ? KeycloakAdapter.normalizeIssuer(metadata.issuer)\n : metadata.issuer);\n \n const claims = await validateIdToken(\n tokens.id_token,\n metadata.jwks_uri,\n issuer || metadata.issuer,\n this.config.clientId,\n this.config.quirks?.skipIssuerCheck\n );\n \n // Map claims to AuthUser based on provider-specific logic\n const mappedClaims = this.config.provider === 'keycloak'\n ? KeycloakAdapter.mapClaims(claims)\n : claims;\n \n // Apply custom claims mapping if provided\n const user: AuthUser = {\n id: this.getClaimValue(mappedClaims, this.config.claimsMapping?.user_id, 'sub'),\n email: this.getClaimValue(mappedClaims, this.config.claimsMapping?.email, 'email'),\n name: this.getClaimValue(mappedClaims, this.config.claimsMapping?.name, 'name'),\n roles: this.extractRoles(mappedClaims),\n metadata: {\n provider: this.config.provider,\n originalClaims: mappedClaims,\n },\n };\n \n return user;\n }\n \n /**\n * Validate session (check if token is still valid)\n * \n * Simple time-based validation. For more security, you could:\n * - Call the userinfo endpoint\n * - Verify token hasn't been revoked\n * - Check against a session store\n * \n * @param session - Session to validate\n * @returns true if session is still valid\n */\n async validate(session: AuthSession): Promise<boolean> {\n // Check if session has expired\n if (Date.now() > session.expiresAt) {\n return false;\n }\n \n return true;\n }\n \n /**\n * Refresh session using refresh token\n * \n * When the access token expires, use the refresh token to get new tokens\n * without requiring the user to re-authenticate.\n * \n * @param session - Session with refresh token\n * @returns Updated session with new tokens, or null if refresh failed\n */\n async refresh(session: AuthSession): Promise<AuthSession | null> {\n if (!session.refreshToken) {\n return null;\n }\n \n const metadata = await this.getMetadata();\n \n try {\n const tokens = await refreshAccessToken(\n metadata,\n session.refreshToken,\n this.config.clientId,\n this.config.clientSecret\n );\n \n // Return updated session with new tokens\n return {\n ...session,\n expiresAt: Date.now() + tokens.expires_in * 1000,\n refreshToken: tokens.refresh_token || session.refreshToken,\n };\n } catch (error) {\n return null;\n }\n }\n \n /**\n * Get authorization URL for initiating OIDC login\n * \n * Redirect users to this URL to start the authentication flow.\n * \n * @param redirectUri - Where to redirect after authentication\n * @param state - CSRF protection token (recommended)\n * @returns Authorization URL\n */\n async getAuthorizationUrl(redirectUri: string, state?: string): Promise<string> {\n const metadata = await this.getMetadata();\n return buildAuthorizationUrl(metadata, this.config.clientId, redirectUri, state);\n }\n \n /**\n * Extract claim value with fallback\n * \n * Tries custom mapped key first, then falls back to default key.\n * \n * @param claims - JWT claims\n * @param mappedKey - Custom mapped key from config\n * @param defaultKey - Default OIDC key\n * @returns Claim value or undefined\n */\n private getClaimValue(claims: Record<string, any>, mappedKey?: string, defaultKey?: string): any {\n if (mappedKey && claims[mappedKey]) {\n return claims[mappedKey];\n }\n if (defaultKey && claims[defaultKey]) {\n return claims[defaultKey];\n }\n return undefined;\n }\n \n /**\n * Extract roles from claims (provider-specific logic)\n * \n * Different OIDC providers store roles in different places:\n * - Standard: 'roles' claim\n * - Keycloak: realm_access.roles\n * - Cognito: cognito:groups\n * - Azure AD: roles claim\n * \n * @param claims - JWT claims\n * @returns Array of role strings\n */\n private extractRoles(claims: Record<string, any>): string[] {\n // Try custom mapping first\n if (this.config.claimsMapping?.roles) {\n const rolesValue = claims[this.config.claimsMapping.roles];\n if (Array.isArray(rolesValue)) {\n return rolesValue;\n }\n if (typeof rolesValue === 'string') {\n return [rolesValue];\n }\n }\n \n // Standard OIDC claims\n if (Array.isArray(claims.roles)) {\n return claims.roles;\n }\n \n // Keycloak realm_access.roles\n if (claims.realm_access?.roles) {\n return claims.realm_access.roles;\n }\n \n // Cognito cognito:groups\n if (claims['cognito:groups']) {\n return claims['cognito:groups'];\n }\n \n // Default: no roles\n return [];\n }\n}\n","import * as jose from 'jose';\nimport type { AuthUser, AuthSession } from '../types/index.js';\n\nexport interface SessionManagerConfig {\n /**\n * Secret key for JWT signing (must be at least 32 bytes)\n */\n secret: string;\n \n /**\n * Session duration in seconds (default: 15 minutes)\n */\n sessionDuration?: number;\n \n /**\n * Algorithm for JWT signing (default: HS256)\n */\n algorithm?: string;\n \n /**\n * Issuer claim for JWT\n */\n issuer?: string;\n \n /**\n * Audience claim for JWT\n */\n audience?: string;\n}\n\nexport class SessionManager {\n private secret: Uint8Array;\n private sessionDuration: number;\n private algorithm: string;\n private issuer?: string;\n private audience?: string;\n \n constructor(config: SessionManagerConfig) {\n // Validate secret length\n if (config.secret.length < 32) {\n throw new Error('Session secret must be at least 32 characters');\n }\n \n // Convert string secret to Uint8Array for jose\n this.secret = new TextEncoder().encode(config.secret);\n this.sessionDuration = config.sessionDuration || 900; // 15 minutes default\n this.algorithm = config.algorithm || 'HS256';\n this.issuer = config.issuer;\n this.audience = config.audience;\n }\n \n /**\n * Create a new session for authenticated user\n */\n async createSession(user: AuthUser, refreshToken?: string): Promise<AuthSession> {\n const now = Date.now();\n const expiresAt = now + this.sessionDuration * 1000;\n \n const session: AuthSession = {\n user,\n issuedAt: now,\n expiresAt,\n refreshToken,\n };\n \n return session;\n }\n \n /**\n * Sign session into a JWT\n */\n async signSession(session: AuthSession): Promise<string> {\n const jwt = await new jose.SignJWT({\n user: session.user,\n refreshToken: session.refreshToken,\n })\n .setProtectedHeader({ alg: this.algorithm })\n .setIssuedAt(session.issuedAt / 1000) // jose expects seconds\n .setExpirationTime(session.expiresAt / 1000)\n .setIssuer(this.issuer || 'stackwright-auth')\n .setAudience(this.audience || 'stackwright-app')\n .sign(this.secret);\n \n return jwt;\n }\n \n /**\n * Verify and decode session JWT\n */\n async verifySession(jwt: string): Promise<AuthSession | null> {\n try {\n const { payload } = await jose.jwtVerify(jwt, this.secret, {\n issuer: this.issuer || 'stackwright-auth',\n audience: this.audience || 'stackwright-app',\n });\n \n // Reconstruct session from payload\n const session: AuthSession = {\n user: payload.user as AuthUser,\n issuedAt: (payload.iat || 0) * 1000, // Convert back to milliseconds\n expiresAt: (payload.exp || 0) * 1000,\n refreshToken: payload.refreshToken as string | undefined,\n };\n \n return session;\n } catch (error) {\n // JWT verification failed (expired, invalid signature, etc.)\n return null;\n }\n }\n \n /**\n * Check if session is expired\n */\n isExpired(session: AuthSession): boolean {\n return Date.now() > session.expiresAt;\n }\n \n /**\n * Check if session should be refreshed (within 5 minutes of expiry)\n */\n shouldRefresh(session: AuthSession): boolean {\n const timeUntilExpiry = session.expiresAt - Date.now();\n const REFRESH_THRESHOLD = 5 * 60 * 1000; // 5 minutes\n \n return timeUntilExpiry < REFRESH_THRESHOLD && timeUntilExpiry > 0;\n }\n \n /**\n * Refresh session (extend expiration)\n */\n async refreshSession(session: AuthSession): Promise<AuthSession> {\n return {\n ...session,\n issuedAt: Date.now(),\n expiresAt: Date.now() + this.sessionDuration * 1000,\n };\n }\n \n /**\n * Serialize session to string (for cookies/localStorage)\n */\n async serialize(session: AuthSession): Promise<string> {\n return this.signSession(session);\n }\n \n /**\n * Deserialize session from string\n */\n async deserialize(serialized: string): Promise<AuthSession | null> {\n return this.verifySession(serialized);\n }\n}\n","/**\n * Cookie options for session cookies\n */\nexport interface CookieOptions {\n /**\n * Cookie name (default: 'stackwright_session')\n */\n name?: string;\n \n /**\n * Domain for cookie\n */\n domain?: string;\n \n /**\n * Path for cookie (default: '/')\n */\n path?: string;\n \n /**\n * Max age in seconds\n */\n maxAge?: number;\n \n /**\n * HttpOnly flag (default: true)\n */\n httpOnly?: boolean;\n \n /**\n * Secure flag (default: true in production)\n */\n secure?: boolean;\n \n /**\n * SameSite policy (default: 'lax')\n */\n sameSite?: 'strict' | 'lax' | 'none';\n}\n\n/**\n * Serialize cookie with options\n */\nexport function serializeCookie(\n name: string,\n value: string,\n options: CookieOptions = {}\n): string {\n const {\n domain,\n path = '/',\n maxAge,\n httpOnly = true,\n secure = process.env.NODE_ENV === 'production',\n sameSite = 'lax',\n } = options;\n \n const parts: string[] = [\n `${name}=${encodeURIComponent(value)}`,\n ];\n \n if (domain) {\n parts.push(`Domain=${domain}`);\n }\n \n parts.push(`Path=${path}`);\n \n if (maxAge !== undefined) {\n parts.push(`Max-Age=${maxAge}`);\n }\n \n if (httpOnly) {\n parts.push('HttpOnly');\n }\n \n if (secure) {\n parts.push('Secure');\n }\n \n if (sameSite) {\n parts.push(`SameSite=${sameSite.charAt(0).toUpperCase() + sameSite.slice(1)}`);\n }\n \n return parts.join('; ');\n}\n\n/**\n * Parse cookie string into key-value pairs\n */\nexport function parseCookies(cookieHeader?: string): Record<string, string> {\n if (!cookieHeader) {\n return {};\n }\n \n const cookies: Record<string, string> = {};\n \n for (const cookie of cookieHeader.split(';')) {\n const [key, ...valueParts] = cookie.trim().split('=');\n if (key) {\n cookies[key] = decodeURIComponent(valueParts.join('='));\n }\n }\n \n return cookies;\n}\n\n/**\n * Create a cookie header for clearing/deleting a cookie\n */\nexport function clearCookie(name: string, options: Pick<CookieOptions, 'domain' | 'path'> = {}): string {\n return serializeCookie(name, '', {\n ...options,\n maxAge: 0,\n });\n}\n","import type { AuthUser, RBACConfig, ComponentAuthConfig } from '../types/index.js';\n\n/**\n * RBAC Engine for checking roles and permissions\n */\nexport class RBACEngine {\n private config: RBACConfig;\n private rolePermissions: Map<string, Set<string>>;\n \n constructor(config: RBACConfig) {\n this.config = config;\n this.rolePermissions = this.buildRolePermissionMap();\n }\n \n /**\n * Build internal map of role → permissions for fast lookups\n */\n private buildRolePermissionMap(): Map<string, Set<string>> {\n const map = new Map<string, Set<string>>();\n \n for (const role of this.config.roles) {\n map.set(role.name, new Set(role.permissions || []));\n }\n \n return map;\n }\n \n /**\n * Check if user has a specific role\n */\n hasRole(user: AuthUser, role: string): boolean {\n return user.roles.includes(role);\n }\n \n /**\n * Check if user has any of the specified roles\n */\n hasAnyRole(user: AuthUser, roles: string[]): boolean {\n return roles.some(role => this.hasRole(user, role));\n }\n \n /**\n * Check if user has all of the specified roles\n */\n hasAllRoles(user: AuthUser, roles: string[]): boolean {\n return roles.every(role => this.hasRole(user, role));\n }\n \n /**\n * Check if user has a specific permission\n * Permissions are checked both:\n * 1. Directly in user.permissions array\n * 2. Through role-based permissions from config\n */\n hasPermission(user: AuthUser, permission: string): boolean {\n // Check direct permissions\n if (user.permissions?.includes(permission)) {\n return true;\n }\n \n // Check role-based permissions\n for (const role of user.roles) {\n const permissions = this.rolePermissions.get(role);\n if (permissions?.has(permission)) {\n return true;\n }\n \n // Check wildcard permissions (e.g., admin:* grants admin:read, admin:write)\n if (permissions) {\n for (const p of permissions) {\n if (p.endsWith(':*')) {\n const prefix = p.slice(0, -1); // Remove the *\n if (permission.startsWith(prefix)) {\n return true;\n }\n }\n }\n }\n }\n \n return false;\n }\n \n /**\n * Check if user has any of the specified permissions\n */\n hasAnyPermission(user: AuthUser, permissions: string[]): boolean {\n return permissions.some(permission => this.hasPermission(user, permission));\n }\n \n /**\n * Check if user has all of the specified permissions\n */\n hasAllPermissions(user: AuthUser, permissions: string[]): boolean {\n return permissions.every(permission => this.hasPermission(user, permission));\n }\n \n /**\n * Check if route is public (no auth required)\n */\n isPublicRoute(path: string): boolean {\n if (!this.config.public_routes) {\n return false;\n }\n \n return this.config.public_routes.some(publicPath => {\n return this.matchPath(path, publicPath);\n });\n }\n \n /**\n * Check if user can access a route based on protected_routes config\n */\n canAccessRoute(user: AuthUser | null, path: string): boolean {\n // Check if route is public\n if (this.isPublicRoute(path)) {\n return true;\n }\n \n // No user = can't access protected routes\n if (!user) {\n return false;\n }\n \n // If no protected routes configured, allow by default\n if (!this.config.protected_routes || this.config.protected_routes.length === 0) {\n return true;\n }\n \n // Find matching protected route\n const matchingRoute = this.config.protected_routes.find(route => {\n return this.matchPath(path, route.path);\n });\n \n // If no matching protected route, allow (route not explicitly protected)\n if (!matchingRoute) {\n return true;\n }\n \n // Check if user has required role for this route\n return this.hasAnyRole(user, matchingRoute.roles);\n }\n \n /**\n * Check if user can access a component based on component auth config\n */\n canAccessComponent(user: AuthUser | null, authConfig: ComponentAuthConfig | undefined): boolean {\n // No auth config = public component\n if (!authConfig) {\n return true;\n }\n \n // No user = can't access protected component\n if (!user) {\n return false;\n }\n \n // Check required roles\n if (authConfig.required_roles && authConfig.required_roles.length > 0) {\n if (!this.hasAnyRole(user, authConfig.required_roles)) {\n return false;\n }\n }\n \n // Check required permissions\n if (authConfig.required_permissions && authConfig.required_permissions.length > 0) {\n if (!this.hasAllPermissions(user, authConfig.required_permissions)) {\n return false;\n }\n }\n \n return true;\n }\n \n\n // Match a path against a pattern with wildcard support\n private matchPath(path: string, pattern: string): boolean {\n // Exact match\n if (path === pattern) {\n return true;\n }\n \n // No wildcards in pattern\n if (!pattern.includes('*')) {\n return false;\n }\n \n // Convert pattern to regex\n const regexPattern = pattern\n .replace(/\\*/g, '.*') // * becomes .*\n .replace(/\\//g, '\\\\/'); // Escape slashes\n \n const regex = new RegExp(`^${regexPattern}$`);\n return regex.test(path);\n }\n}\n","import { createContext, useContext } from 'react';\nimport type { AuthUser, AuthSession } from '../types/index.js';\n\n/**\n * Auth context value provided to component tree\n */\nexport interface AuthContextValue {\n /**\n * Currently authenticated user (null if not authenticated)\n */\n user: AuthUser | null;\n \n /**\n * Current session (null if not authenticated)\n */\n session: AuthSession | null;\n \n /**\n * Whether user is authenticated\n */\n isAuthenticated: boolean;\n \n /**\n * Whether auth is still loading\n */\n isLoading: boolean;\n \n /**\n * Check if user has a specific role\n */\n hasRole: (role: string) => boolean;\n \n /**\n * Check if user has a specific permission\n */\n hasPermission: (permission: string) => boolean;\n \n /**\n * Check if user has any of the specified roles\n */\n hasAnyRole: (roles: string[]) => boolean;\n \n /**\n * Check if user has all of the specified permissions\n */\n hasAllPermissions: (permissions: string[]) => boolean;\n}\n\n/**\n * Auth context - provides authentication state to components\n */\nexport const AuthContext = createContext<AuthContextValue | null>(null);\n\n/**\n * Hook to access auth context\n * Throws error if used outside AuthProvider\n */\nexport function useAuth(): AuthContextValue {\n const context = useContext(AuthContext);\n \n if (!context) {\n throw new Error('useAuth must be used within AuthProvider');\n }\n \n return context;\n}\n\n/**\n * Hook to require authentication\n * Returns null and logs warning if not authenticated\n */\nexport function useRequireAuth(): AuthContextValue | null {\n const auth = useAuth();\n \n if (!auth.isAuthenticated) {\n console.warn('useRequireAuth: User is not authenticated');\n return null;\n }\n \n return auth;\n}\n","import React, { useMemo, type ReactNode, type ReactElement } from 'react';\nimport { AuthContext, type AuthContextValue } from './AuthContext.js';\nimport { RBACEngine } from '../rbac/rbac-engine.js';\nimport type { AuthUser, AuthSession, RBACConfig } from '../types/index.js';\n\nexport interface AuthProviderProps {\n /**\n * Current authenticated user (null if not authenticated)\n */\n user: AuthUser | null;\n \n /**\n * Current session (null if not authenticated)\n */\n session: AuthSession | null;\n \n /**\n * RBAC configuration for role/permission checking\n */\n rbacConfig: RBACConfig;\n \n /**\n * Whether auth is still loading\n */\n isLoading?: boolean;\n \n /**\n * Child components\n */\n children: ReactNode;\n}\n\n/**\n * AuthProvider - Provides authentication state to component tree\n * \n * @example\n * ```tsx\n * <AuthProvider user={user} session={session} rbacConfig={config}>\n * <App />\n * </AuthProvider>\n * ```\n */\nexport function AuthProvider({\n user,\n session,\n rbacConfig,\n isLoading = false,\n children,\n}: AuthProviderProps): ReactElement {\n // Create RBAC engine for role/permission checking\n const rbac = useMemo(() => new RBACEngine(rbacConfig), [rbacConfig]);\n \n // Build context value with helper functions\n const value: AuthContextValue = useMemo(() => ({\n user,\n session,\n isAuthenticated: user !== null,\n isLoading,\n \n hasRole: (role: string) => {\n if (!user) return false;\n return rbac.hasRole(user, role);\n },\n \n hasPermission: (permission: string) => {\n if (!user) return false;\n return rbac.hasPermission(user, permission);\n },\n \n hasAnyRole: (roles: string[]) => {\n if (!user) return false;\n return rbac.hasAnyRole(user, roles);\n },\n \n hasAllPermissions: (permissions: string[]) => {\n if (!user) return false;\n return rbac.hasAllPermissions(user, permissions);\n },\n }), [user, session, isLoading, rbac]);\n \n return (\n <AuthContext.Provider value={value}>\n {children}\n </AuthContext.Provider>\n );\n}\n","/**\n * DoD CAC Profile Configuration\n * \n * Pre-built profile for DoD Common Access Card (CAC) certificates.\n * \n * This profile includes:\n * - List of trusted DoD CA issuers\n * - Required OU validation (DOD)\n * - EDIPI extraction for user ID\n * \n * Last updated: 2025-01 (DoD PKI CA list)\n * \n * Note: DoD PKI infrastructure is regularly updated. Verify current CA list at:\n * https://public.cyber.mil/pki-pke/\n */\n\nimport type { PKIConfig } from '../types/index.js';\n\n/**\n * DoD CAC profile configuration\n * \n * This provides sensible defaults for DoD CAC authentication in most deployments.\n * Assumes gateway (e.g., NGINX, HAProxy) handles mTLS and forwards headers.\n */\nexport const DOD_CAC_PROFILE: Omit<PKIConfig, 'type'> = {\n profile: 'dod_cac',\n source: 'gateway_headers',\n headerPrefix: 'x-client-cert-',\n verifiedHeader: 'x-client-cert-verified',\n requiredValue: 'SUCCESS',\n requiredOU: ['DOD', 'DoD', 'U.S. Government'],\n \n // DoD Root CAs (add current list)\n // These are sample CA names - verify against current DoD PKI infrastructure\n allowedIssuers: [\n // DoD Interoperability Root CA 2\n 'CN=DoD Interoperability Root CA 2',\n \n // DoD Root CA 3-6 (current generation)\n 'CN=DoD Root CA 3',\n 'CN=DoD Root CA 4',\n 'CN=DoD Root CA 5',\n 'CN=DoD Root CA 6',\n \n // DoD ID CAs (email/PIV auth)\n 'CN=DOD ID CA-59',\n 'CN=DOD ID CA-60',\n 'CN=DOD ID CA-61',\n 'CN=DOD ID CA-62',\n 'CN=DOD ID CA-63',\n 'CN=DOD ID CA-64',\n 'CN=DOD ID CA-65',\n 'CN=DOD ID CA-66',\n 'CN=DOD ID CA-67',\n 'CN=DOD ID CA-68',\n 'CN=DOD ID CA-69',\n 'CN=DOD ID CA-70',\n \n // DoD SW CAs (software/device auth)\n 'CN=DOD SW CA-59',\n 'CN=DOD SW CA-60',\n 'CN=DOD SW CA-61',\n 'CN=DOD SW CA-62',\n 'CN=DOD SW CA-63',\n 'CN=DOD SW CA-64',\n 'CN=DOD SW CA-65',\n 'CN=DOD SW CA-66',\n \n // Legacy DoD Email CAs (being phased out but may still be in use)\n 'CN=DOD EMAIL CA-59',\n 'CN=DOD EMAIL CA-60',\n 'CN=DOD EMAIL CA-61',\n 'CN=DOD EMAIL CA-62',\n 'CN=DOD EMAIL CA-63',\n 'CN=DOD EMAIL CA-64',\n 'CN=DOD EMAIL CA-65',\n 'CN=DOD EMAIL CA-66',\n ],\n};\n\n/**\n * Create DoD CAC configuration with custom overrides\n * \n * @example\n * ```typescript\n * const config = createDoDCACConfig({\n * source: 'direct_tls', // If terminating TLS in Node.js\n * headerPrefix: 'ssl-client-', // Custom gateway header prefix\n * });\n * ```\n */\nexport function createDoDCACConfig(overrides?: Partial<PKIConfig>): PKIConfig {\n return {\n type: 'pki',\n ...DOD_CAC_PROFILE,\n ...overrides,\n };\n}\n\n/**\n * Minimal DoD CAC config for development/testing\n * Relaxes some requirements for local testing without real CAC cards\n */\nexport function createDoDCACDevConfig(): PKIConfig {\n return {\n type: 'pki',\n profile: 'dod_cac',\n source: 'gateway_headers',\n headerPrefix: 'x-client-cert-',\n verifiedHeader: 'x-client-cert-verified',\n requiredValue: 'SUCCESS',\n // Only require 'DOD' in OU for dev\n requiredOU: ['DOD'],\n // Don't restrict issuers in dev mode\n allowedIssuers: undefined,\n };\n}\n","import React from 'react';\nimport { useAuth } from '../context/AuthContext.js';\nimport type { ComponentAuthConfig } from '../types/index.js';\n\n/**\n * Props that any component wrapped with withAuth will receive\n */\nexport interface ComponentProps {\n id?: string;\n [key: string]: any;\n}\n\n/**\n * Fallback component props\n */\ninterface FallbackProps {\n message?: string;\n className?: string;\n}\n\n/**\n * Default fallback components for unauthorized access\n */\nconst FallbackComponents = {\n /**\n * Hide component (render nothing)\n */\n hide: () => null,\n \n /**\n * Show placeholder message\n */\n placeholder: ({ className }: FallbackProps) => (\n <div className={className || 'auth-placeholder'} style={{\n padding: '1rem',\n border: '1px dashed #ccc',\n borderRadius: '4px',\n color: '#666',\n fontStyle: 'italic',\n textAlign: 'center',\n }}>\n Content requires authorization\n </div>\n ),\n \n /**\n * Show custom message\n */\n message: ({ message, className }: FallbackProps) => (\n <div className={className || 'auth-message'} style={{\n padding: '1rem',\n border: '1px solid #f0ad4e',\n borderRadius: '4px',\n backgroundColor: '#fcf8e3',\n color: '#8a6d3b',\n }}>\n {message || 'Unauthorized'}\n </div>\n ),\n};\n\n/**\n * Higher-order component that wraps a component with authentication checks\n * \n * @example\n * ```tsx\n * const ProtectedButton = withAuth(Button, {\n * required_roles: ['ADMIN'],\n * fallback: 'message',\n * fallback_message: 'Only admins can see this button'\n * });\n * ```\n * \n * @param Component - The component to wrap\n * @param authConfig - Authentication requirements from YAML\n * @returns Wrapped component with auth enforcement\n */\nexport function withAuth<P extends ComponentProps>(\n Component: React.ComponentType<P>,\n authConfig?: ComponentAuthConfig\n): React.ComponentType<P> {\n // If no auth config, return component unchanged\n if (!authConfig) {\n return Component;\n }\n \n // Create wrapped component with display name for debugging\n const WrappedComponent = (props: P) => {\n const auth = useAuth();\n \n // Check role requirements\n if (authConfig.required_roles && authConfig.required_roles.length > 0) {\n if (!auth.hasAnyRole(authConfig.required_roles)) {\n return renderFallback(authConfig);\n }\n }\n \n // Check permission requirements (must have ALL permissions)\n if (authConfig.required_permissions && authConfig.required_permissions.length > 0) {\n if (!auth.hasAllPermissions(authConfig.required_permissions)) {\n return renderFallback(authConfig);\n }\n }\n \n // User authorized - render component\n return <Component {...props} />;\n };\n \n // Set display name for React DevTools\n const componentName = Component.displayName || Component.name || 'Component';\n WrappedComponent.displayName = `withAuth(${componentName})`;\n \n return WrappedComponent;\n}\n\n/**\n * Render fallback component based on configuration\n */\nfunction renderFallback(authConfig: ComponentAuthConfig): React.ReactElement | null {\n const fallbackType = authConfig.fallback || 'hide';\n \n switch (fallbackType) {\n case 'hide':\n return FallbackComponents.hide();\n \n case 'placeholder':\n return FallbackComponents.placeholder({});\n \n case 'message':\n return FallbackComponents.message({\n message: authConfig.fallback_message,\n });\n \n default:\n return null;\n }\n}\n\n/**\n * Custom fallback component (for advanced use cases)\n */\nexport function withAuthFallback<P extends ComponentProps>(\n Component: React.ComponentType<P>,\n authConfig: ComponentAuthConfig,\n FallbackComponent: React.ComponentType<any>\n): React.ComponentType<P> {\n const WrappedComponent = (props: P) => {\n const auth = useAuth();\n \n // Check authorization\n const isAuthorized = checkAuthorization(auth, authConfig);\n \n if (!isAuthorized) {\n return <FallbackComponent />;\n }\n \n return <Component {...props} />;\n };\n \n const componentName = Component.displayName || Component.name || 'Component';\n WrappedComponent.displayName = `withAuthFallback(${componentName})`;\n \n return WrappedComponent;\n}\n\n/**\n * Check if user is authorized based on auth config\n */\nfunction checkAuthorization(auth: ReturnType<typeof useAuth>, authConfig: ComponentAuthConfig): boolean {\n // Check roles\n if (authConfig.required_roles && authConfig.required_roles.length > 0) {\n if (!auth.hasAnyRole(authConfig.required_roles)) {\n return false;\n }\n }\n \n // Check permissions\n if (authConfig.required_permissions && authConfig.required_permissions.length > 0) {\n if (!auth.hasAllPermissions(authConfig.required_permissions)) {\n return false;\n }\n }\n \n return true;\n}\n","import { withAuth } from './decorators/withAuth.js';\nimport type { ComponentAuthConfig } from './types/index.js';\nimport type React from 'react';\n\n/**\n * Global registry for auth decorator function\n * This allows OSS packages to optionally use auth without depending on it\n * \n * Design principle: No hard dependencies!\n * - OSS core never imports from pro packages\n * - Pro package registers itself at runtime\n * - User app is the glue that connects them\n */\nlet authDecoratorRegistry: {\n decorator: typeof withAuth | null;\n} = {\n decorator: null,\n};\n\n/**\n * Register the auth decorator for use by content renderers\n * \n * This should be called once in your app's initialization (e.g., _app.tsx)\n * to enable auth-aware component rendering.\n * \n * @example\n * ```tsx\n * // In pages/_app.tsx\n * import { registerAuthDecorator } from '@stackwright-pro/auth';\n * \n * registerAuthDecorator();\n * \n * function MyApp({ Component, pageProps }: AppProps) {\n * return (\n * <AuthProvider {...authProps}>\n * <Component {...pageProps} />\n * </AuthProvider>\n * );\n * }\n * ```\n */\nexport function registerAuthDecorator(): void {\n authDecoratorRegistry.decorator = withAuth;\n \n // Debug logging (only in browser with debug flag)\n if (typeof window !== 'undefined' && (window as any).__STACKWRIGHT_DEBUG__) {\n console.log('🔐 Auth decorator registered');\n }\n}\n\n/**\n * Get the registered auth decorator (for use by content renderers)\n * \n * Returns null if auth is not registered, allowing graceful degradation.\n * This is the function that OSS core would call to check if auth is available.\n * \n * @returns The withAuth decorator function, or null if not registered\n */\nexport function getAuthDecorator(): typeof withAuth | null {\n return authDecoratorRegistry.decorator;\n}\n\n/**\n * Wrap a component with auth if decorator is registered and config exists\n * \n * This is a safe wrapper that OSS packages can use without depending on auth.\n * If auth is not registered, returns the original component unchanged.\n * If auth config is missing/undefined, returns the original component unchanged.\n * \n * @example\n * ```tsx\n * // In content renderer (can live in OSS core!)\\n * function renderContentItem(item: ContentItem) {\n * const Component = getComponentFromRegistry(item.type);\n * \n * // Apply auth if available\n * const WrappedComponent = maybeWrapWithAuth(Component, item.auth);\n * \n * return <WrappedComponent {...item} />;\n * }\n * ```\n * \n * @param Component - Component to wrap\n * @param authConfig - Auth configuration from YAML (optional)\n * @returns Wrapped component if auth is registered, original component otherwise\n */\nexport function maybeWrapWithAuth<P extends { id?: string; [key: string]: any }>(\n Component: React.ComponentType<P>,\n authConfig?: ComponentAuthConfig\n): React.ComponentType<P> {\n const decorator = getAuthDecorator();\n \n // No decorator registered or no auth config = return unwrapped\n // This ensures graceful degradation when auth isn't installed\n if (!decorator || !authConfig) {\n return Component;\n }\n \n // Wrap with auth\n return decorator(Component, authConfig);\n}\n\n/**\n * Type guard to check if content item has auth config\n * \n * Useful for conditionally applying auth in renderers without\n * needing to import auth types.\n * \n * @example\n * ```tsx\n * if (hasAuthConfig(item)) {\n * // TypeScript knows item.auth exists\n * WrappedComponent = maybeWrapWithAuth(Component, item.auth);\n * }\n * ```\n */\nexport function hasAuthConfig(item: any): item is { auth: ComponentAuthConfig } {\n // Explicitly return boolean to handle null/undefined properly\n if (!item || typeof item !== 'object') {\n return false;\n }\n return 'auth' in item;\n}\n"]}
|