@insforge/react 0.4.0 → 0.4.5

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/dist/index.cjs CHANGED
@@ -5,7 +5,7 @@ if (typeof document !== 'undefined' && typeof window !== 'undefined') {
5
5
  if (!document.getElementById(styleId)) {
6
6
  const style = document.createElement('style');
7
7
  style.id = styleId;
8
- style.textContent = "/**\n * InsForge React Component Library Styles\n * Traditional CSS with scoped class names (no Tailwind)\n */\n\n/* ============================================\n FONTS\n ============================================ */\n@import url('https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap');\n@import url('https://fonts.googleapis.com/css2?family=Manrope:wght@200..800&display=swap');\n\n/* ============================================\n CSS VARIABLES\n ============================================ */\n:root {\n /* Colors */\n --if-color-primary: #000000;\n --if-color-primary-hover: #1f1f1f;\n --if-color-text: #000000;\n --if-color-text-secondary: #828282;\n --if-color-text-muted: #a3a3a3;\n --if-color-border: #d4d4d4;\n --if-color-border-focus: #000000;\n --if-color-bg-white: #ffffff;\n --if-color-bg-light: #fafafa;\n --if-color-bg-hover: #f9fafb;\n --if-color-error: #dc2626;\n --if-color-error-bg: #fee2e2;\n --if-color-success: #16a34a;\n\n /* Spacing */\n --if-space-1: 0.25rem; /* 4px */\n --if-space-2: 0.5rem; /* 8px */\n --if-space-3: 0.75rem; /* 12px */\n --if-space-4: 1rem; /* 16px */\n --if-space-6: 1.5rem; /* 24px */\n --if-space-8: 2rem; /* 32px */\n\n /* Border Radius */\n --if-radius-xs: 0.125rem; /* 2px */\n --if-radius-sm: 0.25rem; /* 4px */\n --if-radius-md: 0.375rem; /* 6px */\n --if-radius-lg: 0.5rem; /* 8px */\n --if-radius-xl: 0.75rem; /* 12px */\n\n /* Typography */\n --if-font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;\n --if-font-family-manrope:\n 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;\n --if-font-size-xs: 0.75rem; /* 12px */\n --if-font-size-sm: 0.875rem; /* 14px */\n --if-font-size-base: 1rem; /* 16px */\n --if-font-size-lg: 1.125rem; /* 18px */\n --if-font-size-xl: 1.25rem; /* 20px */\n --if-font-size-2xl: 1.5rem; /* 24px */\n\n /* Shadows */\n --if-shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);\n --if-shadow-md: 0 1px 2px 0 rgba(0, 0, 0, 0.1);\n --if-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);\n\n /* Transitions */\n --if-transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1);\n --if-transition-base: 200ms cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n/* ============================================\n AUTH CONTAINER\n ============================================ */\n.if-authContainer {\n width: 100%;\n max-width: 400px;\n border-radius: var(--if-radius-xl);\n overflow: hidden;\n box-shadow: var(--if-shadow-lg);\n}\n\n.if-authCard {\n background-color: var(--if-color-bg-white);\n padding: var(--if-space-6);\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: stretch;\n gap: var(--if-space-6);\n}\n\n/* ============================================\n AUTH HEADER\n ============================================ */\n.if-authHeader {\n display: flex;\n flex-direction: column;\n justify-content: flex-start;\n align-items: flex-start;\n gap: var(--if-space-2);\n}\n\n.if-authHeader-title {\n font-size: var(--if-font-size-2xl);\n font-weight: 600;\n color: var(--if-color-text);\n line-height: 2rem;\n margin: 0;\n font-family: var(--if-font-family);\n}\n\n.if-authHeader-subtitle {\n font-size: var(--if-font-size-sm);\n font-weight: 400;\n color: var(--if-color-text-secondary);\n line-height: 1.5rem;\n margin: 0;\n font-family: var(--if-font-family);\n}\n\n/* ============================================\n FORM FIELD\n ============================================ */\n.if-formField {\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: stretch;\n gap: var(--if-space-1);\n}\n\n.if-formField-label {\n font-size: var(--if-font-size-sm);\n font-weight: 400;\n color: var(--if-color-text);\n line-height: 1.5rem;\n font-family: var(--if-font-family);\n}\n\n.if-formField-input {\n width: 100%;\n display: flex;\n align-items: center;\n gap: var(--if-space-2);\n align-self: stretch;\n padding: var(--if-space-2) var(--if-space-3);\n border-radius: var(--if-radius-sm);\n border: 1px solid var(--if-color-border);\n background-color: var(--if-color-bg-white);\n font-size: var(--if-font-size-sm);\n font-weight: 400;\n line-height: 1.25rem;\n color: var(--if-color-text);\n font-family: var(--if-font-family);\n transition: border-color var(--if-transition-base);\n}\n\n.if-formField-input::placeholder {\n color: var(--if-color-text-muted);\n font-size: var(--if-font-size-sm);\n font-weight: 400;\n}\n\n.if-formField-input:focus {\n outline: none;\n border-color: var(--if-color-border-focus);\n}\n\n/* ============================================\n PASSWORD FIELD\n ============================================ */\n.if-passwordField {\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: stretch;\n gap: var(--if-space-1);\n}\n\n.if-passwordField-labelRow {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.if-passwordField-label {\n font-size: var(--if-font-size-sm);\n font-weight: 400;\n color: var(--if-color-text);\n line-height: 1.5rem;\n font-family: var(--if-font-family);\n}\n\n.if-passwordField-forgotLink {\n font-size: var(--if-font-size-sm);\n font-weight: 400;\n color: var(--if-color-text-secondary);\n text-decoration: none;\n transition: color var(--if-transition-fast);\n font-family: var(--if-font-family);\n}\n\n.if-passwordField-inputWrapper {\n position: relative;\n width: 100%;\n}\n\n.if-passwordField-input {\n width: 100%;\n display: flex;\n align-items: center;\n align-self: stretch;\n padding: var(--if-space-2) var(--if-space-3);\n padding-right: 2.5rem; /* Space for toggle button */\n border-radius: var(--if-radius-sm);\n border: 1px solid var(--if-color-border);\n background-color: var(--if-color-bg-white);\n font-size: var(--if-font-size-sm);\n font-weight: 400;\n line-height: 1.25rem;\n color: var(--if-color-text);\n font-family: var(--if-font-family);\n transition: border-color var(--if-transition-base);\n}\n\n.if-passwordField-input::placeholder {\n color: var(--if-color-text-muted);\n}\n\n.if-passwordField-input:focus {\n outline: none;\n border-color: var(--if-color-border-focus);\n}\n\n.if-passwordField-toggleButton {\n position: absolute;\n right: var(--if-space-1);\n top: 50%;\n transform: translateY(-50%);\n background: none;\n border: none;\n cursor: pointer;\n padding: var(--if-space-1);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--if-color-text-secondary);\n transition: color var(--if-transition-fast);\n}\n\n/* ============================================\n SUBMIT BUTTON\n ============================================ */\n.if-submitButton {\n border-radius: var(--if-radius-sm);\n background-color: var(--if-color-primary);\n height: 2.5rem;\n width: 100%;\n display: flex;\n margin-top: var(--if-space-4);\n padding: var(--if-space-2) var(--if-space-4);\n justify-content: center;\n align-items: center;\n gap: 0.625rem;\n align-self: stretch;\n color: var(--if-color-bg-white);\n font-weight: 600;\n font-family: var(--if-font-family-manrope);\n font-size: var(--if-font-size-base);\n line-height: normal;\n border: none;\n cursor: pointer;\n transition: background-color var(--if-transition-base);\n}\n\n.if-submitButton:hover:not(:disabled) {\n background-color: var(--if-color-primary-hover);\n}\n\n.if-submitButton:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.if-submitButton-icon {\n width: 1.25rem;\n height: 1.25rem;\n}\n\n/* Spinner animation */\n@keyframes if-spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n\n.if-submitButton-spinner {\n animation: if-spin 1s linear infinite;\n}\n\n/* ============================================\n OAUTH BUTTON\n ============================================ */\n.if-oauthButton {\n display: flex;\n width: 100%;\n height: 2.25rem;\n padding: var(--if-space-2) var(--if-space-3);\n flex-direction: row;\n justify-content: center;\n align-items: center;\n gap: var(--if-space-3);\n border-radius: var(--if-radius-md);\n border: 1px solid #e4e4e7;\n background-color: var(--if-color-bg-white);\n box-shadow: var(--if-shadow-md);\n color: #09090b;\n text-align: center;\n font-size: var(--if-font-size-sm);\n font-weight: 500;\n line-height: 1.25rem;\n cursor: pointer;\n transition: all var(--if-transition-base);\n font-family: var(--if-font-family);\n}\n\n.if-oauthButton:hover:not(:disabled) {\n background-color: var(--if-color-bg-hover);\n border-color: #9ca3af;\n}\n\n.if-oauthButton:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.if-oauthButton-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: 1.125rem;\n height: 1.125rem;\n}\n\n.if-oauthButton-full {\n justify-content: center;\n}\n\n.if-oauthButton-short {\n justify-content: center;\n padding: var(--if-space-2);\n gap: var(--if-space-2);\n}\n\n.if-oauthButton-icon-only {\n justify-content: center;\n gap: 0;\n}\n\n/* ============================================\n OAUTH PROVIDERS CONTAINER\n ============================================ */\n.if-oauthProviders {\n display: flex;\n flex-direction: column;\n gap: var(--if-space-3);\n width: 100%;\n}\n\n/* ============================================\n AUTH LINK\n ============================================ */\n.if-authLink {\n display: flex;\n justify-content: center;\n align-items: center;\n gap: var(--if-space-1);\n font-size: var(--if-font-size-sm);\n color: var(--if-color-text-secondary);\n font-family: var(--if-font-family);\n}\n\n.if-authLink-text {\n font-weight: 400;\n}\n\n.if-authLink-link {\n font-weight: 600;\n color: var(--if-color-text);\n text-decoration: none;\n transition: opacity var(--if-transition-fast);\n}\n\n/* ============================================\n AUTH DIVIDER\n ============================================ */\n.if-authDivider {\n display: flex;\n align-items: center;\n text-align: center;\n width: 100%;\n gap: var(--if-space-3);\n}\n\n.if-authDivider-line {\n flex: 1;\n border-top: 1px solid var(--if-color-border);\n}\n\n.if-authDivider-text {\n font-size: var(--if-font-size-sm);\n color: var(--if-color-text-secondary);\n font-weight: 400;\n font-family: var(--if-font-family-manrope);\n}\n\n/* ============================================\n ERROR BANNER\n ============================================ */\n.if-errorBanner {\n padding: var(--if-space-3);\n background-color: var(--if-color-error-bg);\n border-radius: var(--if-radius-md);\n border: 1px solid var(--if-color-error);\n}\n\n.if-errorBanner-text {\n font-size: var(--if-font-size-sm);\n color: var(--if-color-error);\n font-weight: 400;\n font-family: var(--if-font-family);\n margin: 0;\n}\n\n/* ============================================\n AUTH BRANDING\n ============================================ */\n.if-authBranding {\n background-color: var(--if-color-bg-light);\n padding: var(--if-space-4) var(--if-space-2);\n display: flex;\n flex-direction: row;\n justify-content: center;\n align-items: center;\n gap: var(--if-space-1);\n}\n\n.if-authBranding-text {\n font-size: var(--if-font-size-xs);\n font-weight: 500;\n color: var(--if-color-text);\n font-family: var(--if-font-family-manrope);\n margin: 0;\n}\n\n/* ============================================\n VERIFICATION CODE INPUT\n ============================================ */\n.if-verificationCode {\n display: flex;\n flex-direction: column;\n gap: var(--if-space-4);\n}\n\n.if-verificationCode-description {\n font-size: var(--if-font-size-sm);\n color: var(--if-color-text-secondary);\n text-align: center;\n font-family: var(--if-font-family);\n}\n\n.if-verificationCode-email {\n font-weight: 600;\n color: var(--if-color-text);\n}\n\n.if-verificationCode-inputContainer {\n display: flex;\n gap: var(--if-space-2);\n justify-content: center;\n}\n\n.if-verificationCode-input {\n width: 3rem;\n height: 3rem;\n text-align: center;\n font-size: var(--if-font-size-xl);\n font-weight: 600;\n border: 2px solid var(--if-color-border);\n border-radius: var(--if-radius-md);\n transition: border-color var(--if-transition-base);\n font-family: var(--if-font-family);\n}\n\n.if-verificationCode-input:focus {\n outline: none;\n border-color: var(--if-color-border-focus);\n}\n\n/* ============================================\n PASSWORD STRENGTH INDICATOR\n ============================================ */\n.if-passwordStrength {\n margin-top: var(--if-space-2);\n}\n\n.if-passwordStrength-bar {\n height: 4px;\n background-color: #e5e7eb;\n border-radius: 2px;\n overflow: hidden;\n margin-bottom: var(--if-space-2);\n}\n\n.if-passwordStrength-fill {\n height: 100%;\n transition:\n width var(--if-transition-base),\n background-color var(--if-transition-base);\n}\n\n.if-passwordStrength-fill.weak {\n background-color: #ef4444;\n width: 33%;\n}\n\n.if-passwordStrength-fill.medium {\n background-color: #f59e0b;\n width: 66%;\n}\n\n.if-passwordStrength-fill.strong {\n background-color: var(--if-color-success);\n width: 100%;\n}\n\n.if-passwordStrength-text {\n font-size: var(--if-font-size-xs);\n color: var(--if-color-text-secondary);\n font-family: var(--if-font-family);\n}\n\n.if-passwordStrength-requirements {\n margin-top: var(--if-space-2);\n font-size: var(--if-font-size-xs);\n color: var(--if-color-text-secondary);\n font-family: var(--if-font-family);\n}\n\n.if-passwordStrength-requirement {\n display: flex;\n align-items: center;\n gap: var(--if-space-1);\n margin-bottom: var(--if-space-1);\n}\n\n.if-passwordStrength-requirement.met {\n color: var(--if-color-success);\n}\n\n.if-passwordStrength-requirement.unmet {\n color: var(--if-color-text-muted);\n}\n\n/* ============================================\n FORM CONTAINER\n ============================================ */\n.if-form {\n display: flex;\n flex-direction: column;\n align-items: stretch;\n justify-content: center;\n gap: var(--if-space-6);\n}\n\n/* ============================================\n USER BUTTON\n ============================================ */\n.if-userButton {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: var(--if-space-2);\n border-radius: 9999px;\n background-color: var(--if-color-bg-white);\n border: 1px solid var(--if-color-border);\n cursor: pointer;\n transition: all var(--if-transition-base);\n}\n\n.if-userButton:hover {\n background-color: var(--if-color-bg-light);\n}\n\n.if-userButton-avatar {\n width: 2rem;\n height: 2rem;\n border-radius: 9999px;\n background-color: var(--if-color-primary);\n color: var(--if-color-bg-white);\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: 600;\n font-size: var(--if-font-size-sm);\n font-family: var(--if-font-family);\n}\n\n.if-userButton-menu {\n position: absolute;\n margin-top: var(--if-space-2);\n background-color: var(--if-color-bg-white);\n border: 1px solid var(--if-color-border);\n border-radius: var(--if-radius-md);\n box-shadow: var(--if-shadow-lg);\n padding: var(--if-space-2);\n min-width: 200px;\n z-index: 50;\n}\n\n.if-userButton-menuItem {\n display: flex;\n align-items: center;\n gap: var(--if-space-2);\n padding: var(--if-space-2);\n border-radius: var(--if-radius-sm);\n cursor: pointer;\n transition: background-color var(--if-transition-fast);\n font-size: var(--if-font-size-sm);\n color: var(--if-color-text);\n font-family: var(--if-font-family);\n}\n\n.if-userButton-menuItem:hover {\n background-color: var(--if-color-bg-light);\n}\n\n/* ============================================\n UTILITY CLASSES\n ============================================ */\n.if-hidden {\n display: none;\n}\n\n.if-visuallyHidden {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border-width: 0;\n}\n";
8
+ style.textContent = "/**\n * InsForge React Component Library Styles\n * Traditional CSS with scoped class names (no Tailwind)\n */\n\n/* ============================================\n FONTS\n ============================================ */\n@import url('https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap');\n@import url('https://fonts.googleapis.com/css2?family=Manrope:wght@200..800&display=swap');\n\n/* ============================================\n CSS VARIABLES\n ============================================ */\n:root {\n /* Colors */\n --if-color-primary: #000000;\n --if-color-primary-hover: #1f1f1f;\n --if-color-text: #000000;\n --if-color-text-secondary: #828282;\n --if-color-text-muted: #a3a3a3;\n --if-color-border: #d4d4d4;\n --if-color-border-focus: #000000;\n --if-color-bg-white: #ffffff;\n --if-color-bg-light: #fafafa;\n --if-color-bg-hover: #f9fafb;\n --if-color-error: #dc2626;\n --if-color-error-bg: #fee2e2;\n --if-color-success: #16a34a;\n\n /* Spacing */\n --if-space-1: 0.25rem; /* 4px */\n --if-space-2: 0.5rem; /* 8px */\n --if-space-3: 0.75rem; /* 12px */\n --if-space-4: 1rem; /* 16px */\n --if-space-6: 1.5rem; /* 24px */\n --if-space-8: 2rem; /* 32px */\n\n /* Border Radius */\n --if-radius-xs: 0.125rem; /* 2px */\n --if-radius-sm: 0.25rem; /* 4px */\n --if-radius-md: 0.375rem; /* 6px */\n --if-radius-lg: 0.5rem; /* 8px */\n --if-radius-xl: 0.75rem; /* 12px */\n\n /* Typography */\n --if-font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;\n --if-font-family-manrope:\n 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;\n --if-font-size-xs: 0.75rem; /* 12px */\n --if-font-size-sm: 0.875rem; /* 14px */\n --if-font-size-base: 1rem; /* 16px */\n --if-font-size-lg: 1.125rem; /* 18px */\n --if-font-size-xl: 1.25rem; /* 20px */\n --if-font-size-2xl: 1.5rem; /* 24px */\n\n /* Shadows */\n --if-shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);\n --if-shadow-md: 0 1px 2px 0 rgba(0, 0, 0, 0.1);\n --if-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);\n\n /* Transitions */\n --if-transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1);\n --if-transition-base: 200ms cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n/* ============================================\n AUTH CONTAINER\n ============================================ */\n.if-authContainer {\n width: 100%;\n max-width: 400px;\n border-radius: var(--if-radius-xl);\n overflow: hidden;\n box-shadow: var(--if-shadow-lg);\n}\n\n.if-authCard {\n background-color: var(--if-color-bg-white);\n padding: var(--if-space-6);\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: stretch;\n gap: var(--if-space-6);\n}\n\n/* ============================================\n AUTH HEADER\n ============================================ */\n.if-authHeader {\n display: flex;\n flex-direction: column;\n justify-content: flex-start;\n align-items: flex-start;\n gap: var(--if-space-2);\n}\n\n.if-authHeader-title {\n font-size: var(--if-font-size-2xl);\n font-weight: 600;\n color: var(--if-color-text);\n line-height: 2rem;\n margin: 0;\n font-family: var(--if-font-family);\n}\n\n.if-authHeader-subtitle {\n font-size: var(--if-font-size-sm);\n font-weight: 400;\n color: var(--if-color-text-secondary);\n line-height: 1.5rem;\n margin: 0;\n font-family: var(--if-font-family);\n}\n\n/* ============================================\n FORM FIELD\n ============================================ */\n.if-formField {\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: stretch;\n gap: var(--if-space-1);\n}\n\n.if-formField-label {\n font-size: var(--if-font-size-sm);\n font-weight: 400;\n color: var(--if-color-text);\n line-height: 1.5rem;\n font-family: var(--if-font-family);\n}\n\n.if-formField-input {\n width: 100%;\n display: flex;\n align-items: center;\n gap: var(--if-space-2);\n align-self: stretch;\n padding: var(--if-space-2) var(--if-space-3);\n border-radius: var(--if-radius-sm);\n border: 1px solid var(--if-color-border);\n background-color: var(--if-color-bg-white);\n font-size: var(--if-font-size-sm);\n font-weight: 400;\n line-height: 1.25rem;\n color: var(--if-color-text);\n font-family: var(--if-font-family);\n transition: border-color var(--if-transition-base);\n}\n\n.if-formField-input::placeholder {\n color: var(--if-color-text-muted);\n font-size: var(--if-font-size-sm);\n font-weight: 400;\n}\n\n.if-formField-input:focus {\n outline: none;\n border-color: var(--if-color-border-focus);\n}\n\n/* ============================================\n PASSWORD FIELD\n ============================================ */\n.if-passwordField {\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: stretch;\n gap: var(--if-space-1);\n}\n\n.if-passwordField-labelRow {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.if-passwordField-label {\n font-size: var(--if-font-size-sm);\n font-weight: 400;\n color: var(--if-color-text);\n line-height: 1.5rem;\n font-family: var(--if-font-family);\n}\n\n.if-passwordField-forgotLink {\n font-size: var(--if-font-size-sm);\n font-weight: 400;\n color: var(--if-color-text-secondary);\n text-decoration: none;\n transition: color var(--if-transition-fast);\n font-family: var(--if-font-family);\n}\n\n.if-passwordField-inputWrapper {\n position: relative;\n width: 100%;\n}\n\n.if-passwordField-input {\n width: 100%;\n display: flex;\n align-items: center;\n align-self: stretch;\n padding: var(--if-space-2) var(--if-space-3);\n padding-right: 2.5rem; /* Space for toggle button */\n border-radius: var(--if-radius-sm);\n border: 1px solid var(--if-color-border);\n background-color: var(--if-color-bg-white);\n font-size: var(--if-font-size-sm);\n font-weight: 400;\n line-height: 1.25rem;\n color: var(--if-color-text);\n font-family: var(--if-font-family);\n transition: border-color var(--if-transition-base);\n}\n\n.if-passwordField-input::placeholder {\n color: var(--if-color-text-muted);\n}\n\n.if-passwordField-input:focus {\n outline: none;\n border-color: var(--if-color-border-focus);\n}\n\n.if-passwordField-toggleButton {\n position: absolute;\n right: var(--if-space-1);\n top: 50%;\n transform: translateY(-50%);\n background: none;\n border: none;\n cursor: pointer;\n padding: var(--if-space-1);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--if-color-text-secondary);\n transition: color var(--if-transition-fast);\n}\n\n/* ============================================\n SUBMIT BUTTON\n ============================================ */\n.if-submitButton {\n border-radius: var(--if-radius-sm);\n background-color: var(--if-color-primary);\n height: 2.5rem;\n width: 100%;\n display: flex;\n margin-top: var(--if-space-4);\n padding: var(--if-space-2) var(--if-space-4);\n justify-content: center;\n align-items: center;\n gap: 0.625rem;\n align-self: stretch;\n color: var(--if-color-bg-white);\n font-weight: 600;\n font-family: var(--if-font-family-manrope);\n font-size: var(--if-font-size-base);\n line-height: normal;\n border: none;\n cursor: pointer;\n transition: background-color var(--if-transition-base);\n}\n\n.if-submitButton:hover:not(:disabled) {\n background-color: var(--if-color-primary-hover);\n}\n\n.if-submitButton:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.if-submitButton-icon {\n width: 1.25rem;\n height: 1.25rem;\n}\n\n/* Spinner animation */\n@keyframes if-spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n\n.if-submitButton-spinner {\n animation: if-spin 1s linear infinite;\n}\n\n/* ============================================\n OAUTH BUTTON\n ============================================ */\n.if-oauthButton {\n display: flex;\n width: 100%;\n height: 2.25rem;\n padding: var(--if-space-2) var(--if-space-3);\n flex-direction: row;\n justify-content: center;\n align-items: center;\n gap: var(--if-space-3);\n border-radius: var(--if-radius-md);\n border: 1px solid #e4e4e7;\n background-color: var(--if-color-bg-white);\n box-shadow: var(--if-shadow-md);\n color: #09090b;\n text-align: center;\n font-size: var(--if-font-size-sm);\n font-weight: 500;\n line-height: 1.25rem;\n cursor: pointer;\n transition: all var(--if-transition-base);\n font-family: var(--if-font-family);\n}\n\n.if-oauthButton:hover:not(:disabled) {\n background-color: var(--if-color-bg-hover);\n border-color: #9ca3af;\n}\n\n.if-oauthButton:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.if-oauthButton-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: 1.125rem;\n height: 1.125rem;\n}\n\n.if-oauthButton-full {\n justify-content: center;\n}\n\n.if-oauthButton-short {\n justify-content: center;\n padding: var(--if-space-2);\n gap: var(--if-space-2);\n}\n\n.if-oauthButton-icon-only {\n justify-content: center;\n gap: 0;\n}\n\n/* ============================================\n OAUTH PROVIDERS CONTAINER\n ============================================ */\n.if-oauthProviders {\n display: flex;\n flex-direction: column;\n gap: var(--if-space-3);\n width: 100%;\n}\n\n/* ============================================\n AUTH LINK\n ============================================ */\n.if-authLink {\n display: flex;\n justify-content: center;\n align-items: center;\n gap: var(--if-space-1);\n font-size: var(--if-font-size-sm);\n color: var(--if-color-text-secondary);\n font-family: var(--if-font-family);\n}\n\n.if-authLink-text {\n font-weight: 400;\n}\n\n.if-authLink-link {\n font-weight: 600;\n color: var(--if-color-text);\n text-decoration: none;\n transition: opacity var(--if-transition-fast);\n}\n\n/* ============================================\n AUTH DIVIDER\n ============================================ */\n.if-authDivider {\n display: flex;\n align-items: center;\n text-align: center;\n width: 100%;\n gap: var(--if-space-3);\n}\n\n.if-authDivider-line {\n flex: 1;\n border-top: 1px solid var(--if-color-border);\n}\n\n.if-authDivider-text {\n font-size: var(--if-font-size-sm);\n color: var(--if-color-text-secondary);\n font-weight: 400;\n font-family: var(--if-font-family-manrope);\n}\n\n/* ============================================\n ERROR BANNER\n ============================================ */\n.if-errorBanner {\n padding: var(--if-space-3);\n background-color: var(--if-color-error-bg);\n border-radius: var(--if-radius-md);\n border: 1px solid var(--if-color-error);\n}\n\n.if-errorBanner-content {\n display: flex;\n align-items: center;\n gap: var(--if-space-2);\n}\n\n.if-errorBanner-icon {\n width: 1.5rem;\n height: 1.5rem;\n flex-shrink: 0;\n color: var(--if-color-error);\n}\n\n.if-errorBanner-text {\n font-size: var(--if-font-size-sm);\n color: var(--if-color-error);\n font-weight: 400;\n font-family: var(--if-font-family);\n margin: 0;\n}\n\n/* ============================================\n AUTH BRANDING\n ============================================ */\n.if-authBranding {\n background-color: var(--if-color-bg-light);\n padding: var(--if-space-4) var(--if-space-2);\n display: flex;\n flex-direction: row;\n justify-content: center;\n align-items: center;\n gap: var(--if-space-1);\n}\n\n.if-authBranding-text {\n font-size: var(--if-font-size-xs);\n font-weight: 500;\n color: var(--if-color-text);\n font-family: var(--if-font-family-manrope);\n margin: 0;\n}\n\n/* ============================================\n VERIFICATION CODE INPUT\n ============================================ */\n.if-verificationCode {\n display: flex;\n flex-direction: column;\n gap: var(--if-space-4);\n}\n\n.if-verificationCode-description {\n font-size: var(--if-font-size-sm);\n color: var(--if-color-text-secondary);\n text-align: center;\n font-family: var(--if-font-family);\n}\n\n.if-verificationCode-email {\n font-weight: 600;\n color: var(--if-color-text);\n}\n\n.if-verificationCode-inputContainer {\n display: flex;\n gap: var(--if-space-2);\n justify-content: center;\n}\n\n.if-verificationCode-input {\n width: 3rem;\n height: 3rem;\n text-align: center;\n font-size: var(--if-font-size-xl);\n font-weight: 600;\n border: 2px solid var(--if-color-border);\n border-radius: var(--if-radius-md);\n transition: border-color var(--if-transition-base);\n font-family: var(--if-font-family);\n}\n\n.if-verificationCode-input:focus {\n outline: none;\n border-color: var(--if-color-border-focus);\n}\n\n/* ============================================\n VERIFICATION STEP\n ============================================ */\n.if-verificationStep {\n display: flex;\n flex-direction: column;\n gap: var(--if-space-6);\n align-items: stretch;\n}\n\n.if-verificationStep-description {\n font-size: var(--if-font-size-sm);\n color: var(--if-color-text-secondary);\n text-align: center;\n margin: 0;\n font-family: var(--if-font-family);\n}\n\n.if-verificationStep-codeContainer {\n width: 100%;\n background-color: #f5f5f5;\n border-radius: var(--if-radius-lg);\n padding: var(--if-space-4) var(--if-space-4) var(--if-space-6);\n display: flex;\n flex-direction: column;\n gap: var(--if-space-4);\n}\n\n.if-verificationStep-codeInputWrapper {\n display: flex;\n flex-direction: column;\n gap: var(--if-space-3);\n margin-top: var(--if-space-2);\n}\n\n.if-verificationStep-verifyingText {\n font-size: var(--if-font-size-sm);\n color: var(--if-color-text-secondary);\n text-align: center;\n font-family: var(--if-font-family);\n}\n\n.if-verificationStep-resendContainer {\n width: 100%;\n font-size: var(--if-font-size-sm);\n text-align: center;\n color: var(--if-color-text-secondary);\n font-family: var(--if-font-family);\n}\n\n.if-verificationStep-resendButton {\n color: var(--if-color-text);\n font-weight: 500;\n transition: all var(--if-transition-base);\n background: none;\n border: none;\n padding: 0;\n font-family: var(--if-font-family);\n font-size: var(--if-font-size-sm);\n}\n\n.if-verificationStep-resendButton:not(:disabled) {\n cursor: pointer;\n text-decoration: underline;\n}\n\n.if-verificationStep-resendButton:disabled {\n cursor: not-allowed;\n text-decoration: none;\n opacity: 0.5;\n}\n\n/* ============================================\n PASSWORD STRENGTH INDICATOR\n ============================================ */\n.if-passwordStrength {\n margin-top: var(--if-space-2);\n}\n\n.if-passwordStrength-bar {\n height: 4px;\n background-color: #e5e7eb;\n border-radius: 2px;\n overflow: hidden;\n margin-bottom: var(--if-space-2);\n}\n\n.if-passwordStrength-fill {\n height: 100%;\n transition:\n width var(--if-transition-base),\n background-color var(--if-transition-base);\n}\n\n.if-passwordStrength-fill.weak {\n background-color: #ef4444;\n width: 33%;\n}\n\n.if-passwordStrength-fill.medium {\n background-color: #f59e0b;\n width: 66%;\n}\n\n.if-passwordStrength-fill.strong {\n background-color: var(--if-color-success);\n width: 100%;\n}\n\n.if-passwordStrength-text {\n font-size: var(--if-font-size-xs);\n color: var(--if-color-text-secondary);\n font-family: var(--if-font-family);\n}\n\n.if-passwordStrength-requirements {\n margin-top: var(--if-space-2);\n font-size: var(--if-font-size-xs);\n color: var(--if-color-text-secondary);\n font-family: var(--if-font-family);\n}\n\n.if-passwordStrength-requirement {\n display: flex;\n align-items: center;\n gap: var(--if-space-1);\n margin-bottom: var(--if-space-1);\n}\n\n.if-passwordStrength-requirement.met {\n color: var(--if-color-success);\n}\n\n.if-passwordStrength-requirement.unmet {\n color: var(--if-color-text-muted);\n}\n\n/* ============================================\n FORM CONTAINER\n ============================================ */\n.if-form {\n display: flex;\n flex-direction: column;\n align-items: stretch;\n justify-content: center;\n gap: var(--if-space-6);\n}\n\n/* ============================================\n USER BUTTON\n ============================================ */\n.if-userButton-container {\n position: relative;\n display: inline-block;\n}\n\n.if-userButton {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: var(--if-space-2);\n padding: var(--if-space-2);\n border-radius: 9999px;\n background-color: transparent;\n border: none;\n cursor: pointer;\n transition: all var(--if-transition-base);\n}\n\n.if-userButton:hover {\n opacity: 0.8;\n}\n\n.if-userButton-detailed {\n background-color: var(--if-color-bg-white);\n border: 1px solid var(--if-color-border);\n border-radius: var(--if-radius-sm);\n padding: var(--if-space-2);\n}\n\n.if-userButton-detailed:hover {\n background-color: var(--if-color-bg-light);\n opacity: 1;\n}\n\n.if-userButton-avatar {\n width: 2rem;\n height: 2rem;\n border-radius: 9999px;\n background-color: var(--if-color-primary);\n color: var(--if-color-bg-white);\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: 600;\n font-size: var(--if-font-size-sm);\n font-family: var(--if-font-family);\n overflow: hidden;\n}\n\n.if-userButton-avatarImage {\n border-radius: 9999px;\n object-fit: cover;\n width: 100%;\n height: 100%;\n}\n\n.if-userButton-avatarInitials {\n color: var(--if-color-bg-white);\n font-weight: 600;\n font-size: var(--if-font-size-sm);\n}\n\n.if-userButton-info {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 0.125rem;\n}\n\n.if-userButton-name {\n font-size: var(--if-font-size-sm);\n font-weight: 600;\n color: var(--if-color-text);\n line-height: 1.25rem;\n text-align: left;\n font-family: var(--if-font-family);\n}\n\n.if-userButton-email {\n font-size: var(--if-font-size-xs);\n color: var(--if-color-text-secondary);\n line-height: 1rem;\n text-align: left;\n font-family: var(--if-font-family);\n}\n\n.if-userButton-menu {\n position: absolute;\n margin-top: var(--if-space-2);\n background-color: var(--if-color-bg-white);\n border: 1px solid var(--if-color-border);\n border-radius: var(--if-radius-md);\n box-shadow: var(--if-shadow-lg);\n padding: var(--if-space-2);\n min-width: 200px;\n z-index: 50;\n}\n\n.if-userButton-menuItem {\n display: flex;\n align-items: center;\n gap: var(--if-space-2);\n padding: var(--if-space-2);\n border-radius: var(--if-radius-sm);\n cursor: pointer;\n transition: background-color var(--if-transition-fast);\n font-size: var(--if-font-size-sm);\n color: var(--if-color-text);\n font-family: var(--if-font-family);\n background: none;\n border: none;\n width: 100%;\n text-align: left;\n}\n\n.if-userButton-menuItem:hover {\n background-color: var(--if-color-bg-light);\n}\n\n.if-userButton-menuItem-signout {\n color: var(--if-color-error);\n}\n\n.if-userButton-menuItem-icon {\n width: 1.25rem;\n height: 1.25rem;\n}\n\n/* ============================================\n EMAIL VERIFICATION STATUS\n ============================================ */\n.if-verifyStatus-container {\n width: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--if-space-6);\n}\n\n.if-verifyStatus-container-stretch {\n width: 100%;\n display: flex;\n flex-direction: column;\n align-items: stretch;\n justify-content: center;\n gap: var(--if-space-6);\n}\n\n.if-verifyStatus-spinner {\n border-radius: 9999px;\n height: 3rem;\n width: 3rem;\n border-bottom: 2px solid var(--if-color-primary);\n}\n\n.if-verifyStatus-successContent {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--if-space-4);\n}\n\n.if-verifyStatus-successIcon {\n width: 4rem;\n height: 4rem;\n border-radius: 9999px;\n background-color: #d1fae5;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.if-verifyStatus-successIconSvg {\n width: 2rem;\n height: 2rem;\n color: #059669;\n}\n\n.if-verifyStatus-textCenter {\n text-align: center;\n}\n\n/* ============================================\n UTILITY CLASSES\n ============================================ */\n.if-hidden {\n display: none;\n}\n\n.if-visuallyHidden {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border-width: 0;\n}\n";
9
9
  if (document.head) {
10
10
  document.head.appendChild(style);
11
11
  }
@@ -15,6 +15,7 @@ if (typeof document !== 'undefined' && typeof window !== 'undefined') {
15
15
  'use strict';
16
16
 
17
17
  var react = require('react');
18
+ var reactRouterDom = require('react-router-dom');
18
19
  var sdk = require('@insforge/sdk');
19
20
  var jsxRuntime = require('react/jsx-runtime');
20
21
  var lucideReact = require('lucide-react');
@@ -25,8 +26,8 @@ function InsforgeProvider({
25
26
  children,
26
27
  baseUrl,
27
28
  onAuthChange,
28
- syncTokenToCookie,
29
- clearCookie
29
+ onSignIn,
30
+ onSignOut
30
31
  }) {
31
32
  const [user, setUser] = react.useState(null);
32
33
  const [isLoaded, setIsLoaded] = react.useState(false);
@@ -62,9 +63,9 @@ function InsforgeProvider({
62
63
  return { success: true };
63
64
  } else {
64
65
  await insforge.auth.signOut();
65
- if (clearCookie) {
66
+ if (onSignOut) {
66
67
  try {
67
- await clearCookie();
68
+ await onSignOut();
68
69
  } catch (error) {
69
70
  if (error instanceof Error) {
70
71
  console.error("[InsforgeProvider] Error clearing cookie:", error.message);
@@ -81,9 +82,9 @@ function InsforgeProvider({
81
82
  } catch (error) {
82
83
  console.error("[InsforgeProvider] Token validation failed:", error);
83
84
  await insforge.auth.signOut();
84
- if (clearCookie) {
85
+ if (onSignOut) {
85
86
  try {
86
- await clearCookie();
87
+ await onSignOut();
87
88
  } catch (error2) {
88
89
  if (error2 instanceof Error) {
89
90
  console.error("[InsforgeProvider] Error clearing cookie:", error2.message);
@@ -100,7 +101,7 @@ function InsforgeProvider({
100
101
  error: error instanceof Error ? error.message : "Authentication failed"
101
102
  };
102
103
  }
103
- }, [insforge, onAuthChange, clearCookie]);
104
+ }, [insforge, onAuthChange, onSignOut]);
104
105
  react.useEffect(() => {
105
106
  loadAuthState();
106
107
  const intervalId = refreshIntervalRef.current;
@@ -139,9 +140,9 @@ function InsforgeProvider({
139
140
  if (onAuthChange) {
140
141
  onAuthChange(userData);
141
142
  }
142
- if (syncTokenToCookie) {
143
+ if (onSignIn) {
143
144
  try {
144
- await syncTokenToCookie(authToken);
145
+ await onSignIn(authToken);
145
146
  } catch (error) {
146
147
  if (error instanceof Error) {
147
148
  console.error("[InsforgeProvider] Error syncing token to cookie:", error.message);
@@ -161,7 +162,7 @@ function InsforgeProvider({
161
162
  }
162
163
  }
163
164
  },
164
- [insforge, onAuthChange, syncTokenToCookie]
165
+ [insforge, onAuthChange, onSignIn]
165
166
  );
166
167
  const signIn = react.useCallback(
167
168
  async (email, password) => {
@@ -216,9 +217,9 @@ function InsforgeProvider({
216
217
  );
217
218
  const signOut = react.useCallback(async () => {
218
219
  await insforge.auth.signOut();
219
- if (clearCookie) {
220
+ if (onSignOut) {
220
221
  try {
221
- await clearCookie();
222
+ await onSignOut();
222
223
  } catch (error) {
223
224
  if (error instanceof Error) {
224
225
  console.error("[InsforgeProvider] Error clearing cookie:", error.message);
@@ -232,7 +233,7 @@ function InsforgeProvider({
232
233
  if (onAuthChange) {
233
234
  onAuthChange(null);
234
235
  }
235
- }, [insforge, onAuthChange, clearCookie]);
236
+ }, [insforge, onAuthChange, onSignOut]);
236
237
  const updateUser = react.useCallback(
237
238
  async (data) => {
238
239
  if (!user) {
@@ -262,6 +263,13 @@ function InsforgeProvider({
262
263
  },
263
264
  [user, onAuthChange, insforge]
264
265
  );
266
+ const sendVerificationEmail = react.useCallback(
267
+ async (email) => {
268
+ const sdkResult = await insforge.auth.sendVerificationEmail({ email });
269
+ return sdkResult.data;
270
+ },
271
+ [insforge]
272
+ );
265
273
  const sendResetPasswordEmail = react.useCallback(
266
274
  async (email) => {
267
275
  const sdkResult = await insforge.auth.sendResetPasswordEmail({ email });
@@ -280,8 +288,39 @@ function InsforgeProvider({
280
288
  [insforge]
281
289
  );
282
290
  const verifyEmail = react.useCallback(
283
- async (token) => {
284
- const sdkResult = await insforge.auth.verifyEmail({ otp: token });
291
+ async (otp, email) => {
292
+ const sdkResult = await insforge.auth.verifyEmail({ otp, email: email || void 0 });
293
+ if (sdkResult.data) {
294
+ return sdkResult.data;
295
+ } else {
296
+ return {
297
+ accessToken: "",
298
+ error: {
299
+ message: sdkResult.error?.message || "Email verification failed"
300
+ }
301
+ };
302
+ }
303
+ },
304
+ [insforge]
305
+ );
306
+ const exchangeResetPasswordToken = react.useCallback(
307
+ async (email, code) => {
308
+ const sdkResult = await insforge.auth.exchangeResetPasswordToken({ email, code });
309
+ if (sdkResult.data) {
310
+ return sdkResult.data;
311
+ } else {
312
+ return {
313
+ error: {
314
+ message: sdkResult.error?.message || "Failed to exchange reset password token"
315
+ }
316
+ };
317
+ }
318
+ },
319
+ [insforge]
320
+ );
321
+ const loginWithOAuth = react.useCallback(
322
+ async (provider, redirectTo) => {
323
+ const sdkResult = await insforge.auth.signInWithOAuth({ provider, redirectTo });
285
324
  return sdkResult.data;
286
325
  },
287
326
  [insforge]
@@ -300,10 +339,13 @@ function InsforgeProvider({
300
339
  updateUser,
301
340
  reloadAuth: loadAuthState,
302
341
  baseUrl,
342
+ sendVerificationEmail,
303
343
  sendResetPasswordEmail,
304
344
  resetPassword,
305
345
  verifyEmail,
306
- getPublicAuthConfig
346
+ exchangeResetPasswordToken,
347
+ getPublicAuthConfig,
348
+ loginWithOAuth
307
349
  },
308
350
  children
309
351
  }
@@ -421,21 +463,12 @@ function AuthErrorBanner({ error }) {
421
463
  if (!error) {
422
464
  return null;
423
465
  }
424
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "if-errorBanner if-internal-eb2m7k", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
425
- /* @__PURE__ */ jsxRuntime.jsx(
426
- lucideReact.AlertTriangle,
427
- {
428
- style: { width: "1.5rem", height: "1.5rem", flexShrink: 0, color: "#dc2626" }
429
- }
430
- ),
466
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "if-errorBanner if-internal-eb2m7k", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "if-errorBanner-content", children: [
467
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "if-errorBanner-icon" }),
431
468
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "if-errorBanner-text", children: error })
432
469
  ] }) });
433
470
  }
434
- function AuthFormField({
435
- label,
436
- id,
437
- ...props
438
- }) {
471
+ function AuthFormField({ label, id, ...props }) {
439
472
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "if-formField if-internal-f9n6p2", children: [
440
473
  /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: id, className: "if-formField-label if-internal-l3k8m1", children: label }),
441
474
  /* @__PURE__ */ jsxRuntime.jsx("input", { id, className: "if-formField-input if-internal-i2v8k4", ...props })
@@ -562,14 +595,17 @@ function AuthSubmitButton({
562
595
  children,
563
596
  isLoading = false,
564
597
  confirmed = false,
565
- disabled = false
598
+ disabled = false,
599
+ type = "submit",
600
+ onClick
566
601
  }) {
567
602
  return /* @__PURE__ */ jsxRuntime.jsxs(
568
603
  "button",
569
604
  {
570
- type: "submit",
605
+ type,
571
606
  className: "if-submitButton if-internal-b8p3m4",
572
607
  disabled: disabled || isLoading || confirmed,
608
+ onClick,
573
609
  children: [
574
610
  isLoading && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "if-submitButton-icon if-submitButton-spinner", size: 20 }),
575
611
  confirmed && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CircleCheck, { className: "if-submitButton-icon", size: 20 }),
@@ -578,24 +614,16 @@ function AuthSubmitButton({
578
614
  }
579
615
  );
580
616
  }
581
- function AuthLink({
582
- text,
583
- linkText,
584
- href
585
- }) {
586
- const currentSearch = typeof window !== "undefined" ? window.location.search : "";
617
+ function AuthLink({ text, linkText, href }) {
618
+ const [searchParams] = reactRouterDom.useSearchParams();
619
+ const currentSearch = searchParams.toString();
587
620
  const finalHref = (() => {
588
621
  if (!currentSearch) {
589
622
  return href;
590
623
  }
591
624
  try {
592
625
  const url = new URL(href, window.location.origin);
593
- const currentParams = new URLSearchParams(currentSearch);
594
- currentParams.forEach((value, key) => {
595
- if (!url.searchParams.has(key)) {
596
- url.searchParams.set(key, value);
597
- }
598
- });
626
+ url.search = currentSearch;
599
627
  return url.pathname + url.search;
600
628
  } catch {
601
629
  return href;
@@ -955,28 +983,26 @@ function AuthVerificationCodeInput({
955
983
  }
956
984
  function AuthEmailVerificationStep({
957
985
  email,
958
- description,
959
986
  method = "code",
960
987
  onVerifyCode
961
988
  }) {
962
- const { baseUrl } = useInsforge();
963
- const [insforge] = react.useState(() => sdk.createClient({ baseUrl }));
989
+ const { sendVerificationEmail } = useInsforge();
964
990
  const [resendDisabled, setResendDisabled] = react.useState(true);
965
991
  const [resendCountdown, setResendCountdown] = react.useState(60);
966
992
  const [isSending, setIsSending] = react.useState(false);
967
993
  const [verificationCode, setVerificationCode] = react.useState("");
968
994
  const [isVerifying, setIsVerifying] = react.useState(false);
969
- const [verificationError, setVerificationError] = react.useState("");
970
995
  const defaultDescription = method === "code" ? "We've sent a 6-digit verification code to {email}. Please enter it below to verify your account. The code will expire in 10 minutes." : "We've sent a verification link to {email}. Please check your email and click the link to verify your account. The link will expire in 10 minutes.";
971
996
  react.useEffect(() => {
972
997
  const sendInitialEmail = async () => {
973
998
  try {
974
- await insforge.auth.sendVerificationEmail({ email });
975
- } catch {
999
+ await sendVerificationEmail(email);
1000
+ } catch (error) {
1001
+ console.error("Failed to send verification email:", error);
976
1002
  }
977
1003
  };
978
1004
  void sendInitialEmail();
979
- }, [email, method, insforge.auth]);
1005
+ }, [email, sendVerificationEmail]);
980
1006
  react.useEffect(() => {
981
1007
  if (resendCountdown > 0) {
982
1008
  const timer = setInterval(() => {
@@ -995,9 +1021,8 @@ function AuthEmailVerificationStep({
995
1021
  setResendDisabled(true);
996
1022
  setResendCountdown(60);
997
1023
  setIsSending(true);
998
- setVerificationError("");
999
1024
  try {
1000
- await insforge.auth.sendVerificationEmail({ email });
1025
+ await sendVerificationEmail(email);
1001
1026
  } catch {
1002
1027
  setResendDisabled(false);
1003
1028
  setResendCountdown(0);
@@ -1005,123 +1030,157 @@ function AuthEmailVerificationStep({
1005
1030
  setIsSending(false);
1006
1031
  }
1007
1032
  };
1008
- const handleVerifyCode = async (code) => {
1009
- if (!onVerifyCode) {
1033
+ const handleSubmit = async () => {
1034
+ if (!onVerifyCode || verificationCode.length !== 6) {
1010
1035
  return;
1011
1036
  }
1012
1037
  setIsVerifying(true);
1013
- setVerificationError("");
1014
1038
  try {
1015
- await onVerifyCode(code);
1016
- } catch (error) {
1017
- setVerificationError(
1018
- error instanceof Error ? error.message : "Invalid verification code. Please try again."
1019
- );
1020
- setVerificationCode("");
1039
+ await onVerifyCode(verificationCode);
1021
1040
  } finally {
1022
1041
  setIsVerifying(false);
1042
+ setVerificationCode("");
1023
1043
  }
1024
1044
  };
1025
- const displayDescription = description || defaultDescription;
1026
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "1.5rem", alignItems: "stretch" }, children: [
1027
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "if-verificationCode-description", children: displayDescription.split("{email}").map((part, index, array) => /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
1045
+ const displayDescription = defaultDescription;
1046
+ const isLinkMethod = method === "link";
1047
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "if-verificationStep", children: [
1048
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "if-verificationStep-description", children: displayDescription.split("{email}").map((part, index, array) => /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
1028
1049
  part,
1029
1050
  index < array.length - 1 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "if-verificationCode-email", children: email })
1030
1051
  ] }, index)) }),
1031
- verificationError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "if-errorBanner if-internal-eb2m7k", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
1052
+ !isLinkMethod && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "if-verificationStep-codeContainer", children: [
1053
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "if-verificationStep-codeInputWrapper", children: /* @__PURE__ */ jsxRuntime.jsx(
1054
+ AuthVerificationCodeInput,
1055
+ {
1056
+ value: verificationCode,
1057
+ onChange: setVerificationCode,
1058
+ email,
1059
+ disabled: isVerifying
1060
+ }
1061
+ ) }),
1032
1062
  /* @__PURE__ */ jsxRuntime.jsx(
1033
- "svg",
1063
+ AuthSubmitButton,
1034
1064
  {
1035
- style: { width: "1.5rem", height: "1.5rem", flexShrink: 0, color: "#DC2626" },
1036
- fill: "none",
1037
- strokeLinecap: "round",
1038
- strokeLinejoin: "round",
1039
- strokeWidth: "2",
1040
- viewBox: "0 0 24 24",
1041
- stroke: "currentColor",
1042
- children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" })
1065
+ type: "button",
1066
+ isLoading: isVerifying,
1067
+ disabled: isVerifying || verificationCode.length !== 6,
1068
+ onClick: () => {
1069
+ void handleSubmit();
1070
+ },
1071
+ children: isVerifying ? "Verifying..." : "Verify Code"
1043
1072
  }
1044
- ),
1045
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "if-errorBanner-text", children: verificationError })
1046
- ] }) }),
1047
- method === "code" && /* @__PURE__ */ jsxRuntime.jsxs(
1048
- "div",
1049
- {
1050
- style: {
1051
- width: "100%",
1052
- backgroundColor: "#F5F5F5",
1053
- borderRadius: "0.5rem",
1054
- padding: "1rem 1rem 1.5rem",
1055
- display: "flex",
1056
- flexDirection: "column",
1057
- gap: "1rem"
1058
- },
1059
- children: [
1060
- /* @__PURE__ */ jsxRuntime.jsx(
1061
- AuthVerificationCodeInput,
1062
- {
1063
- value: verificationCode,
1064
- onChange: setVerificationCode,
1065
- email,
1066
- disabled: isVerifying,
1067
- onComplete: (code) => {
1068
- void handleVerifyCode(code);
1069
- }
1070
- }
1071
- ),
1072
- isVerifying && /* @__PURE__ */ jsxRuntime.jsx(
1073
- "p",
1074
- {
1075
- style: {
1076
- fontSize: "0.875rem",
1077
- color: "#828282",
1078
- textAlign: "center",
1079
- fontFamily: "var(--if-font-family)"
1080
- },
1081
- children: "Verifying..."
1082
- }
1083
- )
1084
- ]
1085
- }
1086
- ),
1087
- /* @__PURE__ */ jsxRuntime.jsxs(
1088
- "div",
1089
- {
1090
- style: {
1091
- width: "100%",
1092
- fontSize: "0.875rem",
1093
- textAlign: "center",
1094
- color: "#828282",
1095
- fontFamily: "var(--if-font-family)"
1096
- },
1097
- children: [
1098
- "Didn't receive the email?",
1099
- " ",
1100
- /* @__PURE__ */ jsxRuntime.jsx(
1101
- "button",
1102
- {
1103
- onClick: () => {
1104
- void handleResend();
1105
- },
1106
- disabled: resendDisabled || isSending,
1107
- style: {
1108
- color: "#000",
1109
- fontWeight: 500,
1110
- transition: "all 0.2s",
1111
- cursor: resendDisabled || isSending ? "not-allowed" : "pointer",
1112
- background: "none",
1113
- border: "none",
1114
- padding: 0,
1115
- textDecoration: resendDisabled || isSending ? "none" : "underline",
1116
- opacity: resendDisabled || isSending ? 0.5 : 1,
1117
- fontFamily: "var(--if-font-family)"
1118
- },
1119
- children: isSending ? "Sending..." : resendDisabled ? `Retry in (${resendCountdown}s)` : "Click to resend"
1120
- }
1121
- )
1122
- ]
1123
- }
1124
- )
1073
+ )
1074
+ ] }),
1075
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "if-verificationStep-resendContainer", children: [
1076
+ "Didn't receive the email?",
1077
+ " ",
1078
+ /* @__PURE__ */ jsxRuntime.jsx(
1079
+ "button",
1080
+ {
1081
+ onClick: () => {
1082
+ void handleResend();
1083
+ },
1084
+ disabled: resendDisabled || isSending,
1085
+ className: "if-verificationStep-resendButton",
1086
+ children: isSending ? "Sending..." : resendDisabled ? `Retry in (${resendCountdown}s)` : "Click to resend"
1087
+ }
1088
+ )
1089
+ ] })
1090
+ ] });
1091
+ }
1092
+ function AuthResetPasswordVerificationStep({
1093
+ email,
1094
+ method,
1095
+ onVerifyCode,
1096
+ onResendEmail
1097
+ }) {
1098
+ const [resendDisabled, setResendDisabled] = react.useState(true);
1099
+ const [resendCountdown, setResendCountdown] = react.useState(60);
1100
+ const [isSending, setIsSending] = react.useState(false);
1101
+ const [verificationCode, setVerificationCode] = react.useState("");
1102
+ const [isVerifying, setIsVerifying] = react.useState(false);
1103
+ react.useEffect(() => {
1104
+ if (resendCountdown > 0) {
1105
+ const timer = setInterval(() => {
1106
+ setResendCountdown((prev) => {
1107
+ if (prev <= 1) {
1108
+ setResendDisabled(false);
1109
+ return 0;
1110
+ }
1111
+ return prev - 1;
1112
+ });
1113
+ }, 1e3);
1114
+ return () => clearInterval(timer);
1115
+ }
1116
+ }, [resendCountdown]);
1117
+ const handleResend = react.useCallback(async () => {
1118
+ setResendDisabled(true);
1119
+ setResendCountdown(60);
1120
+ setIsSending(true);
1121
+ try {
1122
+ await onResendEmail();
1123
+ } catch {
1124
+ setResendDisabled(false);
1125
+ setResendCountdown(0);
1126
+ } finally {
1127
+ setIsSending(false);
1128
+ }
1129
+ }, [onResendEmail]);
1130
+ const handleSubmit = async () => {
1131
+ if (!onVerifyCode || verificationCode.length !== 6) {
1132
+ return;
1133
+ }
1134
+ setIsVerifying(true);
1135
+ try {
1136
+ await onVerifyCode(verificationCode);
1137
+ } finally {
1138
+ setIsVerifying(false);
1139
+ setVerificationCode("");
1140
+ }
1141
+ };
1142
+ const isLinkMethod = method === "link";
1143
+ const description = isLinkMethod ? `We've sent a password reset link to ${email}. Please check your email and click the link to reset your password. The link will expire in 10 minutes.` : `We've sent a 6-digit verification code to ${email}. Please enter it below to reset your password. The code will expire in 10 minutes.`;
1144
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "if-verificationStep", children: [
1145
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "if-verificationStep-description", children: description }),
1146
+ !isLinkMethod && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "if-verificationStep-codeContainer", children: [
1147
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "if-verificationStep-codeInputWrapper", children: /* @__PURE__ */ jsxRuntime.jsx(
1148
+ AuthVerificationCodeInput,
1149
+ {
1150
+ value: verificationCode,
1151
+ onChange: setVerificationCode,
1152
+ email,
1153
+ disabled: isVerifying
1154
+ }
1155
+ ) }),
1156
+ /* @__PURE__ */ jsxRuntime.jsx(
1157
+ AuthSubmitButton,
1158
+ {
1159
+ type: "button",
1160
+ isLoading: isVerifying,
1161
+ disabled: isVerifying || verificationCode.length !== 6,
1162
+ onClick: () => {
1163
+ void handleSubmit();
1164
+ },
1165
+ children: isVerifying ? "Verifying..." : "Continue"
1166
+ }
1167
+ )
1168
+ ] }),
1169
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "if-verificationStep-resendContainer", children: [
1170
+ "Didn't receive the email?",
1171
+ " ",
1172
+ /* @__PURE__ */ jsxRuntime.jsx(
1173
+ "button",
1174
+ {
1175
+ onClick: () => {
1176
+ void handleResend();
1177
+ },
1178
+ disabled: resendDisabled || isSending,
1179
+ className: "if-verificationStep-resendButton",
1180
+ children: isSending ? "Sending..." : resendDisabled ? `Retry in (${resendCountdown}s)` : "Click to resend"
1181
+ }
1182
+ )
1183
+ ] })
1125
1184
  ] });
1126
1185
  }
1127
1186
  function SignInForm({
@@ -1151,8 +1210,7 @@ function SignInForm({
1151
1210
  signUpUrl = "/sign-up",
1152
1211
  dividerText = "or",
1153
1212
  showVerificationStep = false,
1154
- onVerifyCode,
1155
- verificationDescription
1213
+ onVerifyCode
1156
1214
  }) {
1157
1215
  return /* @__PURE__ */ jsxRuntime.jsxs(AuthContainer, { children: [
1158
1216
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -1163,14 +1221,7 @@ function SignInForm({
1163
1221
  }
1164
1222
  ),
1165
1223
  /* @__PURE__ */ jsxRuntime.jsx(AuthErrorBanner, { error: error || "" }),
1166
- showVerificationStep ? /* @__PURE__ */ jsxRuntime.jsx(
1167
- AuthEmailVerificationStep,
1168
- {
1169
- email,
1170
- description: verificationDescription,
1171
- onVerifyCode
1172
- }
1173
- ) : /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit, noValidate: true, className: "if-form if-internal-fm9k2p", children: [
1224
+ showVerificationStep ? /* @__PURE__ */ jsxRuntime.jsx(AuthEmailVerificationStep, { email, onVerifyCode }) : /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit, noValidate: true, className: "if-form if-internal-fm9k2p", children: [
1174
1225
  /* @__PURE__ */ jsxRuntime.jsx(
1175
1226
  AuthFormField,
1176
1227
  {
@@ -1220,16 +1271,17 @@ function SignInForm({
1220
1271
  ] })
1221
1272
  ] });
1222
1273
  }
1223
- function SignIn({ afterSignInUrl, onSuccess, onError, ...uiProps }) {
1224
- const { signIn, baseUrl } = useInsforge();
1274
+ function SignIn({ onError, ...uiProps }) {
1275
+ const { signIn, verifyEmail, loginWithOAuth } = useInsforge();
1225
1276
  const { authConfig } = usePublicAuthConfig();
1226
1277
  const [email, setEmail] = react.useState("");
1227
1278
  const [password, setPassword] = react.useState("");
1228
1279
  const [error, setError] = react.useState("");
1229
1280
  const [loading, setLoading] = react.useState(false);
1230
1281
  const [step, setStep] = react.useState("form");
1231
- const [oauthLoading, setOauthLoading] = react.useState(null);
1232
- const [insforge] = react.useState(() => sdk.createClient({ baseUrl }));
1282
+ const [oauthLoading] = react.useState(null);
1283
+ const [searchParams] = reactRouterDom.useSearchParams();
1284
+ const redirectUrl = searchParams.get("redirect");
1233
1285
  async function handleSubmit(e) {
1234
1286
  e.preventDefault();
1235
1287
  setLoading(true);
@@ -1245,10 +1297,13 @@ function SignIn({ afterSignInUrl, onSuccess, onError, ...uiProps }) {
1245
1297
  throw new Error(result.error);
1246
1298
  }
1247
1299
  const { user, accessToken, redirectTo } = result;
1248
- if (onSuccess) {
1249
- if (user) {
1250
- onSuccess(user, accessToken || "", redirectTo);
1251
- }
1300
+ if (user) {
1301
+ const finalUrl = new URL(redirectTo || redirectUrl || "", window.location.origin);
1302
+ finalUrl.searchParams.set("access_token", accessToken);
1303
+ finalUrl.searchParams.set("user_id", user.id);
1304
+ finalUrl.searchParams.set("email", user.email);
1305
+ finalUrl.searchParams.set("name", user.name);
1306
+ window.location.href = finalUrl.toString();
1252
1307
  }
1253
1308
  } catch (err) {
1254
1309
  const errorMessage = err instanceof Error ? err.message : "Sign in failed";
@@ -1261,38 +1316,28 @@ function SignIn({ afterSignInUrl, onSuccess, onError, ...uiProps }) {
1261
1316
  }
1262
1317
  }
1263
1318
  async function handleVerifyCode(code) {
1319
+ setError("");
1264
1320
  try {
1265
- const result = await insforge.auth.verifyEmail({ email, otp: code });
1266
- if (result.error) {
1321
+ const result = await verifyEmail(email, code);
1322
+ if (result?.error) {
1267
1323
  throw new Error(result.error.message || "Verification failed");
1268
1324
  }
1269
- if (result.data?.accessToken) {
1270
- if (onSuccess && result.data.user) {
1271
- onSuccess(result.data.user, result.data.accessToken);
1272
- }
1325
+ if (result?.user) {
1326
+ const finalUrl = new URL(result.redirectTo || redirectUrl || "", window.location.origin);
1327
+ finalUrl.searchParams.set("access_token", result.accessToken);
1328
+ finalUrl.searchParams.set("user_id", result.user.id);
1329
+ finalUrl.searchParams.set("email", result.user.email);
1330
+ finalUrl.searchParams.set("name", result.user.name);
1331
+ window.location.href = finalUrl.toString();
1273
1332
  }
1274
1333
  } catch (err) {
1275
1334
  const errorMessage = err instanceof Error ? err.message : "Invalid verification code";
1276
- throw new Error(errorMessage);
1277
- }
1278
- }
1279
- async function handleOAuth(provider) {
1280
- try {
1281
- setOauthLoading(provider);
1282
- setError("");
1283
- await insforge.auth.signInWithOAuth({
1284
- provider,
1285
- redirectTo: afterSignInUrl
1286
- });
1287
- } catch (err) {
1288
- const errorMessage = err instanceof Error ? err.message : `${provider} sign in failed`;
1289
1335
  setError(errorMessage);
1290
- if (onError) {
1291
- onError(new Error(errorMessage));
1292
- }
1293
- setOauthLoading(null);
1294
1336
  }
1295
1337
  }
1338
+ function handleOAuth(provider) {
1339
+ loginWithOAuth(provider, redirectUrl || "");
1340
+ }
1296
1341
  if (!authConfig) {
1297
1342
  return null;
1298
1343
  }
@@ -1341,8 +1386,7 @@ function SignUpForm({
1341
1386
  signInUrl = "/sign-in",
1342
1387
  dividerText = "or",
1343
1388
  showVerificationStep = false,
1344
- onVerifyCode,
1345
- verificationDescription
1389
+ onVerifyCode
1346
1390
  }) {
1347
1391
  return /* @__PURE__ */ jsxRuntime.jsxs(AuthContainer, { children: [
1348
1392
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -1353,14 +1397,7 @@ function SignUpForm({
1353
1397
  }
1354
1398
  ),
1355
1399
  /* @__PURE__ */ jsxRuntime.jsx(AuthErrorBanner, { error: error || "" }),
1356
- showVerificationStep ? /* @__PURE__ */ jsxRuntime.jsx(
1357
- AuthEmailVerificationStep,
1358
- {
1359
- email,
1360
- description: verificationDescription,
1361
- onVerifyCode
1362
- }
1363
- ) : /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit, noValidate: true, className: "if-form if-internal-fm9k2p", children: [
1400
+ showVerificationStep ? /* @__PURE__ */ jsxRuntime.jsx(AuthEmailVerificationStep, { email, onVerifyCode }) : /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit, noValidate: true, className: "if-form if-internal-fm9k2p", children: [
1364
1401
  /* @__PURE__ */ jsxRuntime.jsx(
1365
1402
  AuthFormField,
1366
1403
  {
@@ -1479,16 +1516,17 @@ function checkPasswordStrength(password) {
1479
1516
  }
1480
1517
  return { score, feedback };
1481
1518
  }
1482
- function SignUp({ afterSignUpUrl, onSuccess, onError, ...uiProps }) {
1483
- const { signUp, baseUrl } = useInsforge();
1519
+ function SignUp({ onError, ...uiProps }) {
1520
+ const { signUp, verifyEmail, loginWithOAuth } = useInsforge();
1484
1521
  const { authConfig } = usePublicAuthConfig();
1485
1522
  const [email, setEmail] = react.useState("");
1486
1523
  const [password, setPassword] = react.useState("");
1487
1524
  const [error, setError] = react.useState("");
1488
1525
  const [loading, setLoading] = react.useState(false);
1489
1526
  const [step, setStep] = react.useState("form");
1490
- const [oauthLoading, setOauthLoading] = react.useState(null);
1491
- const [insforge] = react.useState(() => sdk.createClient({ baseUrl }));
1527
+ const [oauthLoading] = react.useState(null);
1528
+ const [searchParams] = reactRouterDom.useSearchParams();
1529
+ const redirectUrl = searchParams.get("redirect");
1492
1530
  async function handleSubmit(e) {
1493
1531
  e.preventDefault();
1494
1532
  setLoading(true);
@@ -1530,9 +1568,12 @@ function SignUp({ afterSignUpUrl, onSuccess, onError, ...uiProps }) {
1530
1568
  return;
1531
1569
  }
1532
1570
  if (result.accessToken && result.user) {
1533
- if (onSuccess) {
1534
- onSuccess(result.user, result.accessToken, result.redirectTo);
1535
- }
1571
+ const finalUrl = new URL(result.redirectTo || redirectUrl || "", window.location.origin);
1572
+ finalUrl.searchParams.set("access_token", result.accessToken);
1573
+ finalUrl.searchParams.set("user_id", result.user.id);
1574
+ finalUrl.searchParams.set("email", result.user.email);
1575
+ finalUrl.searchParams.set("name", result.user.name);
1576
+ window.location.href = finalUrl.toString();
1536
1577
  }
1537
1578
  } catch (err) {
1538
1579
  const errorMessage = err instanceof Error ? err.message : "Sign up failed";
@@ -1545,38 +1586,28 @@ function SignUp({ afterSignUpUrl, onSuccess, onError, ...uiProps }) {
1545
1586
  }
1546
1587
  }
1547
1588
  async function handleVerifyCode(code) {
1589
+ setError("");
1548
1590
  try {
1549
- const result = await insforge.auth.verifyEmail({ email, otp: code });
1550
- if (result.error) {
1591
+ const result = await verifyEmail(email, code);
1592
+ if (result?.error) {
1551
1593
  throw new Error(result.error.message || "Verification failed");
1552
1594
  }
1553
- if (result.data?.accessToken) {
1554
- if (onSuccess && result.data.user) {
1555
- onSuccess(result.data.user, result.data.accessToken);
1556
- }
1595
+ if (result?.user) {
1596
+ const finalUrl = new URL(result.redirectTo || redirectUrl || "", window.location.origin);
1597
+ finalUrl.searchParams.set("access_token", result.accessToken);
1598
+ finalUrl.searchParams.set("user_id", result.user.id);
1599
+ finalUrl.searchParams.set("email", result.user.email);
1600
+ finalUrl.searchParams.set("name", result.user.name);
1601
+ window.location.href = finalUrl.toString();
1557
1602
  }
1558
1603
  } catch (err) {
1559
1604
  const errorMessage = err instanceof Error ? err.message : "Invalid verification code";
1560
- throw new Error(errorMessage);
1561
- }
1562
- }
1563
- async function handleOAuth(provider) {
1564
- try {
1565
- setOauthLoading(provider);
1566
- setError("");
1567
- await insforge.auth.signInWithOAuth({
1568
- provider,
1569
- redirectTo: afterSignUpUrl
1570
- });
1571
- } catch (err) {
1572
- const errorMessage = err instanceof Error ? err.message : `${provider} sign up failed`;
1573
1605
  setError(errorMessage);
1574
- if (onError) {
1575
- onError(new Error(errorMessage));
1576
- }
1577
- setOauthLoading(null);
1578
1606
  }
1579
1607
  }
1608
+ function handleOAuth(provider) {
1609
+ loginWithOAuth(provider, redirectUrl || "");
1610
+ }
1580
1611
  if (!authConfig) {
1581
1612
  return null;
1582
1613
  }
@@ -1606,7 +1637,6 @@ function ForgotPasswordForm({
1606
1637
  onSubmit,
1607
1638
  error,
1608
1639
  loading = false,
1609
- success = false,
1610
1640
  title = "Forgot Password?",
1611
1641
  subtitle = "Enter your email address and we'll send you a code to reset your password.",
1612
1642
  emailLabel = "Email",
@@ -1615,53 +1645,30 @@ function ForgotPasswordForm({
1615
1645
  loadingButtonText = "Sending...",
1616
1646
  backToSignInText = "Remember your password?",
1617
1647
  backToSignInUrl = "/sign-in",
1618
- successTitle = "Check Your Email",
1619
- successMessage
1648
+ showVerificationStep = false,
1649
+ resetPasswordMethod = "code",
1650
+ onVerifyCode,
1651
+ onResendEmail
1620
1652
  }) {
1621
- if (success) {
1622
- return /* @__PURE__ */ jsxRuntime.jsx(AuthContainer, { children: /* @__PURE__ */ jsxRuntime.jsxs(
1623
- "div",
1653
+ return /* @__PURE__ */ jsxRuntime.jsxs(AuthContainer, { children: [
1654
+ /* @__PURE__ */ jsxRuntime.jsx(
1655
+ AuthHeader,
1624
1656
  {
1625
- style: { display: "flex", flexDirection: "column", alignItems: "center", gap: "1rem" },
1626
- children: [
1627
- /* @__PURE__ */ jsxRuntime.jsx(
1628
- "div",
1629
- {
1630
- style: {
1631
- width: "4rem",
1632
- height: "4rem",
1633
- borderRadius: "50%",
1634
- backgroundColor: "#D1FAE5",
1635
- display: "flex",
1636
- alignItems: "center",
1637
- justifyContent: "center"
1638
- },
1639
- children: /* @__PURE__ */ jsxRuntime.jsx(
1640
- "svg",
1641
- {
1642
- style: { width: "2rem", height: "2rem", color: "#059669" },
1643
- fill: "none",
1644
- strokeLinecap: "round",
1645
- strokeLinejoin: "round",
1646
- strokeWidth: "2",
1647
- viewBox: "0 0 24 24",
1648
- stroke: "currentColor",
1649
- children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5 13l4 4L19 7" })
1650
- }
1651
- )
1652
- }
1653
- ),
1654
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "if-authHeader-title", style: { textAlign: "center" }, children: successTitle }),
1655
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "if-authHeader-subtitle", style: { textAlign: "center" }, children: successMessage || `We've sent a password reset link to ${email}. Please check your email and follow the instructions.` }),
1656
- /* @__PURE__ */ jsxRuntime.jsx("a", { href: backToSignInUrl, className: "if-authLink-link", style: { marginTop: "1rem" }, children: "Back to Sign In" })
1657
- ]
1657
+ title: showVerificationStep ? resetPasswordMethod === "link" ? "Check Your Email" : "Enter Reset Code" : title,
1658
+ subtitle: showVerificationStep ? "" : subtitle
1658
1659
  }
1659
- ) });
1660
- }
1661
- return /* @__PURE__ */ jsxRuntime.jsxs(AuthContainer, { children: [
1662
- /* @__PURE__ */ jsxRuntime.jsx(AuthHeader, { title, subtitle }),
1660
+ ),
1663
1661
  /* @__PURE__ */ jsxRuntime.jsx(AuthErrorBanner, { error: error || "" }),
1664
- /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit, noValidate: true, className: "if-form if-internal-fm9k2p", children: [
1662
+ showVerificationStep ? /* @__PURE__ */ jsxRuntime.jsx(
1663
+ AuthResetPasswordVerificationStep,
1664
+ {
1665
+ email,
1666
+ method: resetPasswordMethod,
1667
+ onVerifyCode,
1668
+ onResendEmail: onResendEmail || (async () => {
1669
+ })
1670
+ }
1671
+ ) : /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit, noValidate: true, className: "if-form if-internal-fm9k2p", children: [
1665
1672
  /* @__PURE__ */ jsxRuntime.jsx(
1666
1673
  AuthFormField,
1667
1674
  {
@@ -1677,7 +1684,7 @@ function ForgotPasswordForm({
1677
1684
  ),
1678
1685
  /* @__PURE__ */ jsxRuntime.jsx(AuthSubmitButton, { isLoading: loading, disabled: loading, children: loading ? loadingButtonText : submitButtonText })
1679
1686
  ] }),
1680
- /* @__PURE__ */ jsxRuntime.jsx(AuthLink, { text: backToSignInText, linkText: "Back to Sign In", href: backToSignInUrl })
1687
+ !showVerificationStep && /* @__PURE__ */ jsxRuntime.jsx(AuthLink, { text: backToSignInText, linkText: "Back to Sign In", href: backToSignInUrl })
1681
1688
  ] });
1682
1689
  }
1683
1690
  function ResetPasswordForm({
@@ -1698,11 +1705,12 @@ function ResetPasswordForm({
1698
1705
  confirmPasswordPlaceholder = "\u2022\u2022\u2022\u2022\u2022\u2022",
1699
1706
  submitButtonText = "Reset Password",
1700
1707
  loadingButtonText = "Resetting...",
1701
- backToSignInText = "",
1702
- backToSignInUrl = "/sign-in",
1703
- successTitle = "Password Reset Successful!",
1704
- successMessage = "Your password has been successfully reset. You can now sign in with your new password."
1708
+ successTitle = "Password Reset Successful!"
1705
1709
  }) {
1710
+ let successMessage = "Your password has been successfully reset. You can close this page and sign in with your new password.";
1711
+ if (authConfig && authConfig.verifyEmailMethod === "code") {
1712
+ successMessage = "Your password has been successfully reset. You can wait for redirect to sign in with your new password.";
1713
+ }
1706
1714
  if (success) {
1707
1715
  return /* @__PURE__ */ jsxRuntime.jsx(AuthContainer, { children: /* @__PURE__ */ jsxRuntime.jsxs(
1708
1716
  "div",
@@ -1737,8 +1745,7 @@ function ResetPasswordForm({
1737
1745
  }
1738
1746
  ),
1739
1747
  /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "if-authHeader-title", style: { textAlign: "center" }, children: successTitle }),
1740
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "if-authHeader-subtitle", style: { textAlign: "center" }, children: successMessage }),
1741
- /* @__PURE__ */ jsxRuntime.jsx("a", { href: backToSignInUrl, className: "if-authLink-link", style: { marginTop: "1rem" }, children: "Back to Sign In" })
1748
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "if-authHeader-subtitle", style: { textAlign: "center" }, children: successMessage })
1742
1749
  ]
1743
1750
  }
1744
1751
  ) });
@@ -1775,40 +1782,87 @@ function ResetPasswordForm({
1775
1782
  }
1776
1783
  ),
1777
1784
  /* @__PURE__ */ jsxRuntime.jsx(AuthSubmitButton, { isLoading: loading, disabled: loading, children: loading ? loadingButtonText : submitButtonText })
1778
- ] }),
1779
- /* @__PURE__ */ jsxRuntime.jsx(AuthLink, { text: backToSignInText, linkText: "Back to Sign In", href: backToSignInUrl })
1785
+ ] })
1780
1786
  ] });
1781
1787
  }
1782
- function ResetPassword({
1783
- token,
1784
- backToSignInUrl = "/sign-in",
1785
- onSuccess,
1786
- onError,
1787
- ...uiProps
1788
- }) {
1789
- const { resetPassword } = useInsforge();
1788
+ function ForgotPassword({ onError, ...uiProps }) {
1789
+ const { sendResetPasswordEmail, exchangeResetPasswordToken, resetPassword } = useInsforge();
1790
1790
  const { authConfig } = usePublicAuthConfig();
1791
- const [newPassword, setNewPassword] = react.useState("");
1791
+ const [searchParams] = reactRouterDom.useSearchParams();
1792
+ const [step, setStep] = react.useState("email");
1793
+ const [email, setEmail] = react.useState("");
1794
+ const [resetToken, setResetToken] = react.useState("");
1795
+ const [newPassword, setNewPassword] = react.useState("");
1792
1796
  const [confirmPassword, setConfirmPassword] = react.useState("");
1793
1797
  const [error, setError] = react.useState("");
1794
1798
  const [loading, setLoading] = react.useState(false);
1795
1799
  const [success, setSuccess] = react.useState(false);
1796
- async function handleSubmit(e) {
1800
+ const [showVerificationStep, setShowVerificationStep] = react.useState(false);
1801
+ async function handleEmailSubmit(e) {
1797
1802
  e.preventDefault();
1798
1803
  setLoading(true);
1799
1804
  setError("");
1800
- if (!authConfig) {
1801
- setError("Configuration not loaded. Please refresh the page.");
1805
+ const emailValidation = emailSchema.safeParse(email);
1806
+ if (!emailValidation.success) {
1807
+ const firstError = emailValidation.error.issues[0];
1808
+ setError(firstError.message);
1802
1809
  setLoading(false);
1803
1810
  return;
1804
1811
  }
1812
+ try {
1813
+ const result = await sendResetPasswordEmail(emailValidation.data);
1814
+ if (result?.success) {
1815
+ setShowVerificationStep(true);
1816
+ } else {
1817
+ const errorMessage = result?.message || "Failed to send reset email";
1818
+ setError(errorMessage);
1819
+ if (onError) {
1820
+ onError(new Error(errorMessage));
1821
+ }
1822
+ }
1823
+ } catch (err) {
1824
+ const errorMessage = err instanceof Error ? err.message : "Failed to send reset email";
1825
+ setError(errorMessage);
1826
+ if (onError) {
1827
+ onError(new Error(errorMessage));
1828
+ }
1829
+ } finally {
1830
+ setLoading(false);
1831
+ }
1832
+ }
1833
+ async function handleVerifyCode(code) {
1834
+ setError("");
1835
+ try {
1836
+ const result = await exchangeResetPasswordToken(email, code);
1837
+ if ("error" in result) {
1838
+ throw new Error(result.error.message || "Failed to verify code");
1839
+ }
1840
+ if (result.token) {
1841
+ setResetToken(result.token);
1842
+ setStep("password");
1843
+ }
1844
+ } catch (err) {
1845
+ const errorMessage = err instanceof Error ? err.message : "Invalid verification code";
1846
+ setError(errorMessage);
1847
+ if (onError) {
1848
+ onError(new Error(errorMessage));
1849
+ }
1850
+ }
1851
+ }
1852
+ async function handleResendEmail() {
1853
+ await sendResetPasswordEmail(email);
1854
+ }
1855
+ async function handleResetPasswordSubmit(e) {
1856
+ e.preventDefault();
1857
+ setLoading(true);
1858
+ setError("");
1805
1859
  if (newPassword !== confirmPassword) {
1806
1860
  setError("Passwords do not match");
1807
1861
  setLoading(false);
1808
1862
  return;
1809
1863
  }
1810
- if (!token) {
1811
- setError("Reset token is missing");
1864
+ if (!authConfig) {
1865
+ setError("Configuration not loaded");
1812
1866
  setLoading(false);
1813
1867
  return;
1814
1868
  }
@@ -1827,12 +1881,16 @@ function ResetPassword({
1827
1881
  return;
1828
1882
  }
1829
1883
  try {
1830
- const result = await resetPassword(token, newPassword);
1884
+ const result = await resetPassword(resetToken, newPassword);
1831
1885
  if (result?.message) {
1832
1886
  setSuccess(true);
1833
- if (onSuccess) {
1834
- onSuccess();
1835
- }
1887
+ const signInUrl = new URL("/sign-in", window.location.origin);
1888
+ searchParams.forEach((value, key) => {
1889
+ signInUrl.searchParams.set(key, value);
1890
+ });
1891
+ setTimeout(() => {
1892
+ window.location.href = signInUrl.toString();
1893
+ }, 2e3);
1836
1894
  } else {
1837
1895
  const errorMessage = "Failed to reset password";
1838
1896
  setError(errorMessage);
@@ -1853,6 +1911,25 @@ function ResetPassword({
1853
1911
  if (!authConfig) {
1854
1912
  return null;
1855
1913
  }
1914
+ if (step === "email") {
1915
+ return /* @__PURE__ */ jsxRuntime.jsx(
1916
+ ForgotPasswordForm,
1917
+ {
1918
+ email,
1919
+ onEmailChange: setEmail,
1920
+ onSubmit: (e) => {
1921
+ void handleEmailSubmit(e);
1922
+ },
1923
+ error,
1924
+ loading,
1925
+ showVerificationStep,
1926
+ resetPasswordMethod: authConfig.resetPasswordMethod,
1927
+ onVerifyCode: handleVerifyCode,
1928
+ onResendEmail: handleResendEmail,
1929
+ ...uiProps
1930
+ }
1931
+ );
1932
+ }
1856
1933
  return /* @__PURE__ */ jsxRuntime.jsx(
1857
1934
  ResetPasswordForm,
1858
1935
  {
@@ -1860,83 +1937,71 @@ function ResetPassword({
1860
1937
  confirmPassword,
1861
1938
  onNewPasswordChange: setNewPassword,
1862
1939
  onConfirmPasswordChange: setConfirmPassword,
1863
- onSubmit: handleSubmit,
1940
+ onSubmit: handleResetPasswordSubmit,
1864
1941
  error,
1865
1942
  loading,
1866
1943
  success,
1867
1944
  authConfig,
1868
- backToSignInUrl,
1869
1945
  ...uiProps
1870
1946
  }
1871
1947
  );
1872
1948
  }
1873
- function ForgotPassword({
1874
- backToSignInUrl = "/sign-in",
1875
- onSuccess,
1876
- onError,
1877
- ...uiProps
1878
- }) {
1879
- const { sendResetPasswordEmail, baseUrl } = useInsforge();
1949
+ function ResetPassword({ onError, ...uiProps }) {
1950
+ const [searchParams] = reactRouterDom.useSearchParams();
1951
+ const token = searchParams.get("token");
1952
+ const { resetPassword } = useInsforge();
1880
1953
  const { authConfig } = usePublicAuthConfig();
1881
- const [insforge] = react.useState(() => sdk.createClient({ baseUrl }));
1882
- const [step, setStep] = react.useState("email");
1883
- const [email, setEmail] = react.useState("");
1884
- const [verificationCode, setVerificationCode] = react.useState("");
1885
- const [resetToken, setResetToken] = react.useState("");
1954
+ const [newPassword, setNewPassword] = react.useState("");
1955
+ const [confirmPassword, setConfirmPassword] = react.useState("");
1886
1956
  const [error, setError] = react.useState("");
1887
1957
  const [loading, setLoading] = react.useState(false);
1888
1958
  const [success, setSuccess] = react.useState(false);
1889
- const [resendDisabled, setResendDisabled] = react.useState(true);
1890
- const [resendCountdown, setResendCountdown] = react.useState(60);
1891
- const [isSendingCode, setIsSendingCode] = react.useState(false);
1892
- const [isVerifyingCode, setIsVerifyingCode] = react.useState(false);
1893
- react.useEffect(() => {
1894
- if (resendCountdown > 0 && step === "code") {
1895
- const timer = setInterval(() => {
1896
- setResendCountdown((prev) => {
1897
- if (prev <= 1) {
1898
- setResendDisabled(false);
1899
- return 0;
1900
- }
1901
- return prev - 1;
1902
- });
1903
- }, 1e3);
1904
- return () => clearInterval(timer);
1905
- }
1906
- }, [resendCountdown, step]);
1907
- async function handleEmailSubmit(e) {
1959
+ async function handleSubmit(e) {
1908
1960
  e.preventDefault();
1909
1961
  setLoading(true);
1910
1962
  setError("");
1911
- const emailValidation = emailSchema.safeParse(email);
1912
- if (!emailValidation.success) {
1913
- const firstError = emailValidation.error.issues[0];
1963
+ if (!authConfig) {
1964
+ setError("Configuration not loaded. Please refresh the page.");
1965
+ setLoading(false);
1966
+ return;
1967
+ }
1968
+ if (newPassword !== confirmPassword) {
1969
+ setError("Passwords do not match");
1970
+ setLoading(false);
1971
+ return;
1972
+ }
1973
+ if (!token) {
1974
+ setError("Reset token is missing");
1975
+ setLoading(false);
1976
+ return;
1977
+ }
1978
+ const passwordZodSchema = createPasswordSchema({
1979
+ minLength: authConfig.passwordMinLength,
1980
+ requireUppercase: authConfig.requireUppercase,
1981
+ requireLowercase: authConfig.requireLowercase,
1982
+ requireNumber: authConfig.requireNumber,
1983
+ requireSpecialChar: authConfig.requireSpecialChar
1984
+ });
1985
+ const passwordValidation = passwordZodSchema.safeParse(newPassword);
1986
+ if (!passwordValidation.success) {
1987
+ const firstError = passwordValidation.error.issues[0];
1914
1988
  setError(firstError.message);
1915
1989
  setLoading(false);
1916
1990
  return;
1917
1991
  }
1918
1992
  try {
1919
- const result = await sendResetPasswordEmail(emailValidation.data);
1920
- if (result?.success) {
1921
- if (authConfig?.resetPasswordMethod === "link") {
1922
- setSuccess(true);
1923
- if (onSuccess) {
1924
- onSuccess();
1925
- }
1926
- } else {
1927
- setStep("code");
1928
- setResendDisabled(true);
1929
- setResendCountdown(60);
1930
- }
1993
+ const result = await resetPassword(token, newPassword);
1994
+ if (result?.message) {
1995
+ setSuccess(true);
1931
1996
  } else {
1932
- const errorMessage = result?.message || "Failed to send reset code";
1997
+ const errorMessage = "Failed to reset password";
1933
1998
  setError(errorMessage);
1934
1999
  if (onError) {
1935
2000
  onError(new Error(errorMessage));
1936
2001
  }
1937
2002
  }
1938
2003
  } catch (err) {
1939
- const errorMessage = err instanceof Error ? err.message : "Failed to send reset code";
2004
+ const errorMessage = err instanceof Error ? err.message : "Failed to reset password";
1940
2005
  setError(errorMessage);
1941
2006
  if (onError) {
1942
2007
  onError(new Error(errorMessage));
@@ -1945,297 +2010,157 @@ function ForgotPassword({
1945
2010
  setLoading(false);
1946
2011
  }
1947
2012
  }
1948
- async function handleVerifyCode(code) {
1949
- setIsVerifyingCode(true);
1950
- setError("");
1951
- setVerificationCode(code);
1952
- try {
1953
- const result = await insforge.auth.exchangeResetPasswordToken({ email, code });
1954
- if (result.error) {
1955
- throw new Error(result.error.message || "Failed to verify code");
1956
- }
1957
- if (result.data) {
1958
- setResetToken(result.data.token);
1959
- setStep("password");
1960
- }
1961
- } catch (err) {
1962
- const errorMessage = err instanceof Error ? err.message : "Invalid verification code";
1963
- setError(errorMessage);
1964
- setVerificationCode("");
1965
- } finally {
1966
- setIsVerifyingCode(false);
1967
- }
1968
- }
1969
- const handleResendCode = react.useCallback(async () => {
1970
- setResendDisabled(true);
1971
- setResendCountdown(60);
1972
- setIsSendingCode(true);
1973
- setError("");
1974
- try {
1975
- await sendResetPasswordEmail(email);
1976
- } catch (err) {
1977
- const errorMessage = err instanceof Error ? err.message : "Failed to resend code";
1978
- setError(errorMessage);
1979
- setResendDisabled(false);
1980
- setResendCountdown(0);
1981
- } finally {
1982
- setIsSendingCode(false);
1983
- }
1984
- }, [email, sendResetPasswordEmail]);
1985
- function handlePasswordResetSuccess(redirectTo) {
1986
- const targetUrl = redirectTo || backToSignInUrl;
1987
- if (onSuccess) {
1988
- onSuccess();
1989
- }
1990
- setTimeout(() => {
1991
- window.location.href = targetUrl;
1992
- }, 1500);
1993
- }
1994
2013
  if (!authConfig) {
1995
2014
  return null;
1996
2015
  }
1997
- if (step === "email") {
1998
- return /* @__PURE__ */ jsxRuntime.jsx(
1999
- ForgotPasswordForm,
2000
- {
2001
- email,
2002
- onEmailChange: setEmail,
2003
- onSubmit: (e) => {
2004
- void handleEmailSubmit(e);
2005
- },
2006
- error,
2007
- loading,
2008
- success,
2009
- backToSignInUrl,
2010
- ...uiProps
2011
- }
2012
- );
2013
- }
2014
- if (step === "code") {
2016
+ if (!token) {
2015
2017
  return /* @__PURE__ */ jsxRuntime.jsxs(AuthContainer, { children: [
2018
+ /* @__PURE__ */ jsxRuntime.jsx(AuthHeader, { title: "Invalid Reset Link", subtitle: "" }),
2016
2019
  /* @__PURE__ */ jsxRuntime.jsx(
2017
- AuthHeader,
2018
- {
2019
- title: "Enter Reset Code",
2020
- subtitle: `We've sent a 6-digit verification code to ${email}. Please enter it below to reset your password. The code will expire in 10 minutes.`
2021
- }
2022
- ),
2023
- /* @__PURE__ */ jsxRuntime.jsx(AuthErrorBanner, { error }),
2024
- /* @__PURE__ */ jsxRuntime.jsxs(
2025
2020
  "div",
2026
2021
  {
2027
2022
  style: {
2028
- width: "100%",
2029
- display: "flex",
2030
- flexDirection: "column",
2031
- gap: "1.5rem",
2032
- alignItems: "center"
2023
+ padding: "1.5rem",
2024
+ backgroundColor: "#FEE2E2",
2025
+ borderRadius: "0.5rem",
2026
+ border: "1px solid #DC2626"
2033
2027
  },
2034
- children: [
2035
- /* @__PURE__ */ jsxRuntime.jsx(
2036
- "div",
2037
- {
2038
- style: {
2039
- width: "100%",
2040
- backgroundColor: "#F5F5F5",
2041
- borderRadius: "0.5rem",
2042
- padding: "1rem 1rem 1.5rem",
2043
- display: "flex",
2044
- flexDirection: "column",
2045
- gap: "1rem"
2046
- },
2047
- children: /* @__PURE__ */ jsxRuntime.jsxs(
2048
- "div",
2049
- {
2050
- style: {
2051
- display: "flex",
2052
- flexDirection: "column",
2053
- gap: "0.75rem",
2054
- marginTop: "0.5rem"
2055
- },
2056
- children: [
2057
- /* @__PURE__ */ jsxRuntime.jsx(
2058
- AuthVerificationCodeInput,
2059
- {
2060
- value: verificationCode,
2061
- onChange: setVerificationCode,
2062
- email,
2063
- disabled: isVerifyingCode,
2064
- onComplete: (code) => {
2065
- void handleVerifyCode(code);
2066
- }
2067
- }
2068
- ),
2069
- isVerifyingCode && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "if-authHeader-subtitle", style: { textAlign: "center" }, children: "Verifying..." })
2070
- ]
2071
- }
2072
- )
2073
- }
2074
- ),
2075
- /* @__PURE__ */ jsxRuntime.jsxs(
2076
- "div",
2077
- {
2078
- style: {
2079
- width: "100%",
2080
- fontSize: "0.875rem",
2081
- textAlign: "center",
2082
- color: "#828282",
2083
- fontFamily: "var(--if-font-family)"
2084
- },
2085
- children: [
2086
- "Didn't receive the email?",
2087
- " ",
2088
- /* @__PURE__ */ jsxRuntime.jsx(
2089
- "button",
2090
- {
2091
- onClick: () => {
2092
- void handleResendCode();
2093
- },
2094
- disabled: resendDisabled || isSendingCode,
2095
- style: {
2096
- color: "#000",
2097
- fontWeight: 500,
2098
- transition: "all 0.2s",
2099
- cursor: resendDisabled || isSendingCode ? "not-allowed" : "pointer",
2100
- background: "none",
2101
- border: "none",
2102
- padding: 0,
2103
- textDecoration: resendDisabled || isSendingCode ? "none" : "underline",
2104
- opacity: resendDisabled || isSendingCode ? 0.5 : 1,
2105
- fontFamily: "var(--if-font-family)"
2106
- },
2107
- children: isSendingCode ? "Sending..." : resendDisabled ? `Retry in (${resendCountdown}s)` : "Click to resend"
2108
- }
2109
- )
2110
- ]
2111
- }
2112
- )
2113
- ]
2028
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2029
+ "p",
2030
+ {
2031
+ style: {
2032
+ fontSize: "0.875rem",
2033
+ color: "#DC2626",
2034
+ margin: 0,
2035
+ fontFamily: "var(--if-font-family)"
2036
+ },
2037
+ children: "The password reset link is missing or invalid. Please request a new password reset link."
2038
+ }
2039
+ )
2114
2040
  }
2115
- ),
2116
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "if-authHeader-subtitle", style: { textAlign: "center" }, children: /* @__PURE__ */ jsxRuntime.jsx("a", { href: backToSignInUrl, className: "if-authLink-link", children: "Back to Sign In" }) })
2041
+ )
2117
2042
  ] });
2118
2043
  }
2119
- return /* @__PURE__ */ jsxRuntime.jsx(
2120
- ResetPassword,
2121
- {
2122
- token: resetToken,
2123
- backToSignInUrl,
2124
- onSuccess: handlePasswordResetSuccess,
2125
- onError
2126
- }
2127
- );
2128
- }
2129
- function VerifyEmailStatus({
2130
- status,
2131
- error,
2132
- verifyingTitle = "Verifying your email...",
2133
- successTitle = "Email Verified!",
2134
- successMessage = "Your email has been verified successfully. You can close this page and return to your app.",
2135
- errorTitle = "Verification Failed"
2136
- }) {
2137
- if (status === "verifying") {
2044
+ if (success) {
2138
2045
  return /* @__PURE__ */ jsxRuntime.jsx(AuthContainer, { children: /* @__PURE__ */ jsxRuntime.jsxs(
2139
2046
  "div",
2140
2047
  {
2141
- style: {
2142
- width: "100%",
2143
- display: "flex",
2144
- flexDirection: "column",
2145
- alignItems: "center",
2146
- justifyContent: "center",
2147
- gap: "1.5rem"
2148
- },
2048
+ style: { display: "flex", flexDirection: "column", alignItems: "center", gap: "1rem" },
2149
2049
  children: [
2150
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "if-authHeader-title", children: verifyingTitle }),
2151
2050
  /* @__PURE__ */ jsxRuntime.jsx(
2152
2051
  "div",
2153
2052
  {
2154
- className: "if-submitButton-spinner",
2155
2053
  style: {
2054
+ width: "4rem",
2055
+ height: "4rem",
2156
2056
  borderRadius: "50%",
2157
- height: "3rem",
2158
- width: "3rem",
2159
- borderBottom: "2px solid black"
2160
- }
2057
+ backgroundColor: "#D1FAE5",
2058
+ display: "flex",
2059
+ alignItems: "center",
2060
+ justifyContent: "center"
2061
+ },
2062
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2063
+ "svg",
2064
+ {
2065
+ style: { width: "2rem", height: "2rem", color: "#059669" },
2066
+ fill: "none",
2067
+ strokeLinecap: "round",
2068
+ strokeLinejoin: "round",
2069
+ strokeWidth: "2",
2070
+ viewBox: "0 0 24 24",
2071
+ stroke: "currentColor",
2072
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5 13l4 4L19 7" })
2073
+ }
2074
+ )
2075
+ }
2076
+ ),
2077
+ /* @__PURE__ */ jsxRuntime.jsx(
2078
+ "h2",
2079
+ {
2080
+ style: {
2081
+ fontSize: "1.5rem",
2082
+ fontWeight: 600,
2083
+ color: "#000",
2084
+ margin: 0,
2085
+ textAlign: "center",
2086
+ fontFamily: "var(--if-font-family)"
2087
+ },
2088
+ children: "Password Reset Successfully"
2089
+ }
2090
+ ),
2091
+ /* @__PURE__ */ jsxRuntime.jsx(
2092
+ "p",
2093
+ {
2094
+ style: {
2095
+ fontSize: "0.875rem",
2096
+ color: "#828282",
2097
+ textAlign: "center",
2098
+ margin: 0,
2099
+ fontFamily: "var(--if-font-family)"
2100
+ },
2101
+ children: "Your password has been reset successfully. You can now close this page and return to the login page in your original tab."
2161
2102
  }
2162
2103
  )
2163
2104
  ]
2164
2105
  }
2165
2106
  ) });
2166
2107
  }
2108
+ return /* @__PURE__ */ jsxRuntime.jsx(
2109
+ ResetPasswordForm,
2110
+ {
2111
+ newPassword,
2112
+ confirmPassword,
2113
+ onNewPasswordChange: setNewPassword,
2114
+ onConfirmPasswordChange: setConfirmPassword,
2115
+ onSubmit: handleSubmit,
2116
+ error,
2117
+ loading,
2118
+ success: false,
2119
+ authConfig,
2120
+ ...uiProps
2121
+ }
2122
+ );
2123
+ }
2124
+ function VerifyEmailStatus({
2125
+ status,
2126
+ error,
2127
+ verifyingTitle = "Verifying your email...",
2128
+ successTitle = "Email Verified!",
2129
+ successMessage = "Your email has been verified successfully. You can close this page and sign in to your app.",
2130
+ errorTitle = "Verification Failed"
2131
+ }) {
2132
+ if (status === "verifying") {
2133
+ return /* @__PURE__ */ jsxRuntime.jsx(AuthContainer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "if-verifyStatus-container", children: [
2134
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "if-authHeader-title", children: verifyingTitle }),
2135
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "if-submitButton-spinner if-verifyStatus-spinner" })
2136
+ ] }) });
2137
+ }
2167
2138
  if (status === "error") {
2168
- return /* @__PURE__ */ jsxRuntime.jsx(AuthContainer, { children: /* @__PURE__ */ jsxRuntime.jsx(
2169
- "div",
2139
+ return /* @__PURE__ */ jsxRuntime.jsx(AuthContainer, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "if-verifyStatus-container-stretch", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "if-authHeader if-internal-h3m7w5", children: [
2140
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "if-authHeader-title if-internal-t4p1k9", children: errorTitle }),
2141
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "if-authHeader-subtitle if-internal-s7q2m3", children: [
2142
+ error || "The verification link is invalid or has expired.",
2143
+ " Please try again or contact support if the problem persists. You can close this page and return to your app."
2144
+ ] })
2145
+ ] }) }) });
2146
+ }
2147
+ return /* @__PURE__ */ jsxRuntime.jsx(AuthContainer, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "if-verifyStatus-container-stretch", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "if-verifyStatus-successContent", children: [
2148
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "if-verifyStatus-successIcon", children: /* @__PURE__ */ jsxRuntime.jsx(
2149
+ "svg",
2170
2150
  {
2171
- style: {
2172
- width: "100%",
2173
- display: "flex",
2174
- flexDirection: "column",
2175
- alignItems: "stretch",
2176
- justifyContent: "center",
2177
- gap: "1.5rem"
2178
- },
2179
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "if-authHeader if-internal-h3m7w5", children: [
2180
- /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "if-authHeader-title if-internal-t4p1k9", children: errorTitle }),
2181
- /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "if-authHeader-subtitle if-internal-s7q2m3", style: { lineHeight: "1.5" }, children: [
2182
- error || "The verification link is invalid or has expired.",
2183
- " Please try again or contact support if the problem persists. You can close this page and return to your app."
2184
- ] })
2185
- ] })
2151
+ className: "if-verifyStatus-successIconSvg",
2152
+ fill: "none",
2153
+ strokeLinecap: "round",
2154
+ strokeLinejoin: "round",
2155
+ strokeWidth: "2",
2156
+ viewBox: "0 0 24 24",
2157
+ stroke: "currentColor",
2158
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5 13l4 4L19 7" })
2186
2159
  }
2187
- ) });
2188
- }
2189
- return /* @__PURE__ */ jsxRuntime.jsx(AuthContainer, { children: /* @__PURE__ */ jsxRuntime.jsx(
2190
- "div",
2191
- {
2192
- style: {
2193
- width: "100%",
2194
- display: "flex",
2195
- flexDirection: "column",
2196
- alignItems: "stretch",
2197
- justifyContent: "center",
2198
- gap: "1.5rem"
2199
- },
2200
- children: /* @__PURE__ */ jsxRuntime.jsxs(
2201
- "div",
2202
- {
2203
- style: { display: "flex", flexDirection: "column", alignItems: "center", gap: "1rem" },
2204
- children: [
2205
- /* @__PURE__ */ jsxRuntime.jsx(
2206
- "div",
2207
- {
2208
- style: {
2209
- width: "4rem",
2210
- height: "4rem",
2211
- borderRadius: "50%",
2212
- backgroundColor: "#D1FAE5",
2213
- display: "flex",
2214
- alignItems: "center",
2215
- justifyContent: "center"
2216
- },
2217
- children: /* @__PURE__ */ jsxRuntime.jsx(
2218
- "svg",
2219
- {
2220
- style: { width: "2rem", height: "2rem", color: "#059669" },
2221
- fill: "none",
2222
- strokeLinecap: "round",
2223
- strokeLinejoin: "round",
2224
- strokeWidth: "2",
2225
- viewBox: "0 0 24 24",
2226
- stroke: "currentColor",
2227
- children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5 13l4 4L19 7" })
2228
- }
2229
- )
2230
- }
2231
- ),
2232
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "if-authHeader-title", style: { textAlign: "center" }, children: successTitle }),
2233
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "if-authHeader-subtitle", style: { textAlign: "center" }, children: successMessage })
2234
- ]
2235
- }
2236
- )
2237
- }
2238
- ) });
2160
+ ) }),
2161
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "if-authHeader-title if-verifyStatus-textCenter", children: successTitle }),
2162
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "if-authHeader-subtitle if-verifyStatus-textCenter", children: successMessage })
2163
+ ] }) }) });
2239
2164
  }
