@insforge/react 0.4.0 → 0.4.6

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.js 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
  }
@@ -13,6 +13,7 @@ if (typeof document !== 'undefined' && typeof window !== 'undefined') {
13
13
  }
14
14
 
15
15
  import { createContext, useState, useRef, useCallback, useEffect, useContext } from 'react';
16
+ import { useSearchParams } from 'react-router-dom';
16
17
  import { createClient } from '@insforge/sdk';
17
18
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
18
19
  import { AlertTriangle, Check, EyeOff, Eye, Loader2, CircleCheck, LogOut } from 'lucide-react';
@@ -22,13 +23,15 @@ var InsforgeContext = createContext(void 0);
22
23
  function InsforgeProvider({
23
24
  children,
24
25
  baseUrl,
26
+ afterSignInUrl = "/",
25
27
  onAuthChange,
26
- syncTokenToCookie,
27
- clearCookie
28
+ onSignIn,
29
+ onSignOut
28
30
  }) {
29
31
  const [user, setUser] = useState(null);
30
32
  const [isLoaded, setIsLoaded] = useState(false);
31
33
  const refreshIntervalRef = useRef(null);
34
+ const hasProcessedCallbackRef = useRef(false);
32
35
  const [insforge] = useState(() => createClient({ baseUrl }));
33
36
  const loadAuthState = useCallback(async () => {
34
37
  try {
@@ -60,9 +63,9 @@ function InsforgeProvider({
60
63
  return { success: true };
61
64
  } else {
62
65
  await insforge.auth.signOut();
63
- if (clearCookie) {
66
+ if (onSignOut) {
64
67
  try {
65
- await clearCookie();
68
+ await onSignOut();
66
69
  } catch (error) {
67
70
  if (error instanceof Error) {
68
71
  console.error("[InsforgeProvider] Error clearing cookie:", error.message);
@@ -79,9 +82,9 @@ function InsforgeProvider({
79
82
  } catch (error) {
80
83
  console.error("[InsforgeProvider] Token validation failed:", error);
81
84
  await insforge.auth.signOut();
82
- if (clearCookie) {
85
+ if (onSignOut) {
83
86
  try {
84
- await clearCookie();
87
+ await onSignOut();
85
88
  } catch (error2) {
86
89
  if (error2 instanceof Error) {
87
90
  console.error("[InsforgeProvider] Error clearing cookie:", error2.message);
@@ -98,7 +101,7 @@ function InsforgeProvider({
98
101
  error: error instanceof Error ? error.message : "Authentication failed"
99
102
  };
100
103
  }
101
- }, [insforge, onAuthChange, clearCookie]);
104
+ }, [insforge, onAuthChange, onSignOut]);
102
105
  useEffect(() => {
103
106
  loadAuthState();
104
107
  const intervalId = refreshIntervalRef.current;
@@ -108,6 +111,22 @@ function InsforgeProvider({
108
111
  }
109
112
  };
110
113
  }, [loadAuthState]);
114
+ useEffect(() => {
115
+ if (!isLoaded || hasProcessedCallbackRef.current) {
116
+ return;
117
+ }
118
+ const searchParams = new URLSearchParams(window.location.search);
119
+ const accessToken = searchParams.get("access_token");
120
+ if (accessToken && !!user) {
121
+ hasProcessedCallbackRef.current = true;
122
+ const url = new URL(window.location.href);
123
+ url.search = "";
124
+ window.history.replaceState({}, "", url.toString());
125
+ setTimeout(() => {
126
+ window.location.href = afterSignInUrl;
127
+ }, 100);
128
+ }
129
+ }, [isLoaded, user, afterSignInUrl]);
111
130
  const getPublicAuthConfig = useCallback(async () => {
112
131
  try {
113
132
  const result = await insforge.auth.getPublicAuthConfig();
@@ -137,9 +156,9 @@ function InsforgeProvider({
137
156
  if (onAuthChange) {
138
157
  onAuthChange(userData);
139
158
  }
140
- if (syncTokenToCookie) {
159
+ if (onSignIn) {
141
160
  try {
142
- await syncTokenToCookie(authToken);
161
+ await onSignIn(authToken);
143
162
  } catch (error) {
144
163
  if (error instanceof Error) {
145
164
  console.error("[InsforgeProvider] Error syncing token to cookie:", error.message);
@@ -159,7 +178,7 @@ function InsforgeProvider({
159
178
  }
160
179
  }
161
180
  },
162
- [insforge, onAuthChange, syncTokenToCookie]
181
+ [insforge, onAuthChange, onSignIn]
163
182
  );
164
183
  const signIn = useCallback(
165
184
  async (email, password) => {
@@ -214,9 +233,9 @@ function InsforgeProvider({
214
233
  );
215
234
  const signOut = useCallback(async () => {
216
235
  await insforge.auth.signOut();
217
- if (clearCookie) {
236
+ if (onSignOut) {
218
237
  try {
219
- await clearCookie();
238
+ await onSignOut();
220
239
  } catch (error) {
221
240
  if (error instanceof Error) {
222
241
  console.error("[InsforgeProvider] Error clearing cookie:", error.message);
@@ -230,7 +249,7 @@ function InsforgeProvider({
230
249
  if (onAuthChange) {
231
250
  onAuthChange(null);
232
251
  }
233
- }, [insforge, onAuthChange, clearCookie]);
252
+ }, [insforge, onAuthChange, onSignOut]);
234
253
  const updateUser = useCallback(
235
254
  async (data) => {
236
255
  if (!user) {
@@ -260,6 +279,13 @@ function InsforgeProvider({
260
279
  },
261
280
  [user, onAuthChange, insforge]
262
281
  );
282
+ const sendVerificationEmail = useCallback(
283
+ async (email) => {
284
+ const sdkResult = await insforge.auth.sendVerificationEmail({ email });
285
+ return sdkResult.data;
286
+ },
287
+ [insforge]
288
+ );
263
289
  const sendResetPasswordEmail = useCallback(
264
290
  async (email) => {
265
291
  const sdkResult = await insforge.auth.sendResetPasswordEmail({ email });
@@ -278,8 +304,39 @@ function InsforgeProvider({
278
304
  [insforge]
279
305
  );
280
306
  const verifyEmail = useCallback(
281
- async (token) => {
282
- const sdkResult = await insforge.auth.verifyEmail({ otp: token });
307
+ async (otp, email) => {
308
+ const sdkResult = await insforge.auth.verifyEmail({ otp, email: email || void 0 });
309
+ if (sdkResult.data) {
310
+ return sdkResult.data;
311
+ } else {
312
+ return {
313
+ accessToken: "",
314
+ error: {
315
+ message: sdkResult.error?.message || "Email verification failed"
316
+ }
317
+ };
318
+ }
319
+ },
320
+ [insforge]
321
+ );
322
+ const exchangeResetPasswordToken = useCallback(
323
+ async (email, code) => {
324
+ const sdkResult = await insforge.auth.exchangeResetPasswordToken({ email, code });
325
+ if (sdkResult.data) {
326
+ return sdkResult.data;
327
+ } else {
328
+ return {
329
+ error: {
330
+ message: sdkResult.error?.message || "Failed to exchange reset password token"
331
+ }
332
+ };
333
+ }
334
+ },
335
+ [insforge]
336
+ );
337
+ const loginWithOAuth = useCallback(
338
+ async (provider, redirectTo) => {
339
+ const sdkResult = await insforge.auth.signInWithOAuth({ provider, redirectTo });
283
340
  return sdkResult.data;
284
341
  },
285
342
  [insforge]
@@ -298,10 +355,13 @@ function InsforgeProvider({
298
355
  updateUser,
299
356
  reloadAuth: loadAuthState,
300
357
  baseUrl,
358
+ sendVerificationEmail,
301
359
  sendResetPasswordEmail,
302
360
  resetPassword,
303
361
  verifyEmail,
304
- getPublicAuthConfig
362
+ exchangeResetPasswordToken,
363
+ getPublicAuthConfig,
364
+ loginWithOAuth
305
365
  },
306
366
  children
307
367
  }
@@ -419,21 +479,12 @@ function AuthErrorBanner({ error }) {
419
479
  if (!error) {
420
480
  return null;
421
481
  }
422
- return /* @__PURE__ */ jsx("div", { className: "if-errorBanner if-internal-eb2m7k", children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
423
- /* @__PURE__ */ jsx(
424
- AlertTriangle,
425
- {
426
- style: { width: "1.5rem", height: "1.5rem", flexShrink: 0, color: "#dc2626" }
427
- }
428
- ),
482
+ return /* @__PURE__ */ jsx("div", { className: "if-errorBanner if-internal-eb2m7k", children: /* @__PURE__ */ jsxs("div", { className: "if-errorBanner-content", children: [
483
+ /* @__PURE__ */ jsx(AlertTriangle, { className: "if-errorBanner-icon" }),
429
484
  /* @__PURE__ */ jsx("span", { className: "if-errorBanner-text", children: error })
430
485
  ] }) });
431
486
  }
432
- function AuthFormField({
433
- label,
434
- id,
435
- ...props
436
- }) {
487
+ function AuthFormField({ label, id, ...props }) {
437
488
  return /* @__PURE__ */ jsxs("div", { className: "if-formField if-internal-f9n6p2", children: [
438
489
  /* @__PURE__ */ jsx("label", { htmlFor: id, className: "if-formField-label if-internal-l3k8m1", children: label }),
439
490
  /* @__PURE__ */ jsx("input", { id, className: "if-formField-input if-internal-i2v8k4", ...props })
@@ -560,14 +611,17 @@ function AuthSubmitButton({
560
611
  children,
561
612
  isLoading = false,
562
613
  confirmed = false,
563
- disabled = false
614
+ disabled = false,
615
+ type = "submit",
616
+ onClick
564
617
  }) {
565
618
  return /* @__PURE__ */ jsxs(
566
619
  "button",
567
620
  {
568
- type: "submit",
621
+ type,
569
622
  className: "if-submitButton if-internal-b8p3m4",
570
623
  disabled: disabled || isLoading || confirmed,
624
+ onClick,
571
625
  children: [
572
626
  isLoading && /* @__PURE__ */ jsx(Loader2, { className: "if-submitButton-icon if-submitButton-spinner", size: 20 }),
573
627
  confirmed && /* @__PURE__ */ jsx(CircleCheck, { className: "if-submitButton-icon", size: 20 }),
@@ -576,24 +630,16 @@ function AuthSubmitButton({
576
630
  }
577
631
  );
578
632
  }
579
- function AuthLink({
580
- text,
581
- linkText,
582
- href
583
- }) {
584
- const currentSearch = typeof window !== "undefined" ? window.location.search : "";
633
+ function AuthLink({ text, linkText, href }) {
634
+ const [searchParams] = useSearchParams();
635
+ const currentSearch = searchParams.toString();
585
636
  const finalHref = (() => {
586
637
  if (!currentSearch) {
587
638
  return href;
588
639
  }
589
640
  try {
590
641
  const url = new URL(href, window.location.origin);
591
- const currentParams = new URLSearchParams(currentSearch);
592
- currentParams.forEach((value, key) => {
593
- if (!url.searchParams.has(key)) {
594
- url.searchParams.set(key, value);
595
- }
596
- });
642
+ url.search = currentSearch;
597
643
  return url.pathname + url.search;
598
644
  } catch {
599
645
  return href;
@@ -953,28 +999,26 @@ function AuthVerificationCodeInput({
953
999
  }
954
1000
  function AuthEmailVerificationStep({
955
1001
  email,
956
- description,
957
1002
  method = "code",
958
1003
  onVerifyCode
959
1004
  }) {
960
- const { baseUrl } = useInsforge();
961
- const [insforge] = useState(() => createClient({ baseUrl }));
1005
+ const { sendVerificationEmail } = useInsforge();
962
1006
  const [resendDisabled, setResendDisabled] = useState(true);
963
1007
  const [resendCountdown, setResendCountdown] = useState(60);
964
1008
  const [isSending, setIsSending] = useState(false);
965
1009
  const [verificationCode, setVerificationCode] = useState("");
966
1010
  const [isVerifying, setIsVerifying] = useState(false);
967
- const [verificationError, setVerificationError] = useState("");
968
1011
  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.";
969
1012
  useEffect(() => {
970
1013
  const sendInitialEmail = async () => {
971
1014
  try {
972
- await insforge.auth.sendVerificationEmail({ email });
973
- } catch {
1015
+ await sendVerificationEmail(email);
1016
+ } catch (error) {
1017
+ console.error("Failed to send verification email:", error);
974
1018
  }
975
1019
  };
976
1020
  void sendInitialEmail();
977
- }, [email, method, insforge.auth]);
1021
+ }, [email, sendVerificationEmail]);
978
1022
  useEffect(() => {
979
1023
  if (resendCountdown > 0) {
980
1024
  const timer = setInterval(() => {
@@ -993,9 +1037,8 @@ function AuthEmailVerificationStep({
993
1037
  setResendDisabled(true);
994
1038
  setResendCountdown(60);
995
1039
  setIsSending(true);
996
- setVerificationError("");
997
1040
  try {
998
- await insforge.auth.sendVerificationEmail({ email });
1041
+ await sendVerificationEmail(email);
999
1042
  } catch {
1000
1043
  setResendDisabled(false);
1001
1044
  setResendCountdown(0);
@@ -1003,123 +1046,157 @@ function AuthEmailVerificationStep({
1003
1046
  setIsSending(false);
1004
1047
  }
1005
1048
  };
1006
- const handleVerifyCode = async (code) => {
1007
- if (!onVerifyCode) {
1049
+ const handleSubmit = async () => {
1050
+ if (!onVerifyCode || verificationCode.length !== 6) {
1008
1051
  return;
1009
1052
  }
1010
1053
  setIsVerifying(true);
1011
- setVerificationError("");
1012
1054
  try {
1013
- await onVerifyCode(code);
1014
- } catch (error) {
1015
- setVerificationError(
1016
- error instanceof Error ? error.message : "Invalid verification code. Please try again."
1017
- );
1018
- setVerificationCode("");
1055
+ await onVerifyCode(verificationCode);
1019
1056
  } finally {
1020
1057
  setIsVerifying(false);
1058
+ setVerificationCode("");
1021
1059
  }
1022
1060
  };
1023
- const displayDescription = description || defaultDescription;
1024
- return /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "1.5rem", alignItems: "stretch" }, children: [
1025
- /* @__PURE__ */ jsx("p", { className: "if-verificationCode-description", children: displayDescription.split("{email}").map((part, index, array) => /* @__PURE__ */ jsxs("span", { children: [
1061
+ const displayDescription = defaultDescription;
1062
+ const isLinkMethod = method === "link";
1063
+ return /* @__PURE__ */ jsxs("div", { className: "if-verificationStep", children: [
1064
+ /* @__PURE__ */ jsx("p", { className: "if-verificationStep-description", children: displayDescription.split("{email}").map((part, index, array) => /* @__PURE__ */ jsxs("span", { children: [
1026
1065
  part,
1027
1066
  index < array.length - 1 && /* @__PURE__ */ jsx("span", { className: "if-verificationCode-email", children: email })
1028
1067
  ] }, index)) }),
1029
- verificationError && /* @__PURE__ */ jsx("div", { className: "if-errorBanner if-internal-eb2m7k", children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
1068
+ !isLinkMethod && /* @__PURE__ */ jsxs("div", { className: "if-verificationStep-codeContainer", children: [
1069
+ /* @__PURE__ */ jsx("div", { className: "if-verificationStep-codeInputWrapper", children: /* @__PURE__ */ jsx(
1070
+ AuthVerificationCodeInput,
1071
+ {
1072
+ value: verificationCode,
1073
+ onChange: setVerificationCode,
1074
+ email,
1075
+ disabled: isVerifying
1076
+ }
1077
+ ) }),
1030
1078
  /* @__PURE__ */ jsx(
1031
- "svg",
1079
+ AuthSubmitButton,
1032
1080
  {
1033
- style: { width: "1.5rem", height: "1.5rem", flexShrink: 0, color: "#DC2626" },
1034
- fill: "none",
1035
- strokeLinecap: "round",
1036
- strokeLinejoin: "round",
1037
- strokeWidth: "2",
1038
- viewBox: "0 0 24 24",
1039
- stroke: "currentColor",
1040
- children: /* @__PURE__ */ 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" })
1081
+ type: "button",
1082
+ isLoading: isVerifying,
1083
+ disabled: isVerifying || verificationCode.length !== 6,
1084
+ onClick: () => {
1085
+ void handleSubmit();
1086
+ },
1087
+ children: isVerifying ? "Verifying..." : "Verify Code"
1041
1088
  }
1042
- ),
1043
- /* @__PURE__ */ jsx("p", { className: "if-errorBanner-text", children: verificationError })
1044
- ] }) }),
1045
- method === "code" && /* @__PURE__ */ jsxs(
1046
- "div",
1047
- {
1048
- style: {
1049
- width: "100%",
1050
- backgroundColor: "#F5F5F5",
1051
- borderRadius: "0.5rem",
1052
- padding: "1rem 1rem 1.5rem",
1053
- display: "flex",
1054
- flexDirection: "column",
1055
- gap: "1rem"
1056
- },
1057
- children: [
1058
- /* @__PURE__ */ jsx(
1059
- AuthVerificationCodeInput,
1060
- {
1061
- value: verificationCode,
1062
- onChange: setVerificationCode,
1063
- email,
1064
- disabled: isVerifying,
1065
- onComplete: (code) => {
1066
- void handleVerifyCode(code);
1067
- }
1068
- }
1069
- ),
1070
- isVerifying && /* @__PURE__ */ jsx(
1071
- "p",
1072
- {
1073
- style: {
1074
- fontSize: "0.875rem",
1075
- color: "#828282",
1076
- textAlign: "center",
1077
- fontFamily: "var(--if-font-family)"
1078
- },
1079
- children: "Verifying..."
1080
- }
1081
- )
1082
- ]
1083
- }
1084
- ),
1085
- /* @__PURE__ */ jsxs(
1086
- "div",
1087
- {
1088
- style: {
1089
- width: "100%",
1090
- fontSize: "0.875rem",
1091
- textAlign: "center",
1092
- color: "#828282",
1093
- fontFamily: "var(--if-font-family)"
1094
- },
1095
- children: [
1096
- "Didn't receive the email?",
1097
- " ",
1098
- /* @__PURE__ */ jsx(
1099
- "button",
1100
- {
1101
- onClick: () => {
1102
- void handleResend();
1103
- },
1104
- disabled: resendDisabled || isSending,
1105
- style: {
1106
- color: "#000",
1107
- fontWeight: 500,
1108
- transition: "all 0.2s",
1109
- cursor: resendDisabled || isSending ? "not-allowed" : "pointer",
1110
- background: "none",
1111
- border: "none",
1112
- padding: 0,
1113
- textDecoration: resendDisabled || isSending ? "none" : "underline",
1114
- opacity: resendDisabled || isSending ? 0.5 : 1,
1115
- fontFamily: "var(--if-font-family)"
1116
- },
1117
- children: isSending ? "Sending..." : resendDisabled ? `Retry in (${resendCountdown}s)` : "Click to resend"
1118
- }
1119
- )
1120
- ]
1121
- }
1122
- )
1089
+ )
1090
+ ] }),
1091
+ /* @__PURE__ */ jsxs("div", { className: "if-verificationStep-resendContainer", children: [
1092
+ "Didn't receive the email?",
1093
+ " ",
1094
+ /* @__PURE__ */ jsx(
1095
+ "button",
1096
+ {
1097
+ onClick: () => {
1098
+ void handleResend();
1099
+ },
1100
+ disabled: resendDisabled || isSending,
1101
+ className: "if-verificationStep-resendButton",
1102
+ children: isSending ? "Sending..." : resendDisabled ? `Retry in (${resendCountdown}s)` : "Click to resend"
1103
+ }
1104
+ )
1105
+ ] })
1106
+ ] });
1107
+ }
1108
+ function AuthResetPasswordVerificationStep({
1109
+ email,
1110
+ method,
1111
+ onVerifyCode,
1112
+ onResendEmail
1113
+ }) {
1114
+ const [resendDisabled, setResendDisabled] = useState(true);
1115
+ const [resendCountdown, setResendCountdown] = useState(60);
1116
+ const [isSending, setIsSending] = useState(false);
1117
+ const [verificationCode, setVerificationCode] = useState("");
1118
+ const [isVerifying, setIsVerifying] = useState(false);
1119
+ useEffect(() => {
1120
+ if (resendCountdown > 0) {
1121
+ const timer = setInterval(() => {
1122
+ setResendCountdown((prev) => {
1123
+ if (prev <= 1) {
1124
+ setResendDisabled(false);
1125
+ return 0;
1126
+ }
1127
+ return prev - 1;
1128
+ });
1129
+ }, 1e3);
1130
+ return () => clearInterval(timer);
1131
+ }
1132
+ }, [resendCountdown]);
1133
+ const handleResend = useCallback(async () => {
1134
+ setResendDisabled(true);
1135
+ setResendCountdown(60);
1136
+ setIsSending(true);
1137
+ try {
1138
+ await onResendEmail();
1139
+ } catch {
1140
+ setResendDisabled(false);
1141
+ setResendCountdown(0);
1142
+ } finally {
1143
+ setIsSending(false);
1144
+ }
1145
+ }, [onResendEmail]);
1146
+ const handleSubmit = async () => {
1147
+ if (!onVerifyCode || verificationCode.length !== 6) {
1148
+ return;
1149
+ }
1150
+ setIsVerifying(true);
1151
+ try {
1152
+ await onVerifyCode(verificationCode);
1153
+ } finally {
1154
+ setIsVerifying(false);
1155
+ setVerificationCode("");
1156
+ }
1157
+ };
1158
+ const isLinkMethod = method === "link";
1159
+ 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.`;
1160
+ return /* @__PURE__ */ jsxs("div", { className: "if-verificationStep", children: [
1161
+ /* @__PURE__ */ jsx("p", { className: "if-verificationStep-description", children: description }),
1162
+ !isLinkMethod && /* @__PURE__ */ jsxs("div", { className: "if-verificationStep-codeContainer", children: [
1163
+ /* @__PURE__ */ jsx("div", { className: "if-verificationStep-codeInputWrapper", children: /* @__PURE__ */ jsx(
1164
+ AuthVerificationCodeInput,
1165
+ {
1166
+ value: verificationCode,
1167
+ onChange: setVerificationCode,
1168
+ email,
1169
+ disabled: isVerifying
1170
+ }
1171
+ ) }),
1172
+ /* @__PURE__ */ jsx(
1173
+ AuthSubmitButton,
1174
+ {
1175
+ type: "button",
1176
+ isLoading: isVerifying,
1177
+ disabled: isVerifying || verificationCode.length !== 6,
1178
+ onClick: () => {
1179
+ void handleSubmit();
1180
+ },
1181
+ children: isVerifying ? "Verifying..." : "Continue"
1182
+ }
1183
+ )
1184
+ ] }),
1185
+ /* @__PURE__ */ jsxs("div", { className: "if-verificationStep-resendContainer", children: [
1186
+ "Didn't receive the email?",
1187
+ " ",
1188
+ /* @__PURE__ */ jsx(
1189
+ "button",
1190
+ {
1191
+ onClick: () => {
1192
+ void handleResend();
1193
+ },
1194
+ disabled: resendDisabled || isSending,
1195
+ className: "if-verificationStep-resendButton",
1196
+ children: isSending ? "Sending..." : resendDisabled ? `Retry in (${resendCountdown}s)` : "Click to resend"
1197
+ }
1198
+ )
1199
+ ] })
1123
1200
  ] });
1124
1201
  }
1125
1202
  function SignInForm({
@@ -1149,8 +1226,7 @@ function SignInForm({
1149
1226
  signUpUrl = "/sign-up",
1150
1227
  dividerText = "or",
1151
1228
  showVerificationStep = false,
1152
- onVerifyCode,
1153
- verificationDescription
1229
+ onVerifyCode
1154
1230
  }) {
1155
1231
  return /* @__PURE__ */ jsxs(AuthContainer, { children: [
1156
1232
  /* @__PURE__ */ jsx(
@@ -1161,14 +1237,7 @@ function SignInForm({
1161
1237
  }
1162
1238
  ),
1163
1239
  /* @__PURE__ */ jsx(AuthErrorBanner, { error: error || "" }),
1164
- showVerificationStep ? /* @__PURE__ */ jsx(
1165
- AuthEmailVerificationStep,
1166
- {
1167
- email,
1168
- description: verificationDescription,
1169
- onVerifyCode
1170
- }
1171
- ) : /* @__PURE__ */ jsxs("form", { onSubmit, noValidate: true, className: "if-form if-internal-fm9k2p", children: [
1240
+ showVerificationStep ? /* @__PURE__ */ jsx(AuthEmailVerificationStep, { email, onVerifyCode }) : /* @__PURE__ */ jsxs("form", { onSubmit, noValidate: true, className: "if-form if-internal-fm9k2p", children: [
1172
1241
  /* @__PURE__ */ jsx(
1173
1242
  AuthFormField,
1174
1243
  {
@@ -1218,16 +1287,17 @@ function SignInForm({
1218
1287
  ] })
1219
1288
  ] });
1220
1289
  }
1221
- function SignIn({ afterSignInUrl, onSuccess, onError, ...uiProps }) {
1222
- const { signIn, baseUrl } = useInsforge();
1290
+ function SignIn({ onError, ...uiProps }) {
1291
+ const { signIn, verifyEmail, loginWithOAuth } = useInsforge();
1223
1292
  const { authConfig } = usePublicAuthConfig();
1224
1293
  const [email, setEmail] = useState("");
1225
1294
  const [password, setPassword] = useState("");
1226
1295
  const [error, setError] = useState("");
1227
1296
  const [loading, setLoading] = useState(false);
1228
1297
  const [step, setStep] = useState("form");
1229
- const [oauthLoading, setOauthLoading] = useState(null);
1230
- const [insforge] = useState(() => createClient({ baseUrl }));
1298
+ const [oauthLoading] = useState(null);
1299
+ const [searchParams] = useSearchParams();
1300
+ const redirectUrl = searchParams.get("redirect");
1231
1301
  async function handleSubmit(e) {
1232
1302
  e.preventDefault();
1233
1303
  setLoading(true);
@@ -1243,10 +1313,13 @@ function SignIn({ afterSignInUrl, onSuccess, onError, ...uiProps }) {
1243
1313
  throw new Error(result.error);
1244
1314
  }
1245
1315
  const { user, accessToken, redirectTo } = result;
1246
- if (onSuccess) {
1247
- if (user) {
1248
- onSuccess(user, accessToken || "", redirectTo);
1249
- }
1316
+ if (user) {
1317
+ const finalUrl = new URL(redirectTo || redirectUrl || "", window.location.origin);
1318
+ finalUrl.searchParams.set("access_token", accessToken);
1319
+ finalUrl.searchParams.set("user_id", user.id);
1320
+ finalUrl.searchParams.set("email", user.email);
1321
+ finalUrl.searchParams.set("name", user.name);
1322
+ window.location.href = finalUrl.toString();
1250
1323
  }
1251
1324
  } catch (err) {
1252
1325
  const errorMessage = err instanceof Error ? err.message : "Sign in failed";
@@ -1259,38 +1332,28 @@ function SignIn({ afterSignInUrl, onSuccess, onError, ...uiProps }) {
1259
1332
  }
1260
1333
  }
1261
1334
  async function handleVerifyCode(code) {
1335
+ setError("");
1262
1336
  try {
1263
- const result = await insforge.auth.verifyEmail({ email, otp: code });
1264
- if (result.error) {
1337
+ const result = await verifyEmail(email, code);
1338
+ if (result?.error) {
1265
1339
  throw new Error(result.error.message || "Verification failed");
1266
1340
  }
1267
- if (result.data?.accessToken) {
1268
- if (onSuccess && result.data.user) {
1269
- onSuccess(result.data.user, result.data.accessToken);
1270
- }
1341
+ if (result?.user) {
1342
+ const finalUrl = new URL(result.redirectTo || redirectUrl || "", window.location.origin);
1343
+ finalUrl.searchParams.set("access_token", result.accessToken);
1344
+ finalUrl.searchParams.set("user_id", result.user.id);
1345
+ finalUrl.searchParams.set("email", result.user.email);
1346
+ finalUrl.searchParams.set("name", result.user.name);
1347
+ window.location.href = finalUrl.toString();
1271
1348
  }
1272
1349
  } catch (err) {
1273
1350
  const errorMessage = err instanceof Error ? err.message : "Invalid verification code";
1274
- throw new Error(errorMessage);
1275
- }
1276
- }
1277
- async function handleOAuth(provider) {
1278
- try {
1279
- setOauthLoading(provider);
1280
- setError("");
1281
- await insforge.auth.signInWithOAuth({
1282
- provider,
1283
- redirectTo: afterSignInUrl
1284
- });
1285
- } catch (err) {
1286
- const errorMessage = err instanceof Error ? err.message : `${provider} sign in failed`;
1287
1351
  setError(errorMessage);
1288
- if (onError) {
1289
- onError(new Error(errorMessage));
1290
- }
1291
- setOauthLoading(null);
1292
1352
  }
1293
1353
  }
1354
+ function handleOAuth(provider) {
1355
+ loginWithOAuth(provider, redirectUrl || "");
1356
+ }
1294
1357
  if (!authConfig) {
1295
1358
  return null;
1296
1359
  }
@@ -1339,8 +1402,7 @@ function SignUpForm({
1339
1402
  signInUrl = "/sign-in",
1340
1403
  dividerText = "or",
1341
1404
  showVerificationStep = false,
1342
- onVerifyCode,
1343
- verificationDescription
1405
+ onVerifyCode
1344
1406
  }) {
1345
1407
  return /* @__PURE__ */ jsxs(AuthContainer, { children: [
1346
1408
  /* @__PURE__ */ jsx(
@@ -1351,14 +1413,7 @@ function SignUpForm({
1351
1413
  }
1352
1414
  ),
1353
1415
  /* @__PURE__ */ jsx(AuthErrorBanner, { error: error || "" }),
1354
- showVerificationStep ? /* @__PURE__ */ jsx(
1355
- AuthEmailVerificationStep,
1356
- {
1357
- email,
1358
- description: verificationDescription,
1359
- onVerifyCode
1360
- }
1361
- ) : /* @__PURE__ */ jsxs("form", { onSubmit, noValidate: true, className: "if-form if-internal-fm9k2p", children: [
1416
+ showVerificationStep ? /* @__PURE__ */ jsx(AuthEmailVerificationStep, { email, onVerifyCode }) : /* @__PURE__ */ jsxs("form", { onSubmit, noValidate: true, className: "if-form if-internal-fm9k2p", children: [
1362
1417
  /* @__PURE__ */ jsx(
1363
1418
  AuthFormField,
1364
1419
  {
@@ -1477,16 +1532,17 @@ function checkPasswordStrength(password) {
1477
1532
  }
1478
1533
  return { score, feedback };
1479
1534
  }
1480
- function SignUp({ afterSignUpUrl, onSuccess, onError, ...uiProps }) {
1481
- const { signUp, baseUrl } = useInsforge();
1535
+ function SignUp({ onError, ...uiProps }) {
1536
+ const { signUp, verifyEmail, loginWithOAuth } = useInsforge();
1482
1537
  const { authConfig } = usePublicAuthConfig();
1483
1538
  const [email, setEmail] = useState("");
1484
1539
  const [password, setPassword] = useState("");
1485
1540
  const [error, setError] = useState("");
1486
1541
  const [loading, setLoading] = useState(false);
1487
1542
  const [step, setStep] = useState("form");
1488
- const [oauthLoading, setOauthLoading] = useState(null);
1489
- const [insforge] = useState(() => createClient({ baseUrl }));
1543
+ const [oauthLoading] = useState(null);
1544
+ const [searchParams] = useSearchParams();
1545
+ const redirectUrl = searchParams.get("redirect");
1490
1546
  async function handleSubmit(e) {
1491
1547
  e.preventDefault();
1492
1548
  setLoading(true);
@@ -1528,9 +1584,12 @@ function SignUp({ afterSignUpUrl, onSuccess, onError, ...uiProps }) {
1528
1584
  return;
1529
1585
  }
1530
1586
  if (result.accessToken && result.user) {
1531
- if (onSuccess) {
1532
- onSuccess(result.user, result.accessToken, result.redirectTo);
1533
- }
1587
+ const finalUrl = new URL(result.redirectTo || redirectUrl || "", window.location.origin);
1588
+ finalUrl.searchParams.set("access_token", result.accessToken);
1589
+ finalUrl.searchParams.set("user_id", result.user.id);
1590
+ finalUrl.searchParams.set("email", result.user.email);
1591
+ finalUrl.searchParams.set("name", result.user.name);
1592
+ window.location.href = finalUrl.toString();
1534
1593
  }
1535
1594
  } catch (err) {
1536
1595
  const errorMessage = err instanceof Error ? err.message : "Sign up failed";
@@ -1543,38 +1602,28 @@ function SignUp({ afterSignUpUrl, onSuccess, onError, ...uiProps }) {
1543
1602
  }
1544
1603
  }
1545
1604
  async function handleVerifyCode(code) {
1605
+ setError("");
1546
1606
  try {
1547
- const result = await insforge.auth.verifyEmail({ email, otp: code });
1548
- if (result.error) {
1607
+ const result = await verifyEmail(email, code);
1608
+ if (result?.error) {
1549
1609
  throw new Error(result.error.message || "Verification failed");
1550
1610
  }
1551
- if (result.data?.accessToken) {
1552
- if (onSuccess && result.data.user) {
1553
- onSuccess(result.data.user, result.data.accessToken);
1554
- }
1611
+ if (result?.user) {
1612
+ const finalUrl = new URL(result.redirectTo || redirectUrl || "", window.location.origin);
1613
+ finalUrl.searchParams.set("access_token", result.accessToken);
1614
+ finalUrl.searchParams.set("user_id", result.user.id);
1615
+ finalUrl.searchParams.set("email", result.user.email);
1616
+ finalUrl.searchParams.set("name", result.user.name);
1617
+ window.location.href = finalUrl.toString();
1555
1618
  }
1556
1619
  } catch (err) {
1557
1620
  const errorMessage = err instanceof Error ? err.message : "Invalid verification code";
1558
- throw new Error(errorMessage);
1559
- }
1560
- }
1561
- async function handleOAuth(provider) {
1562
- try {
1563
- setOauthLoading(provider);
1564
- setError("");
1565
- await insforge.auth.signInWithOAuth({
1566
- provider,
1567
- redirectTo: afterSignUpUrl
1568
- });
1569
- } catch (err) {
1570
- const errorMessage = err instanceof Error ? err.message : `${provider} sign up failed`;
1571
1621
  setError(errorMessage);
1572
- if (onError) {
1573
- onError(new Error(errorMessage));
1574
- }
1575
- setOauthLoading(null);
1576
1622
  }
1577
1623
  }
1624
+ function handleOAuth(provider) {
1625
+ loginWithOAuth(provider, redirectUrl || "");
1626
+ }
1578
1627
  if (!authConfig) {
1579
1628
  return null;
1580
1629
  }
@@ -1604,7 +1653,6 @@ function ForgotPasswordForm({
1604
1653
  onSubmit,
1605
1654
  error,
1606
1655
  loading = false,
1607
- success = false,
1608
1656
  title = "Forgot Password?",
1609
1657
  subtitle = "Enter your email address and we'll send you a code to reset your password.",
1610
1658
  emailLabel = "Email",
@@ -1613,53 +1661,30 @@ function ForgotPasswordForm({
1613
1661
  loadingButtonText = "Sending...",
1614
1662
  backToSignInText = "Remember your password?",
1615
1663
  backToSignInUrl = "/sign-in",
1616
- successTitle = "Check Your Email",
1617
- successMessage
1664
+ showVerificationStep = false,
1665
+ resetPasswordMethod = "code",
1666
+ onVerifyCode,
1667
+ onResendEmail
1618
1668
  }) {
1619
- if (success) {
1620
- return /* @__PURE__ */ jsx(AuthContainer, { children: /* @__PURE__ */ jsxs(
1621
- "div",
1669
+ return /* @__PURE__ */ jsxs(AuthContainer, { children: [
1670
+ /* @__PURE__ */ jsx(
1671
+ AuthHeader,
1622
1672
  {
1623
- style: { display: "flex", flexDirection: "column", alignItems: "center", gap: "1rem" },
1624
- children: [
1625
- /* @__PURE__ */ jsx(
1626
- "div",
1627
- {
1628
- style: {
1629
- width: "4rem",
1630
- height: "4rem",
1631
- borderRadius: "50%",
1632
- backgroundColor: "#D1FAE5",
1633
- display: "flex",
1634
- alignItems: "center",
1635
- justifyContent: "center"
1636
- },
1637
- children: /* @__PURE__ */ jsx(
1638
- "svg",
1639
- {
1640
- style: { width: "2rem", height: "2rem", color: "#059669" },
1641
- fill: "none",
1642
- strokeLinecap: "round",
1643
- strokeLinejoin: "round",
1644
- strokeWidth: "2",
1645
- viewBox: "0 0 24 24",
1646
- stroke: "currentColor",
1647
- children: /* @__PURE__ */ jsx("path", { d: "M5 13l4 4L19 7" })
1648
- }
1649
- )
1650
- }
1651
- ),
1652
- /* @__PURE__ */ jsx("h2", { className: "if-authHeader-title", style: { textAlign: "center" }, children: successTitle }),
1653
- /* @__PURE__ */ 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.` }),
1654
- /* @__PURE__ */ jsx("a", { href: backToSignInUrl, className: "if-authLink-link", style: { marginTop: "1rem" }, children: "Back to Sign In" })
1655
- ]
1673
+ title: showVerificationStep ? resetPasswordMethod === "link" ? "Check Your Email" : "Enter Reset Code" : title,
1674
+ subtitle: showVerificationStep ? "" : subtitle
1656
1675
  }
1657
- ) });
1658
- }
1659
- return /* @__PURE__ */ jsxs(AuthContainer, { children: [
1660
- /* @__PURE__ */ jsx(AuthHeader, { title, subtitle }),
1676
+ ),
1661
1677
  /* @__PURE__ */ jsx(AuthErrorBanner, { error: error || "" }),
1662
- /* @__PURE__ */ jsxs("form", { onSubmit, noValidate: true, className: "if-form if-internal-fm9k2p", children: [
1678
+ showVerificationStep ? /* @__PURE__ */ jsx(
1679
+ AuthResetPasswordVerificationStep,
1680
+ {
1681
+ email,
1682
+ method: resetPasswordMethod,
1683
+ onVerifyCode,
1684
+ onResendEmail: onResendEmail || (async () => {
1685
+ })
1686
+ }
1687
+ ) : /* @__PURE__ */ jsxs("form", { onSubmit, noValidate: true, className: "if-form if-internal-fm9k2p", children: [
1663
1688
  /* @__PURE__ */ jsx(
1664
1689
  AuthFormField,
1665
1690
  {
@@ -1675,7 +1700,7 @@ function ForgotPasswordForm({
1675
1700
  ),
1676
1701
  /* @__PURE__ */ jsx(AuthSubmitButton, { isLoading: loading, disabled: loading, children: loading ? loadingButtonText : submitButtonText })
1677
1702
  ] }),
1678
- /* @__PURE__ */ jsx(AuthLink, { text: backToSignInText, linkText: "Back to Sign In", href: backToSignInUrl })
1703
+ !showVerificationStep && /* @__PURE__ */ jsx(AuthLink, { text: backToSignInText, linkText: "Back to Sign In", href: backToSignInUrl })
1679
1704
  ] });
1680
1705
  }
1681
1706
  function ResetPasswordForm({
@@ -1696,11 +1721,12 @@ function ResetPasswordForm({
1696
1721
  confirmPasswordPlaceholder = "\u2022\u2022\u2022\u2022\u2022\u2022",
1697
1722
  submitButtonText = "Reset Password",
1698
1723
  loadingButtonText = "Resetting...",
1699
- backToSignInText = "",
1700
- backToSignInUrl = "/sign-in",
1701
- successTitle = "Password Reset Successful!",
1702
- successMessage = "Your password has been successfully reset. You can now sign in with your new password."
1724
+ successTitle = "Password Reset Successful!"
1703
1725
  }) {
1726
+ let successMessage = "Your password has been successfully reset. You can close this page and sign in with your new password.";
1727
+ if (authConfig && authConfig.verifyEmailMethod === "code") {
1728
+ successMessage = "Your password has been successfully reset. You can wait for redirect to sign in with your new password.";
1729
+ }
1704
1730
  if (success) {
1705
1731
  return /* @__PURE__ */ jsx(AuthContainer, { children: /* @__PURE__ */ jsxs(
1706
1732
  "div",
@@ -1735,8 +1761,7 @@ function ResetPasswordForm({
1735
1761
  }
1736
1762
  ),
1737
1763
  /* @__PURE__ */ jsx("h2", { className: "if-authHeader-title", style: { textAlign: "center" }, children: successTitle }),
1738
- /* @__PURE__ */ jsx("p", { className: "if-authHeader-subtitle", style: { textAlign: "center" }, children: successMessage }),
1739
- /* @__PURE__ */ jsx("a", { href: backToSignInUrl, className: "if-authLink-link", style: { marginTop: "1rem" }, children: "Back to Sign In" })
1764
+ /* @__PURE__ */ jsx("p", { className: "if-authHeader-subtitle", style: { textAlign: "center" }, children: successMessage })
1740
1765
  ]
1741
1766
  }
1742
1767
  ) });
@@ -1773,40 +1798,87 @@ function ResetPasswordForm({
1773
1798
  }
1774
1799
  ),
1775
1800
  /* @__PURE__ */ jsx(AuthSubmitButton, { isLoading: loading, disabled: loading, children: loading ? loadingButtonText : submitButtonText })
1776
- ] }),
1777
- /* @__PURE__ */ jsx(AuthLink, { text: backToSignInText, linkText: "Back to Sign In", href: backToSignInUrl })
1801
+ ] })
1778
1802
  ] });
1779
1803
  }
1780
- function ResetPassword({
1781
- token,
1782
- backToSignInUrl = "/sign-in",
1783
- onSuccess,
1784
- onError,
1785
- ...uiProps
1786
- }) {
1787
- const { resetPassword } = useInsforge();
1804
+ function ForgotPassword({ onError, ...uiProps }) {
1805
+ const { sendResetPasswordEmail, exchangeResetPasswordToken, resetPassword } = useInsforge();
1788
1806
  const { authConfig } = usePublicAuthConfig();
1807
+ const [searchParams] = useSearchParams();
1808
+ const [step, setStep] = useState("email");
1809
+ const [email, setEmail] = useState("");
1810
+ const [resetToken, setResetToken] = useState("");
1789
1811
  const [newPassword, setNewPassword] = useState("");
1790
1812
  const [confirmPassword, setConfirmPassword] = useState("");
1791
1813
  const [error, setError] = useState("");
1792
1814
  const [loading, setLoading] = useState(false);
1793
1815
  const [success, setSuccess] = useState(false);
1794
- async function handleSubmit(e) {
1816
+ const [showVerificationStep, setShowVerificationStep] = useState(false);
1817
+ async function handleEmailSubmit(e) {
1795
1818
  e.preventDefault();
1796
1819
  setLoading(true);
1797
1820
  setError("");
1798
- if (!authConfig) {
1799
- setError("Configuration not loaded. Please refresh the page.");
1821
+ const emailValidation = emailSchema.safeParse(email);
1822
+ if (!emailValidation.success) {
1823
+ const firstError = emailValidation.error.issues[0];
1824
+ setError(firstError.message);
1800
1825
  setLoading(false);
1801
1826
  return;
1802
1827
  }
1828
+ try {
1829
+ const result = await sendResetPasswordEmail(emailValidation.data);
1830
+ if (result?.success) {
1831
+ setShowVerificationStep(true);
1832
+ } else {
1833
+ const errorMessage = result?.message || "Failed to send reset email";
1834
+ setError(errorMessage);
1835
+ if (onError) {
1836
+ onError(new Error(errorMessage));
1837
+ }
1838
+ }
1839
+ } catch (err) {
1840
+ const errorMessage = err instanceof Error ? err.message : "Failed to send reset email";
1841
+ setError(errorMessage);
1842
+ if (onError) {
1843
+ onError(new Error(errorMessage));
1844
+ }
1845
+ } finally {
1846
+ setLoading(false);
1847
+ }
1848
+ }
1849
+ async function handleVerifyCode(code) {
1850
+ setError("");
1851
+ try {
1852
+ const result = await exchangeResetPasswordToken(email, code);
1853
+ if ("error" in result) {
1854
+ throw new Error(result.error.message || "Failed to verify code");
1855
+ }
1856
+ if (result.token) {
1857
+ setResetToken(result.token);
1858
+ setStep("password");
1859
+ }
1860
+ } catch (err) {
1861
+ const errorMessage = err instanceof Error ? err.message : "Invalid verification code";
1862
+ setError(errorMessage);
1863
+ if (onError) {
1864
+ onError(new Error(errorMessage));
1865
+ }
1866
+ }
1867
+ }
1868
+ async function handleResendEmail() {
1869
+ await sendResetPasswordEmail(email);
1870
+ }
1871
+ async function handleResetPasswordSubmit(e) {
1872
+ e.preventDefault();
1873
+ setLoading(true);
1874
+ setError("");
1803
1875
  if (newPassword !== confirmPassword) {
1804
1876
  setError("Passwords do not match");
1805
1877
  setLoading(false);
1806
1878
  return;
1807
1879
  }
1808
- if (!token) {
1809
- setError("Reset token is missing");
1880
+ if (!authConfig) {
1881
+ setError("Configuration not loaded");
1810
1882
  setLoading(false);
1811
1883
  return;
1812
1884
  }
@@ -1825,12 +1897,16 @@ function ResetPassword({
1825
1897
  return;
1826
1898
  }
1827
1899
  try {
1828
- const result = await resetPassword(token, newPassword);
1900
+ const result = await resetPassword(resetToken, newPassword);
1829
1901
  if (result?.message) {
1830
1902
  setSuccess(true);
1831
- if (onSuccess) {
1832
- onSuccess();
1833
- }
1903
+ const signInUrl = new URL("/sign-in", window.location.origin);
1904
+ searchParams.forEach((value, key) => {
1905
+ signInUrl.searchParams.set(key, value);
1906
+ });
1907
+ setTimeout(() => {
1908
+ window.location.href = signInUrl.toString();
1909
+ }, 2e3);
1834
1910
  } else {
1835
1911
  const errorMessage = "Failed to reset password";
1836
1912
  setError(errorMessage);
@@ -1851,6 +1927,25 @@ function ResetPassword({
1851
1927
  if (!authConfig) {
1852
1928
  return null;
1853
1929
  }
1930
+ if (step === "email") {
1931
+ return /* @__PURE__ */ jsx(
1932
+ ForgotPasswordForm,
1933
+ {
1934
+ email,
1935
+ onEmailChange: setEmail,
1936
+ onSubmit: (e) => {
1937
+ void handleEmailSubmit(e);
1938
+ },
1939
+ error,
1940
+ loading,
1941
+ showVerificationStep,
1942
+ resetPasswordMethod: authConfig.resetPasswordMethod,
1943
+ onVerifyCode: handleVerifyCode,
1944
+ onResendEmail: handleResendEmail,
1945
+ ...uiProps
1946
+ }
1947
+ );
1948
+ }
1854
1949
  return /* @__PURE__ */ jsx(
1855
1950
  ResetPasswordForm,
1856
1951
  {
@@ -1858,83 +1953,71 @@ function ResetPassword({
1858
1953
  confirmPassword,
1859
1954
  onNewPasswordChange: setNewPassword,
1860
1955
  onConfirmPasswordChange: setConfirmPassword,
1861
- onSubmit: handleSubmit,
1956
+ onSubmit: handleResetPasswordSubmit,
1862
1957
  error,
1863
1958
  loading,
1864
1959
  success,
1865
1960
  authConfig,
1866
- backToSignInUrl,
1867
1961
  ...uiProps
1868
1962
  }
1869
1963
  );
1870
1964
  }
1871
- function ForgotPassword({
1872
- backToSignInUrl = "/sign-in",
1873
- onSuccess,
1874
- onError,
1875
- ...uiProps
1876
- }) {
1877
- const { sendResetPasswordEmail, baseUrl } = useInsforge();
1965
+ function ResetPassword({ onError, ...uiProps }) {
1966
+ const [searchParams] = useSearchParams();
1967
+ const token = searchParams.get("token");
1968
+ const { resetPassword } = useInsforge();
1878
1969
  const { authConfig } = usePublicAuthConfig();
1879
- const [insforge] = useState(() => createClient({ baseUrl }));
1880
- const [step, setStep] = useState("email");
1881
- const [email, setEmail] = useState("");
1882
- const [verificationCode, setVerificationCode] = useState("");
1883
- const [resetToken, setResetToken] = useState("");
1970
+ const [newPassword, setNewPassword] = useState("");
1971
+ const [confirmPassword, setConfirmPassword] = useState("");
1884
1972
  const [error, setError] = useState("");
1885
1973
  const [loading, setLoading] = useState(false);
1886
1974
  const [success, setSuccess] = useState(false);
1887
- const [resendDisabled, setResendDisabled] = useState(true);
1888
- const [resendCountdown, setResendCountdown] = useState(60);
1889
- const [isSendingCode, setIsSendingCode] = useState(false);
1890
- const [isVerifyingCode, setIsVerifyingCode] = useState(false);
1891
- useEffect(() => {
1892
- if (resendCountdown > 0 && step === "code") {
1893
- const timer = setInterval(() => {
1894
- setResendCountdown((prev) => {
1895
- if (prev <= 1) {
1896
- setResendDisabled(false);
1897
- return 0;
1898
- }
1899
- return prev - 1;
1900
- });
1901
- }, 1e3);
1902
- return () => clearInterval(timer);
1903
- }
1904
- }, [resendCountdown, step]);
1905
- async function handleEmailSubmit(e) {
1975
+ async function handleSubmit(e) {
1906
1976
  e.preventDefault();
1907
1977
  setLoading(true);
1908
1978
  setError("");
1909
- const emailValidation = emailSchema.safeParse(email);
1910
- if (!emailValidation.success) {
1911
- const firstError = emailValidation.error.issues[0];
1979
+ if (!authConfig) {
1980
+ setError("Configuration not loaded. Please refresh the page.");
1981
+ setLoading(false);
1982
+ return;
1983
+ }
1984
+ if (newPassword !== confirmPassword) {
1985
+ setError("Passwords do not match");
1986
+ setLoading(false);
1987
+ return;
1988
+ }
1989
+ if (!token) {
1990
+ setError("Reset token is missing");
1991
+ setLoading(false);
1992
+ return;
1993
+ }
1994
+ const passwordZodSchema = createPasswordSchema({
1995
+ minLength: authConfig.passwordMinLength,
1996
+ requireUppercase: authConfig.requireUppercase,
1997
+ requireLowercase: authConfig.requireLowercase,
1998
+ requireNumber: authConfig.requireNumber,
1999
+ requireSpecialChar: authConfig.requireSpecialChar
2000
+ });
2001
+ const passwordValidation = passwordZodSchema.safeParse(newPassword);
2002
+ if (!passwordValidation.success) {
2003
+ const firstError = passwordValidation.error.issues[0];
1912
2004
  setError(firstError.message);
1913
2005
  setLoading(false);
1914
2006
  return;
1915
2007
  }
1916
2008
  try {
1917
- const result = await sendResetPasswordEmail(emailValidation.data);
1918
- if (result?.success) {
1919
- if (authConfig?.resetPasswordMethod === "link") {
1920
- setSuccess(true);
1921
- if (onSuccess) {
1922
- onSuccess();
1923
- }
1924
- } else {
1925
- setStep("code");
1926
- setResendDisabled(true);
1927
- setResendCountdown(60);
1928
- }
2009
+ const result = await resetPassword(token, newPassword);
2010
+ if (result?.message) {
2011
+ setSuccess(true);
1929
2012
  } else {
1930
- const errorMessage = result?.message || "Failed to send reset code";
2013
+ const errorMessage = "Failed to reset password";
1931
2014
  setError(errorMessage);
1932
2015
  if (onError) {
1933
2016
  onError(new Error(errorMessage));
1934
2017
  }
1935
2018
  }
1936
2019
  } catch (err) {
1937
- const errorMessage = err instanceof Error ? err.message : "Failed to send reset code";
2020
+ const errorMessage = err instanceof Error ? err.message : "Failed to reset password";
1938
2021
  setError(errorMessage);
1939
2022
  if (onError) {
1940
2023
  onError(new Error(errorMessage));
@@ -1943,297 +2026,157 @@ function ForgotPassword({
1943
2026
  setLoading(false);
1944
2027
  }
1945
2028
  }
1946
- async function handleVerifyCode(code) {
1947
- setIsVerifyingCode(true);
1948
- setError("");
1949
- setVerificationCode(code);
1950
- try {
1951
- const result = await insforge.auth.exchangeResetPasswordToken({ email, code });
1952
- if (result.error) {
1953
- throw new Error(result.error.message || "Failed to verify code");
1954
- }
1955
- if (result.data) {
1956
- setResetToken(result.data.token);
1957
- setStep("password");
1958
- }
1959
- } catch (err) {
1960
- const errorMessage = err instanceof Error ? err.message : "Invalid verification code";
1961
- setError(errorMessage);
1962
- setVerificationCode("");
1963
- } finally {
1964
- setIsVerifyingCode(false);
1965
- }
1966
- }
1967
- const handleResendCode = useCallback(async () => {
1968
- setResendDisabled(true);
1969
- setResendCountdown(60);
1970
- setIsSendingCode(true);
1971
- setError("");
1972
- try {
1973
- await sendResetPasswordEmail(email);
1974
- } catch (err) {
1975
- const errorMessage = err instanceof Error ? err.message : "Failed to resend code";
1976
- setError(errorMessage);
1977
- setResendDisabled(false);
1978
- setResendCountdown(0);
1979
- } finally {
1980
- setIsSendingCode(false);
1981
- }
1982
- }, [email, sendResetPasswordEmail]);
1983
- function handlePasswordResetSuccess(redirectTo) {
1984
- const targetUrl = redirectTo || backToSignInUrl;
1985
- if (onSuccess) {
1986
- onSuccess();
1987
- }
1988
- setTimeout(() => {
1989
- window.location.href = targetUrl;
1990
- }, 1500);
1991
- }
1992
2029
  if (!authConfig) {
1993
2030
  return null;
1994
2031
  }
1995
- if (step === "email") {
1996
- return /* @__PURE__ */ jsx(
1997
- ForgotPasswordForm,
1998
- {
1999
- email,
2000
- onEmailChange: setEmail,
2001
- onSubmit: (e) => {
2002
- void handleEmailSubmit(e);
2003
- },
2004
- error,
2005
- loading,
2006
- success,
2007
- backToSignInUrl,
2008
- ...uiProps
2009
- }
2010
- );
2011
- }
2012
- if (step === "code") {
2032
+ if (!token) {
2013
2033
  return /* @__PURE__ */ jsxs(AuthContainer, { children: [
2034
+ /* @__PURE__ */ jsx(AuthHeader, { title: "Invalid Reset Link", subtitle: "" }),
2014
2035
  /* @__PURE__ */ jsx(
2015
- AuthHeader,
2016
- {
2017
- title: "Enter Reset Code",
2018
- 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.`
2019
- }
2020
- ),
2021
- /* @__PURE__ */ jsx(AuthErrorBanner, { error }),
2022
- /* @__PURE__ */ jsxs(
2023
2036
  "div",
2024
2037
  {
2025
2038
  style: {
2026
- width: "100%",
2027
- display: "flex",
2028
- flexDirection: "column",
2029
- gap: "1.5rem",
2030
- alignItems: "center"
2039
+ padding: "1.5rem",
2040
+ backgroundColor: "#FEE2E2",
2041
+ borderRadius: "0.5rem",
2042
+ border: "1px solid #DC2626"
2031
2043
  },
2032
- children: [
2033
- /* @__PURE__ */ jsx(
2034
- "div",
2035
- {
2036
- style: {
2037
- width: "100%",
2038
- backgroundColor: "#F5F5F5",
2039
- borderRadius: "0.5rem",
2040
- padding: "1rem 1rem 1.5rem",
2041
- display: "flex",
2042
- flexDirection: "column",
2043
- gap: "1rem"
2044
- },
2045
- children: /* @__PURE__ */ jsxs(
2046
- "div",
2047
- {
2048
- style: {
2049
- display: "flex",
2050
- flexDirection: "column",
2051
- gap: "0.75rem",
2052
- marginTop: "0.5rem"
2053
- },
2054
- children: [
2055
- /* @__PURE__ */ jsx(
2056
- AuthVerificationCodeInput,
2057
- {
2058
- value: verificationCode,
2059
- onChange: setVerificationCode,
2060
- email,
2061
- disabled: isVerifyingCode,
2062
- onComplete: (code) => {
2063
- void handleVerifyCode(code);
2064
- }
2065
- }
2066
- ),
2067
- isVerifyingCode && /* @__PURE__ */ jsx("p", { className: "if-authHeader-subtitle", style: { textAlign: "center" }, children: "Verifying..." })
2068
- ]
2069
- }
2070
- )
2071
- }
2072
- ),
2073
- /* @__PURE__ */ jsxs(
2074
- "div",
2075
- {
2076
- style: {
2077
- width: "100%",
2078
- fontSize: "0.875rem",
2079
- textAlign: "center",
2080
- color: "#828282",
2081
- fontFamily: "var(--if-font-family)"
2082
- },
2083
- children: [
2084
- "Didn't receive the email?",
2085
- " ",
2086
- /* @__PURE__ */ jsx(
2087
- "button",
2088
- {
2089
- onClick: () => {
2090
- void handleResendCode();
2091
- },
2092
- disabled: resendDisabled || isSendingCode,
2093
- style: {
2094
- color: "#000",
2095
- fontWeight: 500,
2096
- transition: "all 0.2s",
2097
- cursor: resendDisabled || isSendingCode ? "not-allowed" : "pointer",
2098
- background: "none",
2099
- border: "none",
2100
- padding: 0,
2101
- textDecoration: resendDisabled || isSendingCode ? "none" : "underline",
2102
- opacity: resendDisabled || isSendingCode ? 0.5 : 1,
2103
- fontFamily: "var(--if-font-family)"
2104
- },
2105
- children: isSendingCode ? "Sending..." : resendDisabled ? `Retry in (${resendCountdown}s)` : "Click to resend"
2106
- }
2107
- )
2108
- ]
2109
- }
2110
- )
2111
- ]
2044
+ children: /* @__PURE__ */ jsx(
2045
+ "p",
2046
+ {
2047
+ style: {
2048
+ fontSize: "0.875rem",
2049
+ color: "#DC2626",
2050
+ margin: 0,
2051
+ fontFamily: "var(--if-font-family)"
2052
+ },
2053
+ children: "The password reset link is missing or invalid. Please request a new password reset link."
2054
+ }
2055
+ )
2112
2056
  }
2113
- ),
2114
- /* @__PURE__ */ jsx("p", { className: "if-authHeader-subtitle", style: { textAlign: "center" }, children: /* @__PURE__ */ jsx("a", { href: backToSignInUrl, className: "if-authLink-link", children: "Back to Sign In" }) })
2057
+ )
2115
2058
  ] });
2116
2059
  }
2117
- return /* @__PURE__ */ jsx(
2118
- ResetPassword,
2119
- {
2120
- token: resetToken,
2121
- backToSignInUrl,
2122
- onSuccess: handlePasswordResetSuccess,
2123
- onError
2124
- }
2125
- );
2126
- }
2127
- function VerifyEmailStatus({
2128
- status,
2129
- error,
2130
- verifyingTitle = "Verifying your email...",
2131
- successTitle = "Email Verified!",
2132
- successMessage = "Your email has been verified successfully. You can close this page and return to your app.",
2133
- errorTitle = "Verification Failed"
2134
- }) {
2135
- if (status === "verifying") {
2060
+ if (success) {
2136
2061
  return /* @__PURE__ */ jsx(AuthContainer, { children: /* @__PURE__ */ jsxs(
2137
2062
  "div",
2138
2063
  {
2139
- style: {
2140
- width: "100%",
2141
- display: "flex",
2142
- flexDirection: "column",
2143
- alignItems: "center",
2144
- justifyContent: "center",
2145
- gap: "1.5rem"
2146
- },
2064
+ style: { display: "flex", flexDirection: "column", alignItems: "center", gap: "1rem" },
2147
2065
  children: [
2148
- /* @__PURE__ */ jsx("h2", { className: "if-authHeader-title", children: verifyingTitle }),
2149
2066
  /* @__PURE__ */ jsx(
2150
2067
  "div",
2151
2068
  {
2152
- className: "if-submitButton-spinner",
2153
2069
  style: {
2070
+ width: "4rem",
2071
+ height: "4rem",
2154
2072
  borderRadius: "50%",
2155
- height: "3rem",
2156
- width: "3rem",
2157
- borderBottom: "2px solid black"
2158
- }
2073
+ backgroundColor: "#D1FAE5",
2074
+ display: "flex",
2075
+ alignItems: "center",
2076
+ justifyContent: "center"
2077
+ },
2078
+ children: /* @__PURE__ */ jsx(
2079
+ "svg",
2080
+ {
2081
+ style: { width: "2rem", height: "2rem", color: "#059669" },
2082
+ fill: "none",
2083
+ strokeLinecap: "round",
2084
+ strokeLinejoin: "round",
2085
+ strokeWidth: "2",
2086
+ viewBox: "0 0 24 24",
2087
+ stroke: "currentColor",
2088
+ children: /* @__PURE__ */ jsx("path", { d: "M5 13l4 4L19 7" })
2089
+ }
2090
+ )
2091
+ }
2092
+ ),
2093
+ /* @__PURE__ */ jsx(
2094
+ "h2",
2095
+ {
2096
+ style: {
2097
+ fontSize: "1.5rem",
2098
+ fontWeight: 600,
2099
+ color: "#000",
2100
+ margin: 0,
2101
+ textAlign: "center",
2102
+ fontFamily: "var(--if-font-family)"
2103
+ },
2104
+ children: "Password Reset Successfully"
2105
+ }
2106
+ ),
2107
+ /* @__PURE__ */ jsx(
2108
+ "p",
2109
+ {
2110
+ style: {
2111
+ fontSize: "0.875rem",
2112
+ color: "#828282",
2113
+ textAlign: "center",
2114
+ margin: 0,
2115
+ fontFamily: "var(--if-font-family)"
2116
+ },
2117
+ children: "Your password has been reset successfully. You can now close this page and return to the login page in your original tab."
2159
2118
  }
2160
2119
  )
2161
2120
  ]
2162
2121
  }
2163
2122
  ) });
2164
2123
  }
2124
+ return /* @__PURE__ */ jsx(
2125
+ ResetPasswordForm,
2126
+ {
2127
+ newPassword,
2128
+ confirmPassword,
2129
+ onNewPasswordChange: setNewPassword,
2130
+ onConfirmPasswordChange: setConfirmPassword,
2131
+ onSubmit: handleSubmit,
2132
+ error,
2133
+ loading,
2134
+ success: false,
2135
+ authConfig,
2136
+ ...uiProps
2137
+ }
2138
+ );
2139
+ }
2140
+ function VerifyEmailStatus({
2141
+ status,
2142
+ error,
2143
+ verifyingTitle = "Verifying your email...",
2144
+ successTitle = "Email Verified!",
2145
+ successMessage = "Your email has been verified successfully. You can close this page and sign in to your app.",
2146
+ errorTitle = "Verification Failed"
2147
+ }) {
2148
+ if (status === "verifying") {
2149
+ return /* @__PURE__ */ jsx(AuthContainer, { children: /* @__PURE__ */ jsxs("div", { className: "if-verifyStatus-container", children: [
2150
+ /* @__PURE__ */ jsx("h2", { className: "if-authHeader-title", children: verifyingTitle }),
2151
+ /* @__PURE__ */ jsx("div", { className: "if-submitButton-spinner if-verifyStatus-spinner" })
2152
+ ] }) });
2153
+ }
2165
2154
  if (status === "error") {
2166
- return /* @__PURE__ */ jsx(AuthContainer, { children: /* @__PURE__ */ jsx(
2167
- "div",
2155
+ return /* @__PURE__ */ jsx(AuthContainer, { children: /* @__PURE__ */ jsx("div", { className: "if-verifyStatus-container-stretch", children: /* @__PURE__ */ jsxs("div", { className: "if-authHeader if-internal-h3m7w5", children: [
2156
+ /* @__PURE__ */ jsx("h1", { className: "if-authHeader-title if-internal-t4p1k9", children: errorTitle }),
2157
+ /* @__PURE__ */ jsxs("p", { className: "if-authHeader-subtitle if-internal-s7q2m3", children: [
2158
+ error || "The verification link is invalid or has expired.",
2159
+ " Please try again or contact support if the problem persists. You can close this page and return to your app."
2160
+ ] })
2161
+ ] }) }) });
2162
+ }
2163
+ return /* @__PURE__ */ jsx(AuthContainer, { children: /* @__PURE__ */ jsx("div", { className: "if-verifyStatus-container-stretch", children: /* @__PURE__ */ jsxs("div", { className: "if-verifyStatus-successContent", children: [
2164
+ /* @__PURE__ */ jsx("div", { className: "if-verifyStatus-successIcon", children: /* @__PURE__ */ jsx(
2165
+ "svg",
2168
2166
  {
2169
- style: {
2170
- width: "100%",
2171
- display: "flex",
2172
- flexDirection: "column",
2173
- alignItems: "stretch",
2174
- justifyContent: "center",
2175
- gap: "1.5rem"
2176
- },
2177
- children: /* @__PURE__ */ jsxs("div", { className: "if-authHeader if-internal-h3m7w5", children: [
2178
- /* @__PURE__ */ jsx("h1", { className: "if-authHeader-title if-internal-t4p1k9", children: errorTitle }),
2179
- /* @__PURE__ */ jsxs("p", { className: "if-authHeader-subtitle if-internal-s7q2m3", style: { lineHeight: "1.5" }, children: [
2180
- error || "The verification link is invalid or has expired.",
2181
- " Please try again or contact support if the problem persists. You can close this page and return to your app."
2182
- ] })
2183
- ] })
2167
+ className: "if-verifyStatus-successIconSvg",
2168
+ fill: "none",
2169
+ strokeLinecap: "round",
2170
+ strokeLinejoin: "round",
2171
+ strokeWidth: "2",
2172
+ viewBox: "0 0 24 24",
2173
+ stroke: "currentColor",
2174
+ children: /* @__PURE__ */ jsx("path", { d: "M5 13l4 4L19 7" })
2184
2175
  }
2185
- ) });
2186
- }
2187
- return /* @__PURE__ */ jsx(AuthContainer, { children: /* @__PURE__ */ jsx(
2188
- "div",
2189
- {
2190
- style: {
2191
- width: "100%",
2192
- display: "flex",
2193
- flexDirection: "column",
2194
- alignItems: "stretch",
2195
- justifyContent: "center",
2196
- gap: "1.5rem"
2197
- },
2198
- children: /* @__PURE__ */ jsxs(
2199
- "div",
2200
- {
2201
- style: { display: "flex", flexDirection: "column", alignItems: "center", gap: "1rem" },
2202
- children: [
2203
- /* @__PURE__ */ jsx(
2204
- "div",
2205
- {
2206
- style: {
2207
- width: "4rem",
2208
- height: "4rem",
2209
- borderRadius: "50%",
2210
- backgroundColor: "#D1FAE5",
2211
- display: "flex",
2212
- alignItems: "center",
2213
- justifyContent: "center"
2214
- },
2215
- children: /* @__PURE__ */ jsx(
2216
- "svg",
2217
- {
2218
- style: { width: "2rem", height: "2rem", color: "#059669" },
2219
- fill: "none",
2220
- strokeLinecap: "round",
2221
- strokeLinejoin: "round",
2222
- strokeWidth: "2",
2223
- viewBox: "0 0 24 24",
2224
- stroke: "currentColor",
2225
- children: /* @__PURE__ */ jsx("path", { d: "M5 13l4 4L19 7" })
2226
- }
2227
- )
2228
- }
2229
- ),
2230
- /* @__PURE__ */ jsx("h2", { className: "if-authHeader-title", style: { textAlign: "center" }, children: successTitle }),
2231
- /* @__PURE__ */ jsx("p", { className: "if-authHeader-subtitle", style: { textAlign: "center" }, children: successMessage })
2232
- ]
2233
- }
2234
- )
2235
- }
2236
- ) });
2176
+ ) }),
2177
+ /* @__PURE__ */ jsx("h2", { className: "if-authHeader-title if-verifyStatus-textCenter", children: successTitle }),
2178
+ /* @__PURE__ */ jsx("p", { className: "if-authHeader-subtitle if-verifyStatus-textCenter", children: successMessage })
2179
+ ] }) }) });
2237
2180
  }
2238
2181
  function VerifyEmail({ token, onSuccess, onError, ...uiProps }) {
2239
2182
  const { verifyEmail } = useInsforge();
@@ -2334,93 +2277,43 @@ function UserButton({ afterSignOutUrl = "/", mode = "detailed" }) {
2334
2277
  }
2335
2278
  const initials = user.name ? user.name.charAt(0).toUpperCase() : user.email.split("@")[0].slice(0, 2).toUpperCase();
2336
2279
  const buttonClassName = mode === "detailed" ? "if-userButton if-userButton-detailed" : "if-userButton";
2337
- return /* @__PURE__ */ jsxs(
2338
- "div",
2339
- {
2340
- className: "if-userButton if-internal-ub3k8p",
2341
- style: { position: "relative", display: "inline-block" },
2342
- ref: dropdownRef,
2343
- children: [
2344
- /* @__PURE__ */ jsxs(
2345
- "button",
2346
- {
2347
- className: buttonClassName,
2348
- style: {
2349
- display: "flex",
2350
- alignItems: "center",
2351
- justifyContent: "center",
2352
- gap: "0.5rem",
2353
- ...mode === "detailed" ? { borderRadius: "0.5rem", padding: "0.5rem" } : {}
2354
- },
2355
- onClick: () => setIsOpen(!isOpen),
2356
- "aria-expanded": isOpen,
2357
- "aria-haspopup": "true",
2358
- children: [
2359
- /* @__PURE__ */ jsx("div", { className: "if-userButton-avatar", children: user.avatarUrl && !imageError ? /* @__PURE__ */ jsx(
2360
- "img",
2361
- {
2362
- src: user.avatarUrl,
2363
- alt: user.email,
2364
- onError: () => setImageError(true),
2365
- style: { borderRadius: "50%", objectFit: "cover", width: "100%", height: "100%" }
2366
- }
2367
- ) : /* @__PURE__ */ jsx("span", { style: { color: "white", fontWeight: 600, fontSize: "0.875rem" }, children: initials }) }),
2368
- mode === "detailed" && /* @__PURE__ */ jsxs(
2369
- "div",
2370
- {
2371
- style: {
2372
- display: "flex",
2373
- flexDirection: "column",
2374
- alignItems: "flex-start",
2375
- gap: "0.125rem"
2376
- },
2377
- children: [
2378
- user.name && /* @__PURE__ */ jsx(
2379
- "div",
2380
- {
2381
- style: {
2382
- fontSize: "0.875rem",
2383
- fontWeight: 600,
2384
- color: "#1f1f1f",
2385
- lineHeight: "1.25rem",
2386
- textAlign: "left"
2387
- },
2388
- children: user.name
2389
- }
2390
- ),
2391
- /* @__PURE__ */ jsx(
2392
- "div",
2393
- {
2394
- style: {
2395
- fontSize: "0.75rem",
2396
- color: "#828282",
2397
- lineHeight: "1rem",
2398
- textAlign: "left"
2399
- },
2400
- children: user.email
2401
- }
2402
- )
2403
- ]
2404
- }
2405
- )
2406
- ]
2407
- }
2408
- ),
2409
- isOpen && /* @__PURE__ */ jsx("div", { className: "if-userButton-menu", children: /* @__PURE__ */ jsxs(
2410
- "button",
2411
- {
2412
- onClick: handleSignOut,
2413
- className: "if-userButton-menuItem",
2414
- style: { color: "#DC2626" },
2415
- children: [
2416
- /* @__PURE__ */ jsx(LogOut, { style: { width: "1.25rem", height: "1.25rem" } }),
2417
- "Sign out"
2418
- ]
2419
- }
2420
- ) })
2421
- ]
2422
- }
2423
- );
2280
+ return /* @__PURE__ */ jsxs("div", { className: "if-userButton-container if-internal-ub3k8p", ref: dropdownRef, children: [
2281
+ /* @__PURE__ */ jsxs(
2282
+ "button",
2283
+ {
2284
+ className: buttonClassName,
2285
+ onClick: () => setIsOpen(!isOpen),
2286
+ "aria-expanded": isOpen,
2287
+ "aria-haspopup": "true",
2288
+ children: [
2289
+ /* @__PURE__ */ jsx("div", { className: "if-userButton-avatar", children: user.avatarUrl && !imageError ? /* @__PURE__ */ jsx(
2290
+ "img",
2291
+ {
2292
+ src: user.avatarUrl,
2293
+ alt: user.email,
2294
+ onError: () => setImageError(true),
2295
+ className: "if-userButton-avatarImage"
2296
+ }
2297
+ ) : /* @__PURE__ */ jsx("span", { className: "if-userButton-avatarInitials", children: initials }) }),
2298
+ mode === "detailed" && /* @__PURE__ */ jsxs("div", { className: "if-userButton-info", children: [
2299
+ user.name && /* @__PURE__ */ jsx("div", { className: "if-userButton-name", children: user.name }),
2300
+ /* @__PURE__ */ jsx("div", { className: "if-userButton-email", children: user.email })
2301
+ ] })
2302
+ ]
2303
+ }
2304
+ ),
2305
+ isOpen && /* @__PURE__ */ jsx("div", { className: "if-userButton-menu", children: /* @__PURE__ */ jsxs(
2306
+ "button",
2307
+ {
2308
+ onClick: handleSignOut,
2309
+ className: "if-userButton-menuItem if-userButton-menuItem-signout",
2310
+ children: [
2311
+ /* @__PURE__ */ jsx(LogOut, { className: "if-userButton-menuItem-icon" }),
2312
+ "Sign out"
2313
+ ]
2314
+ }
2315
+ ) })
2316
+ ] });
2424
2317
  }
2425
2318
  function Protect({
2426
2319
  children,
@@ -2478,94 +2371,6 @@ function SignedOut({ children }) {
2478
2371
  }
2479
2372
  return /* @__PURE__ */ jsx(Fragment, { children });
2480
2373
  }
2481
- function InsforgeCallback({
2482
- redirectTo = "/",
2483
- onSuccess,
2484
- onError,
2485
- loadingComponent,
2486
- onRedirect
2487
- }) {
2488
- const isProcessingRef = useRef(false);
2489
- const { isLoaded, isSignedIn } = useInsforge();
2490
- useEffect(() => {
2491
- if (!isLoaded) {
2492
- return;
2493
- }
2494
- if (isProcessingRef.current) {
2495
- return;
2496
- }
2497
- isProcessingRef.current = true;
2498
- const processCallback = () => {
2499
- const searchParams = new URLSearchParams(window.location.search);
2500
- const error = searchParams.get("error");
2501
- if (error) {
2502
- if (onError) {
2503
- onError(error);
2504
- } else {
2505
- const errorUrl = "/?error=" + encodeURIComponent(error);
2506
- if (onRedirect) {
2507
- onRedirect(errorUrl);
2508
- } else {
2509
- window.location.href = errorUrl;
2510
- }
2511
- }
2512
- return;
2513
- }
2514
- if (!isSignedIn) {
2515
- const errorMsg = "authentication_failed";
2516
- if (onError) {
2517
- onError(errorMsg);
2518
- } else {
2519
- const errorUrl = "/?error=" + encodeURIComponent(errorMsg);
2520
- if (onRedirect) {
2521
- onRedirect(errorUrl);
2522
- } else {
2523
- window.location.href = errorUrl;
2524
- }
2525
- }
2526
- return;
2527
- }
2528
- window.history.replaceState({}, "", window.location.pathname);
2529
- if (onSuccess) {
2530
- onSuccess();
2531
- }
2532
- if (onRedirect) {
2533
- onRedirect(redirectTo);
2534
- } else {
2535
- window.location.href = redirectTo;
2536
- }
2537
- };
2538
- processCallback();
2539
- }, [isLoaded, isSignedIn, redirectTo, onSuccess, onError, onRedirect]);
2540
- const defaultLoading = /* @__PURE__ */ jsx(
2541
- "div",
2542
- {
2543
- style: {
2544
- display: "flex",
2545
- alignItems: "center",
2546
- justifyContent: "center",
2547
- minHeight: "100vh"
2548
- },
2549
- children: /* @__PURE__ */ jsxs("div", { style: { textAlign: "center" }, children: [
2550
- /* @__PURE__ */ jsx("h2", { className: "if-authHeader-title", style: { marginBottom: "1rem" }, children: "Completing authentication..." }),
2551
- /* @__PURE__ */ jsx(
2552
- "div",
2553
- {
2554
- className: "if-submitButton-spinner",
2555
- style: {
2556
- borderRadius: "50%",
2557
- height: "3rem",
2558
- width: "3rem",
2559
- borderBottom: "2px solid #2563EB",
2560
- margin: "0 auto"
2561
- }
2562
- }
2563
- )
2564
- ] })
2565
- }
2566
- );
2567
- return loadingComponent || defaultLoading;
2568
- }
2569
2374
 
2570
2375
  // src/hooks/useAuth.ts
2571
2376
  function useAuth() {
@@ -2580,9 +2385,9 @@ function useUser() {
2580
2385
  }
2581
2386
  function RedirectToAuth({ baseUrl, path }) {
2582
2387
  useEffect(() => {
2583
- const callbackUrl = `${window.location.origin}/auth/callback`;
2388
+ const currentUrl = window.location.href;
2584
2389
  const authUrl = new URL(path, baseUrl);
2585
- authUrl.searchParams.set("redirect", callbackUrl);
2390
+ authUrl.searchParams.set("redirect", currentUrl);
2586
2391
  window.location.replace(authUrl.toString());
2587
2392
  }, [baseUrl, path]);
2588
2393
  return null;
@@ -2624,6 +2429,6 @@ function getInsforgeRoutes(config) {
2624
2429
  return routes;
2625
2430
  }
2626
2431
 
2627
- export { AuthBranding, AuthContainer, AuthDivider, AuthEmailVerificationStep, AuthErrorBanner, AuthFormField, AuthHeader, AuthLink, AuthOAuthButton, AuthOAuthProviders, AuthPasswordField, AuthPasswordStrengthIndicator, AuthSubmitButton, AuthVerificationCodeInput, ForgotPassword, ForgotPasswordForm, InsforgeCallback, InsforgeProvider, OAUTH_PROVIDER_CONFIG, Protect, ResetPassword, ResetPasswordForm, SignIn, SignInForm, SignUp, SignUpForm, SignedIn, SignedOut, UserButton, VerifyEmail, VerifyEmailStatus, checkPasswordStrength, createPasswordSchema, emailSchema, getAllProviderConfigs, getInsforgeRoutes, getProviderConfig, passwordSchema, useAuth, useInsforge, usePublicAuthConfig, useUser, validateEmail, validatePassword };
2432
+ export { AuthBranding, AuthContainer, AuthDivider, AuthEmailVerificationStep, AuthErrorBanner, AuthFormField, AuthHeader, AuthLink, AuthOAuthButton, AuthOAuthProviders, AuthPasswordField, AuthPasswordStrengthIndicator, AuthResetPasswordVerificationStep, AuthSubmitButton, AuthVerificationCodeInput, ForgotPassword, ForgotPasswordForm, InsforgeProvider, OAUTH_PROVIDER_CONFIG, Protect, ResetPassword, ResetPasswordForm, SignIn, SignInForm, SignUp, SignUpForm, SignedIn, SignedOut, UserButton, VerifyEmail, VerifyEmailStatus, checkPasswordStrength, createPasswordSchema, emailSchema, getAllProviderConfigs, getInsforgeRoutes, getProviderConfig, passwordSchema, useAuth, useInsforge, usePublicAuthConfig, useUser, validateEmail, validatePassword };
2628
2433
  //# sourceMappingURL=index.js.map
2629
2434
  //# sourceMappingURL=index.js.map