{"version":3,"sources":["../src/lib/validation.ts","../src/lib/path-utils.ts","../src/lib/hosted-auth.ts"],"names":["z"],"mappings":"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","file":"lib.cjs","sourcesContent":["import { z } from 'zod';\r\n\r\n/**\r\n * Email validation schema\r\n */\r\nexport const emailSchema = z.string().min(1, 'Email is required').email('Invalid email address');\r\n\r\n/**\r\n * Password validation schema with configurable requirements\r\n */\r\nexport function createPasswordSchema(options?: {\r\n  minLength?: number;\r\n  requireUppercase?: boolean;\r\n  requireLowercase?: boolean;\r\n  requireNumber?: boolean;\r\n  requireSpecialChar?: boolean;\r\n}) {\r\n  const {\r\n    minLength = 6,\r\n    requireUppercase = false,\r\n    requireLowercase = false,\r\n    requireNumber = false,\r\n    requireSpecialChar = false,\r\n  } = options || {};\r\n\r\n  let schema = z.string().min(minLength, `Password must be at least ${minLength} characters`);\r\n\r\n  if (requireUppercase) {\r\n    schema = schema.regex(/[A-Z]/, 'Password must contain at least one uppercase letter');\r\n  }\r\n\r\n  if (requireLowercase) {\r\n    schema = schema.regex(/[a-z]/, 'Password must contain at least one lowercase letter');\r\n  }\r\n\r\n  if (requireNumber) {\r\n    schema = schema.regex(/\\d/, 'Password must contain at least one number');\r\n  }\r\n\r\n  if (requireSpecialChar) {\r\n    schema = schema.regex(\r\n      /[!@#$%^&*()_+\\-=[\\]{};':\"\\\\|,.<>/?]/,\r\n      'Password must contain at least one special character'\r\n    );\r\n  }\r\n\r\n  return schema;\r\n}\r\n\r\n/**\r\n * Default password schema (minimum 6 characters)\r\n */\r\nexport const passwordSchema = createPasswordSchema();\r\n\r\n/**\r\n * Validate email format\r\n */\r\nexport function validateEmail(email: string): { valid: boolean; error?: string } {\r\n  const result = emailSchema.safeParse(email);\r\n  if (result.success) {\r\n    return { valid: true };\r\n  }\r\n  return { valid: false, error: result.error.message };\r\n}\r\n\r\n/**\r\n * Validate password format\r\n */\r\nexport function validatePassword(\r\n  password: string,\r\n  options?: Parameters<typeof createPasswordSchema>[0]\r\n): { valid: boolean; error?: string } {\r\n  const schema = createPasswordSchema(options);\r\n  const result = schema.safeParse(password);\r\n  if (result.success) {\r\n    return { valid: true };\r\n  }\r\n  return { valid: false, error: result.error.message };\r\n}\r\n\r\n/**\r\n * Validate password strength based on multiple criteria\r\n */\r\nexport function checkPasswordStrength(password: string): {\r\n  score: number;\r\n  feedback: string[];\r\n} {\r\n  const feedback: string[] = [];\r\n  let score = 0;\r\n\r\n  if (password.length >= 8) {\r\n    score += 1;\r\n  } else {\r\n    feedback.push('Use at least 8 characters');\r\n  }\r\n\r\n  if (password.length >= 12) {\r\n    score += 1;\r\n  }\r\n\r\n  if (/[a-z]/.test(password) && /[A-Z]/.test(password)) {\r\n    score += 1;\r\n  } else {\r\n    feedback.push('Use both uppercase and lowercase letters');\r\n  }\r\n\r\n  if (/\\d/.test(password)) {\r\n    score += 1;\r\n  } else {\r\n    feedback.push('Include at least one number');\r\n  }\r\n\r\n  if (/[!@#$%^&*()_+\\-=[\\]{};':\"\\\\|,.<>/?]/.test(password)) {\r\n    score += 1;\r\n  } else {\r\n    feedback.push('Include at least one special character');\r\n  }\r\n\r\n  return { score, feedback };\r\n}\r\n","/**\r\n * Path utilities for handling navigation in auth flows.\r\n * Ensures proper path resolution when auth pages are served under a base path (e.g., /auth/)\r\n */\r\n\r\n/**\r\n * Resolves an auth route path relative to the current location.\r\n * If the current path is under /auth/, it will preserve that prefix.\r\n * Otherwise, it returns the path as-is.\r\n *\r\n * @param targetPath - The target auth path (e.g., '/sign-in', '/sign-up')\r\n * @returns The resolved path with proper base path handling\r\n *\r\n * @example\r\n * // Current URL: http://localhost:5174/auth/sign-in\r\n * resolveAuthPath('/sign-up') // Returns '/auth/sign-up'\r\n *\r\n * @example\r\n * // Current URL: http://localhost:5174/sign-in\r\n * resolveAuthPath('/sign-up') // Returns '/sign-up'\r\n */\r\nexport function resolveAuthPath(targetPath: string): string {\r\n  if (typeof window === 'undefined') {\r\n    return targetPath;\r\n  }\r\n\r\n  const currentPath = window.location.pathname;\r\n\r\n  // Check if we're currently under /auth/ base path\r\n  if (currentPath.startsWith('/auth/')) {\r\n    // If target already has /auth/ prefix, return as-is\r\n    if (targetPath.startsWith('/auth/')) {\r\n      return targetPath;\r\n    }\r\n    // Add /auth/ prefix to the target path\r\n    return `/auth${targetPath}`;\r\n  }\r\n\r\n  // Not under /auth/, return target path as-is\r\n  return targetPath;\r\n}\r\n\r\n/**\r\n * Resolves an auth route URL with search params preserved.\r\n * Similar to resolveAuthPath but returns a full URL string with query parameters.\r\n *\r\n * @param targetPath - The target auth path (e.g., '/sign-in', '/sign-up')\r\n * @param searchParams - Optional URLSearchParams to append\r\n * @returns The resolved URL as a string\r\n *\r\n * @example\r\n * // Current URL: http://localhost:5174/auth/sign-in?redirect=...\r\n * resolveAuthUrl('/sign-up', searchParams) // Returns '/auth/sign-up?redirect=...'\r\n */\r\nexport function resolveAuthUrl(targetPath: string, searchParams?: URLSearchParams): string {\r\n  const resolvedPath = resolveAuthPath(targetPath);\r\n\r\n  if (!searchParams || searchParams.toString() === '') {\r\n    return resolvedPath;\r\n  }\r\n\r\n  return `${resolvedPath}?${searchParams.toString()}`;\r\n}\r\n","/**\r\n * Hosted Auth Helpers\r\n *\r\n * Utilities for detecting hosted auth environment and building legacy auth URLs\r\n * for cross-domain authentication flows.\r\n */\r\n\r\n/**\r\n * Get CSRF token from cookie\r\n *\r\n * Reads the insforge_csrf_token cookie set by the backend after authentication.\r\n * This is needed for OAuth flows where the csrfToken is stored in cookies\r\n * rather than returned in the API response.\r\n *\r\n * @returns The CSRF token value or null if not found\r\n */\r\nexport function getCsrfTokenFromCookie(): string | null {\r\n  if (typeof document === 'undefined') return null;\r\n  const match = document.cookie.match(/(?:^|;\\s*)insforge_csrf_token=([^;]*)/);\r\n  return match ? decodeURIComponent(match[1]) : null;\r\n}\r\n\r\n/**\r\n * Check if current environment is a hosted auth environment\r\n *\r\n * Returns true for:\r\n * - localhost with port 7130 (hosted auth app dev)\r\n * - https://*.insforge.app (hosted auth app production)\r\n *\r\n * @returns true if running in hosted auth environment\r\n */\r\nexport function isHostedAuthEnvironment(): boolean {\r\n  if (typeof window === 'undefined') {\r\n    return false;\r\n  }\r\n\r\n  const { hostname, port, protocol } = window.location;\r\n\r\n  // Local development\r\n  if (hostname === 'localhost' && port === '7130') {\r\n    return true;\r\n  }\r\n\r\n  // Production hosted auth\r\n  if (protocol === 'https:' && hostname.endsWith('.insforge.app')) {\r\n    return true;\r\n  }\r\n\r\n  return false;\r\n}\r\n\r\n/**\r\n * Session data for building legacy auth URL\r\n */\r\nexport interface LegacyAuthSession {\r\n  accessToken: string;\r\n  userId: string;\r\n  email: string;\r\n  name?: string;\r\n  csrfToken?: string;\r\n}\r\n\r\n/**\r\n * Build a legacy flow redirect URL with auth params in query string\r\n *\r\n * This is used to pass authentication credentials back to the user's app\r\n * after OAuth completes in the hosted auth environment.\r\n *\r\n * @param redirectUrl - The URL to redirect to (user's app)\r\n * @param session - The session data to include in the URL\r\n * @returns The complete URL with auth params\r\n */\r\nexport function buildLegacyAuthUrl(redirectUrl: string, session: LegacyAuthSession): string {\r\n  const url = new URL(redirectUrl);\r\n  url.searchParams.set('access_token', session.accessToken);\r\n  url.searchParams.set('user_id', session.userId);\r\n  url.searchParams.set('email', session.email);\r\n\r\n  if (session.name) {\r\n    url.searchParams.set('name', session.name);\r\n  }\r\n\r\n  if (session.csrfToken) {\r\n    url.searchParams.set('csrf_token', session.csrfToken);\r\n  }\r\n\r\n  return url.toString();\r\n}\r\n"]}