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