2240
2165
  function VerifyEmail({ token, onSuccess, onError, ...uiProps }) {
2241
2166
  const { verifyEmail } = useInsforge();
@@ -2336,93 +2261,43 @@ function UserButton({ afterSignOutUrl = "/", mode = "detailed" }) {
2336
2261
  }
2337
2262
  const initials = user.name ? user.name.charAt(0).toUpperCase() : user.email.split("@")[0].slice(0, 2).toUpperCase();
2338
2263
  const buttonClassName = mode === "detailed" ? "if-userButton if-userButton-detailed" : "if-userButton";
2339
- return /* @__PURE__ */ jsxRuntime.jsxs(
2340
- "div",
2341
- {
2342
- className: "if-userButton if-internal-ub3k8p",
2343
- style: { position: "relative", display: "inline-block" },
2344
- ref: dropdownRef,
2345
- children: [
2346
- /* @__PURE__ */ jsxRuntime.jsxs(
2347
- "button",
2348
- {
2349
- className: buttonClassName,
2350
- style: {
2351
- display: "flex",
2352
- alignItems: "center",
2353
- justifyContent: "center",
2354
- gap: "0.5rem",
2355
- ...mode === "detailed" ? { borderRadius: "0.5rem", padding: "0.5rem" } : {}
2356
- },
2357
- onClick: () => setIsOpen(!isOpen),
2358
- "aria-expanded": isOpen,
2359
- "aria-haspopup": "true",
2360
- children: [
2361
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "if-userButton-avatar", children: user.avatarUrl && !imageError ? /* @__PURE__ */ jsxRuntime.jsx(
2362
- "img",
2363
- {
2364
- src: user.avatarUrl,
2365
- alt: user.email,
2366
- onError: () => setImageError(true),
2367
- style: { borderRadius: "50%", objectFit: "cover", width: "100%", height: "100%" }
2368
- }
2369
- ) : /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "white", fontWeight: 600, fontSize: "0.875rem" }, children: initials }) }),
2370
- mode === "detailed" && /* @__PURE__ */ jsxRuntime.jsxs(
2371
- "div",
2372
- {
2373
- style: {
2374
- display: "flex",
2375
- flexDirection: "column",
2376
- alignItems: "flex-start",
2377
- gap: "0.125rem"
2378
- },
2379
- children: [
2380
- user.name && /* @__PURE__ */ jsxRuntime.jsx(
2381
- "div",
2382
- {
2383
- style: {
2384
- fontSize: "0.875rem",
2385
- fontWeight: 600,
2386
- color: "#1f1f1f",
2387
- lineHeight: "1.25rem",
2388
- textAlign: "left"
2389
- },
2390
- children: user.name
2391
- }
2392
- ),
2393
- /* @__PURE__ */ jsxRuntime.jsx(
2394
- "div",
2395
- {
2396
- style: {
2397
- fontSize: "0.75rem",
2398
- color: "#828282",
2399
- lineHeight: "1rem",
2400
- textAlign: "left"
2401
- },
2402
- children: user.email
2403
- }
2404
- )
2405
- ]
2406
- }
2407
- )
2408
- ]
2409
- }
2410
- ),
2411
- isOpen && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "if-userButton-menu", children: /* @__PURE__ */ jsxRuntime.jsxs(
2412
- "button",
2413
- {
2414
- onClick: handleSignOut,
2415
- className: "if-userButton-menuItem",
2416
- style: { color: "#DC2626" },
2417
- children: [
2418
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.LogOut, { style: { width: "1.25rem", height: "1.25rem" } }),
2419
- "Sign out"
2420
- ]
2421
- }
2422
- ) })
2423
- ]
2424
- }
2425
- );
2264
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "if-userButton-container if-internal-ub3k8p", ref: dropdownRef, children: [
2265
+ /* @__PURE__ */ jsxRuntime.jsxs(
2266
+ "button",
2267
+ {
2268
+ className: buttonClassName,
2269
+ onClick: () => setIsOpen(!isOpen),
2270
+ "aria-expanded": isOpen,
2271
+ "aria-haspopup": "true",
2272
+ children: [
2273
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "if-userButton-avatar", children: user.avatarUrl && !imageError ? /* @__PURE__ */ jsxRuntime.jsx(
2274
+ "img",
2275
+ {
2276
+ src: user.avatarUrl,
2277
+ alt: user.email,
2278
+ onError: () => setImageError(true),
2279
+ className: "if-userButton-avatarImage"
2280
+ }
2281
+ ) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "if-userButton-avatarInitials", children: initials }) }),
2282
+ mode === "detailed" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "if-userButton-info", children: [
2283
+ user.name && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "if-userButton-name", children: user.name }),
2284
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "if-userButton-email", children: user.email })
2285
+ ] })
2286
+ ]
2287
+ }
2288
+ ),
2289
+ isOpen && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "if-userButton-menu", children: /* @__PURE__ */ jsxRuntime.jsxs(
2290
+ "button",
2291
+ {
2292
+ onClick: handleSignOut,
2293
+ className: "if-userButton-menuItem if-userButton-menuItem-signout",
2294
+ children: [
2295
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.LogOut, { className: "if-userButton-menuItem-icon" }),
2296
+ "Sign out"
2297
+ ]
2298
+ }
2299
+ ) })
2300
+ ] });
2426
2301
  }
2427
2302
  function Protect({
2428
2303
  children,
@@ -2480,94 +2355,6 @@ function SignedOut({ children }) {
2480
2355
  }
2481
2356
  return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
2482
2357
  }
2483
- function InsforgeCallback({
2484
- redirectTo = "/",
2485
- onSuccess,
2486
- onError,
2487
- loadingComponent,
2488
- onRedirect
2489
- }) {
2490
- const isProcessingRef = react.useRef(false);
2491
- const { isLoaded, isSignedIn } = useInsforge();
2492
- react.useEffect(() => {
2493
- if (!isLoaded) {
2494
- return;
2495
- }
2496
- if (isProcessingRef.current) {
2497
- return;
2498
- }
2499
- isProcessingRef.current = true;
2500
- const processCallback = () => {
2501
- const searchParams = new URLSearchParams(window.location.search);
2502
- const error = searchParams.get("error");
2503
- if (error) {
2504
- if (onError) {
2505
- onError(error);
2506
- } else {
2507
- const errorUrl = "/?error=" + encodeURIComponent(error);
2508
- if (onRedirect) {
2509
- onRedirect(errorUrl);
2510
- } else {
2511
- window.location.href = errorUrl;
2512
- }
2513
- }
2514
- return;
2515
- }
2516
- if (!isSignedIn) {
2517
- const errorMsg = "authentication_failed";
2518
- if (onError) {
2519
- onError(errorMsg);
2520
- } else {
2521
- const errorUrl = "/?error=" + encodeURIComponent(errorMsg);
2522
- if (onRedirect) {
2523
- onRedirect(errorUrl);
2524
- } else {
2525
- window.location.href = errorUrl;
2526
- }
2527
- }
2528
- return;
2529
- }
2530
- window.history.replaceState({}, "", window.location.pathname);
2531
- if (onSuccess) {
2532
- onSuccess();
2533
- }
2534
- if (onRedirect) {
2535
- onRedirect(redirectTo);
2536
- } else {
2537
- window.location.href = redirectTo;
2538
- }
2539
- };
2540
- processCallback();
2541
- }, [isLoaded, isSignedIn, redirectTo, onSuccess, onError, onRedirect]);
2542
- const defaultLoading = /* @__PURE__ */ jsxRuntime.jsx(
2543
- "div",
2544
- {
2545
- style: {
2546
- display: "flex",
2547
- alignItems: "center",
2548
- justifyContent: "center",
2549
- minHeight: "100vh"
2550
- },
2551
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { textAlign: "center" }, children: [
2552
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "if-authHeader-title", style: { marginBottom: "1rem" }, children: "Completing authentication..." }),
2553
- /* @__PURE__ */ jsxRuntime.jsx(
2554
- "div",
2555
- {
2556
- className: "if-submitButton-spinner",
2557
- style: {
2558
- borderRadius: "50%",
2559
- height: "3rem",
2560
- width: "3rem",
2561
- borderBottom: "2px solid #2563EB",
2562
- margin: "0 auto"
2563
- }
2564
- }
2565
- )
2566
- ] })
2567
- }
2568
- );
2569
- return loadingComponent || defaultLoading;
2570
- }
2571
2358
 
2572
2359
  // src/hooks/useAuth.ts
2573
2360
  function useAuth() {
@@ -2638,11 +2425,11 @@ exports.AuthOAuthButton = AuthOAuthButton;
2638
2425
  exports.AuthOAuthProviders = AuthOAuthProviders;
2639
2426
  exports.AuthPasswordField = AuthPasswordField;
2640
2427
  exports.AuthPasswordStrengthIndicator = AuthPasswordStrengthIndicator;
2428
+ exports.AuthResetPasswordVerificationStep = AuthResetPasswordVerificationStep;
2641
2429
  exports.AuthSubmitButton = AuthSubmitButton;
2642
2430
  exports.AuthVerificationCodeInput = AuthVerificationCodeInput;
2643
2431
  exports.ForgotPassword = ForgotPassword;
2644
2432
  exports.ForgotPasswordForm = ForgotPasswordForm;
2645
- exports.InsforgeCallback = InsforgeCallback;
2646
2433
  exports.InsforgeProvider = InsforgeProvider;
2647
2434
  exports.OAUTH_PROVIDER_CONFIG = OAUTH_PROVIDER_CONFIG;
2648
2435
  exports.Protect = Protect;