@proveanything/smartlinks-auth-ui 0.4.6 → 0.4.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api.d.ts.map +1 -1
- package/dist/components/EmailAuthForm.d.ts +1 -0
- package/dist/components/EmailAuthForm.d.ts.map +1 -1
- package/dist/components/PasswordResetForm.d.ts +1 -0
- package/dist/components/PasswordResetForm.d.ts.map +1 -1
- package/dist/components/SmartlinksAuthUI.d.ts.map +1 -1
- package/dist/index.esm.js +167 -30
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +167 -30
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +7 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/errorHandling.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAGpF;;;GAGG;AACH,qBAAa,OAAO;IAClB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,UAAU,CAAC,CAAS;IAC5B,OAAO,CAAC,GAAG,CAAyC;gBAExC,YAAY,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,UAAU;IAQxF,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAI7D,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IAWnD,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAC7C,cAAc,CAAC,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,MAAM,CAAC;YAAC,OAAO,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QACjF,SAAS,CAAC,EAAE,UAAU,GAAG,cAAc,CAAC;KACzC,GAAG,OAAO,CAAC,YAAY,CAAC;IAmBnB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAc7E,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC;IAIvE,eAAe,CACnB,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,YAAY,CAAC;IAIlB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,7 @@ interface EmailAuthFormProps {
|
|
|
11
11
|
loading: boolean;
|
|
12
12
|
error?: string;
|
|
13
13
|
signupProminence?: SignupProminence;
|
|
14
|
+
signupRedirectUrl?: string;
|
|
14
15
|
schema?: ContactSchemaResponse | null;
|
|
15
16
|
registrationFieldsConfig?: RegistrationFieldConfig[];
|
|
16
17
|
/** @deprecated Use schema + registrationFieldsConfig instead */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EmailAuthForm.d.ts","sourceRoot":"","sources":["../../src/components/EmailAuthForm.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4B,MAAM,OAAO,CAAC;AAEjD,OAAO,KAAK,EAAiB,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AACpF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE3E,OAAO,gBAAgB,CAAC;AAExB,UAAU,kBAAkB;IAC1B,IAAI,EAAE,OAAO,GAAG,UAAU,CAAC;IAC3B,QAAQ,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"EmailAuthForm.d.ts","sourceRoot":"","sources":["../../src/components/EmailAuthForm.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4B,MAAM,OAAO,CAAC;AAEjD,OAAO,KAAK,EAAiB,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AACpF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE3E,OAAO,gBAAgB,CAAC;AAExB,UAAU,kBAAkB;IAC1B,IAAI,EAAE,OAAO,GAAG,UAAU,CAAC;IAC3B,QAAQ,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B,MAAM,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAAC;IACtC,wBAAwB,CAAC,EAAE,uBAAuB,EAAE,CAAC;IAErD,gEAAgE;IAChE,gBAAgB,CAAC,EAAE,UAAU,EAAE,CAAC;CACjC;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAyRtD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PasswordResetForm.d.ts","sourceRoot":"","sources":["../../src/components/PasswordResetForm.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AACxC,OAAO,gBAAgB,CAAC;AAExB,UAAU,sBAAsB;IAC9B,QAAQ,EAAE,CAAC,eAAe,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/E,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"PasswordResetForm.d.ts","sourceRoot":"","sources":["../../src/components/PasswordResetForm.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AACxC,OAAO,gBAAgB,CAAC;AAExB,UAAU,sBAAsB;IAC9B,QAAQ,EAAE,CAAC,eAAe,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/E,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAsM9D,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SmartlinksAuthUI.d.ts","sourceRoot":"","sources":["../../src/components/SmartlinksAuthUI.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAY5D,OAAO,KAAK,EAAE,qBAAqB,EAAyF,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"SmartlinksAuthUI.d.ts","sourceRoot":"","sources":["../../src/components/SmartlinksAuthUI.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAY5D,OAAO,KAAK,EAAE,qBAAqB,EAAyF,MAAM,UAAU,CAAC;AA4N7I,QAAA,MAAM,mBAAmB,QAAa,OAAO,CAAC,IAAI,CAqBjD,CAAC;AAqDF,OAAO,EAAE,mBAAmB,EAAE,CAAC;AAI/B,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CA64D5D,CAAC"}
|
package/dist/index.esm.js
CHANGED
|
@@ -258,7 +258,7 @@ const AuthModeToggle = ({ mode, onModeChange, disabled = false, }) => {
|
|
|
258
258
|
return (jsxs("div", { className: "auth-mode-toggle", role: "tablist", "aria-label": "Authentication mode", children: [jsx("button", { type: "button", role: "tab", "aria-selected": mode === 'login', className: `auth-mode-toggle-button ${mode === 'login' ? 'auth-mode-toggle-button--active' : ''}`, onClick: () => onModeChange('login'), disabled: disabled, children: "Sign In" }), jsx("button", { type: "button", role: "tab", "aria-selected": mode === 'register', className: `auth-mode-toggle-button ${mode === 'register' ? 'auth-mode-toggle-button--active' : ''}`, onClick: () => onModeChange('register'), disabled: disabled, children: "Create Account" })] }));
|
|
259
259
|
};
|
|
260
260
|
|
|
261
|
-
const EmailAuthForm = ({ mode, onSubmit, onModeSwitch, onForgotPassword, loading, error, signupProminence = 'minimal', schema, registrationFieldsConfig = [], additionalFields = [], }) => {
|
|
261
|
+
const EmailAuthForm = ({ mode, onSubmit, onModeSwitch, onForgotPassword, loading, error, signupProminence = 'minimal', signupRedirectUrl, schema, registrationFieldsConfig = [], additionalFields = [], }) => {
|
|
262
262
|
const [formData, setFormData] = useState({
|
|
263
263
|
email: '',
|
|
264
264
|
password: '',
|
|
@@ -314,7 +314,7 @@ const EmailAuthForm = ({ mode, onSubmit, onModeSwitch, onForgotPassword, loading
|
|
|
314
314
|
if (newMode !== mode) {
|
|
315
315
|
onModeSwitch();
|
|
316
316
|
}
|
|
317
|
-
}, disabled: loading })), jsxs("div", { className: "auth-form-header", children: [jsx("h2", { className: "auth-form-title", children: title }), jsx("p", { className: "auth-form-subtitle", children: subtitle })] }), error && (jsxs("div", { className: "auth-error", role: "alert", children: [jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "currentColor", children: jsx("path", { d: "M8 0C3.58 0 0 3.58 0 8s3.58 8 8 8 8-3.58 8-8-3.58-8-8-8zm1 13H7v-2h2v2zm0-3H7V4h2v6z" }) }), error] })), mode === 'register' && (jsxs("div", { className: "auth-form-group", children: [jsx("label", { htmlFor: "displayName", className: "auth-label", children: "Full Name" }), jsx("input", { type: "text", id: "displayName", className: "auth-input", value: formData.displayName || '', onChange: (e) => handleChange('displayName', e.target.value), required: mode === 'register', disabled: loading, placeholder: "John Smith" })] })), jsxs("div", { className: "auth-form-group", children: [jsx("label", { htmlFor: "email", className: "auth-label", children: "Email address" }), jsx("input", { type: "email", id: "email", className: "auth-input", value: formData.email || '', onChange: (e) => handleChange('email', e.target.value), required: true, disabled: loading, placeholder: "you@example.com", autoComplete: "email" })] }), jsxs("div", { className: "auth-form-group", children: [jsx("label", { htmlFor: "password", className: "auth-label", children: "Password" }), jsx("input", { type: "password", id: "password", className: "auth-input", value: formData.password || '', onChange: (e) => handleChange('password', e.target.value), required: true, disabled: loading, placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", autoComplete: mode === 'login' ? 'current-password' : 'new-password', minLength: 6 })] }), mode === 'register' && hasSchemaFields && schemaFields.inline.map(renderSchemaField), mode === 'register' && hasLegacyFields && additionalFields.map(renderLegacyField), mode === 'register' && hasSchemaFields && schemaFields.postCredentials.length > 0 && (jsxs(Fragment, { children: [jsx("div", { className: "auth-divider", style: { margin: '16px 0' }, children: jsx("span", { children: "Additional Information" }) }), schemaFields.postCredentials.map(renderSchemaField)] })), mode === 'login' && (jsx("div", { className: "auth-form-footer", children: jsx("button", { type: "button", className: "auth-link", onClick: onForgotPassword, disabled: loading, children: "Forgot password?" }) })), jsx("button", { type: "submit", className: "auth-button auth-button-primary", disabled: loading, children: loading ? (jsx("span", { className: "auth-spinner" })) : mode === 'login' ? ('Sign in') : ('Create account') }), signupProminence !== 'balanced' && (jsxs("div", { className: "auth-divider", children: [jsx("span", { children: mode === 'login' ? "Don't have an account?" : 'Already have an account?' }), jsx("button", { type: "button", className: "auth-link auth-link-bold", onClick: onModeSwitch, disabled: loading, children: mode === 'login' ? 'Sign up' : 'Sign in' })] }))] }));
|
|
317
|
+
}, disabled: loading })), jsxs("div", { className: "auth-form-header", children: [jsx("h2", { className: "auth-form-title", children: title }), jsx("p", { className: "auth-form-subtitle", children: subtitle })] }), error && (jsxs("div", { className: "auth-error", role: "alert", children: [jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "currentColor", children: jsx("path", { d: "M8 0C3.58 0 0 3.58 0 8s3.58 8 8 8 8-3.58 8-8-3.58-8-8-8zm1 13H7v-2h2v2zm0-3H7V4h2v6z" }) }), error] })), mode === 'register' && (jsxs("div", { className: "auth-form-group", children: [jsx("label", { htmlFor: "displayName", className: "auth-label", children: "Full Name" }), jsx("input", { type: "text", id: "displayName", className: "auth-input", value: formData.displayName || '', onChange: (e) => handleChange('displayName', e.target.value), required: mode === 'register', disabled: loading, placeholder: "John Smith" })] })), jsxs("div", { className: "auth-form-group", children: [jsx("label", { htmlFor: "email", className: "auth-label", children: "Email address" }), jsx("input", { type: "email", id: "email", className: "auth-input", value: formData.email || '', onChange: (e) => handleChange('email', e.target.value), required: true, disabled: loading, placeholder: "you@example.com", autoComplete: "email" })] }), jsxs("div", { className: "auth-form-group", children: [jsx("label", { htmlFor: "password", className: "auth-label", children: "Password" }), jsx("input", { type: "password", id: "password", className: "auth-input", value: formData.password || '', onChange: (e) => handleChange('password', e.target.value), required: true, disabled: loading, placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", autoComplete: mode === 'login' ? 'current-password' : 'new-password', minLength: 6 })] }), mode === 'register' && hasSchemaFields && schemaFields.inline.map(renderSchemaField), mode === 'register' && hasLegacyFields && additionalFields.map(renderLegacyField), mode === 'register' && hasSchemaFields && schemaFields.postCredentials.length > 0 && (jsxs(Fragment, { children: [jsx("div", { className: "auth-divider", style: { margin: '16px 0' }, children: jsx("span", { children: "Additional Information" }) }), schemaFields.postCredentials.map(renderSchemaField)] })), mode === 'login' && (jsx("div", { className: "auth-form-footer", children: jsx("button", { type: "button", className: "auth-link", onClick: onForgotPassword, disabled: loading, children: "Forgot password?" }) })), jsx("button", { type: "submit", className: "auth-button auth-button-primary", disabled: loading, children: loading ? (jsx("span", { className: "auth-spinner" })) : mode === 'login' ? ('Sign in') : ('Create account') }), signupProminence !== 'balanced' && signupProminence !== 'none' && (jsxs("div", { className: "auth-divider", children: [jsx("span", { children: mode === 'login' ? "Don't have an account?" : 'Already have an account?' }), signupRedirectUrl && mode === 'login' ? (jsx("a", { href: signupRedirectUrl, target: "_top", className: "auth-link auth-link-bold", children: "Sign up" })) : (jsx("button", { type: "button", className: "auth-link auth-link-bold", onClick: onModeSwitch, disabled: loading, children: mode === 'login' ? 'Sign up' : 'Sign in' }))] }))] }));
|
|
318
318
|
};
|
|
319
319
|
|
|
320
320
|
const ProviderButtons = ({ enabledProviders, providerOrder, onEmailLogin, onGoogleLogin, onPhoneLogin, onMagicLinkLogin, loading, }) => {
|
|
@@ -10811,7 +10811,7 @@ const PhoneAuthForm = ({ onSubmit, onBack, loading, error, }) => {
|
|
|
10811
10811
|
: 'Resend code' }) })] })), jsx("button", { type: "submit", className: "auth-button auth-button-primary", disabled: loading, children: loading ? (jsx("span", { className: "auth-spinner" })) : codeSent ? ('Verify Code') : ('Send Code') }), jsx("div", { className: "auth-divider", children: jsx("button", { type: "button", className: "auth-link auth-link-bold", onClick: onBack, disabled: loading, children: "\u2190 Back to login" }) })] }));
|
|
10812
10812
|
};
|
|
10813
10813
|
|
|
10814
|
-
const PasswordResetForm = ({ onSubmit, onBack, loading, error, success, successMessage, token, }) => {
|
|
10814
|
+
const PasswordResetForm = ({ onSubmit, onBack, loading, error, success, successMessage, token, resetEmail, }) => {
|
|
10815
10815
|
const [email, setEmail] = useState('');
|
|
10816
10816
|
const [password, setPassword] = useState('');
|
|
10817
10817
|
const [confirmPassword, setConfirmPassword] = useState('');
|
|
@@ -10836,14 +10836,14 @@ const PasswordResetForm = ({ onSubmit, onBack, loading, error, success, successM
|
|
|
10836
10836
|
await onSubmit(email);
|
|
10837
10837
|
}
|
|
10838
10838
|
};
|
|
10839
|
-
if (success) {
|
|
10839
|
+
if (success && !error) {
|
|
10840
10840
|
return (jsxs("div", { className: "auth-form", children: [jsxs("div", { className: "auth-form-header", children: [jsx("div", { style: { textAlign: 'center', marginBottom: '1rem' }, children: jsxs("svg", { width: "64", height: "64", viewBox: "0 0 64 64", fill: "none", style: { margin: '0 auto' }, children: [jsx("circle", { cx: "32", cy: "32", r: "32", fill: "#10b981", fillOpacity: "0.1" }), jsx("path", { d: "M20 32l8 8 16-16", stroke: "#10b981", strokeWidth: "4", strokeLinecap: "round", strokeLinejoin: "round" })] }) }), jsx("h2", { className: "auth-form-title", children: token ? 'Password reset!' : 'Check your email' }), jsx("p", { className: "auth-form-subtitle", children: token
|
|
10841
10841
|
? (successMessage || 'Your password has been successfully reset. You can now sign in with your new password.')
|
|
10842
10842
|
: (successMessage || `We've sent password reset instructions to ${email}`) })] }), jsx("button", { type: "button", className: "auth-button auth-button-primary", onClick: onBack, children: "Back to Sign in" })] }));
|
|
10843
10843
|
}
|
|
10844
10844
|
return (jsxs("form", { className: "auth-form", onSubmit: handleSubmit, children: [jsxs("div", { className: "auth-form-header", children: [jsx("h2", { className: "auth-form-title", children: token ? 'Set new password' : 'Reset your password' }), jsx("p", { className: "auth-form-subtitle", children: token
|
|
10845
10845
|
? 'Enter your new password below.'
|
|
10846
|
-
: "Enter your email address and we'll send you instructions to reset your password." })] }), (error || passwordError) && (jsxs("div", { className: "auth-error", role: "alert", children: [jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "currentColor", children: jsx("path", { d: "M8 0C3.58 0 0 3.58 0 8s3.58 8 8 8 8-3.58 8-8-3.58-8-8-8zm1 13H7v-2h2v2zm0-3H7V4h2v6z" }) }), error || passwordError] })), token ? (jsxs(Fragment, { children: [jsxs("div", { className: "auth-form-group", children: [jsx("label", { htmlFor: "password", className: "auth-label", children: "New Password" }), jsx("input", { type: "password", id: "password", className: "auth-input", value: password, onChange: (e) => setPassword(e.target.value), required: true, disabled: loading, placeholder: "Enter new password", autoComplete: "new-password", minLength: 6 })] }), jsxs("div", { className: "auth-form-group", children: [jsx("label", { htmlFor: "confirmPassword", className: "auth-label", children: "Confirm Password" }), jsx("input", { type: "password", id: "confirmPassword", className: "auth-input", value: confirmPassword, onChange: (e) => setConfirmPassword(e.target.value), required: true, disabled: loading, placeholder: "Confirm new password", autoComplete: "new-password", minLength: 6 })] })] })) : (jsxs("div", { className: "auth-form-group", children: [jsx("label", { htmlFor: "email", className: "auth-label", children: "Email address" }), jsx("input", { type: "email", id: "email", className: "auth-input", value: email, onChange: (e) => setEmail(e.target.value), required: true, disabled: loading, placeholder: "you@example.com", autoComplete: "email" })] })), jsx("button", { type: "submit", className: "auth-button auth-button-primary", disabled: loading, children: loading ? (jsx("span", { className: "auth-spinner" })) : token ? ('Reset password') : ('Send reset instructions') }), jsx("div", { className: "auth-divider", children: jsx("button", { type: "button", className: "auth-link auth-link-bold", onClick: onBack, disabled: loading, children: "\u2190 Back to Sign in" }) })] }));
|
|
10846
|
+
: "Enter your email address and we'll send you instructions to reset your password." })] }), (error || passwordError) && (jsxs("div", { className: "auth-error", role: "alert", children: [jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "currentColor", children: jsx("path", { d: "M8 0C3.58 0 0 3.58 0 8s3.58 8 8 8 8-3.58 8-8-3.58-8-8-8zm1 13H7v-2h2v2zm0-3H7V4h2v6z" }) }), error || passwordError] })), token ? (jsxs(Fragment, { children: [resetEmail && (jsx("input", { type: "email", value: resetEmail, readOnly: true, autoComplete: "username", style: { position: 'absolute', opacity: 0, height: 0, width: 0, overflow: 'hidden', pointerEvents: 'none' }, tabIndex: -1, "aria-hidden": "true" })), jsxs("div", { className: "auth-form-group", children: [jsx("label", { htmlFor: "password", className: "auth-label", children: "New Password" }), jsx("input", { type: "password", id: "password", className: "auth-input", value: password, onChange: (e) => setPassword(e.target.value), required: true, disabled: loading, placeholder: "Enter new password", autoComplete: "new-password", minLength: 6 })] }), jsxs("div", { className: "auth-form-group", children: [jsx("label", { htmlFor: "confirmPassword", className: "auth-label", children: "Confirm Password" }), jsx("input", { type: "password", id: "confirmPassword", className: "auth-input", value: confirmPassword, onChange: (e) => setConfirmPassword(e.target.value), required: true, disabled: loading, placeholder: "Confirm new password", autoComplete: "new-password", minLength: 6 })] })] })) : (jsxs("div", { className: "auth-form-group", children: [jsx("label", { htmlFor: "email", className: "auth-label", children: "Email address" }), jsx("input", { type: "email", id: "email", className: "auth-input", value: email, onChange: (e) => setEmail(e.target.value), required: true, disabled: loading, placeholder: "you@example.com", autoComplete: "email" })] })), jsx("button", { type: "submit", className: "auth-button auth-button-primary", disabled: loading, children: loading ? (jsx("span", { className: "auth-spinner" })) : token ? ('Reset password') : ('Send reset instructions') }), jsx("div", { className: "auth-divider", children: jsx("button", { type: "button", className: "auth-link auth-link-bold", onClick: onBack, disabled: loading, children: "\u2190 Back to Sign in" }) })] }));
|
|
10847
10847
|
};
|
|
10848
10848
|
|
|
10849
10849
|
const MagicLinkForm = ({ onSubmit, onCancel, loading = false, error, }) => {
|
|
@@ -10949,14 +10949,46 @@ class AuthAPI {
|
|
|
10949
10949
|
return smartlinks.authKit.verifyPhoneCode(this.clientId, phoneNumber, code);
|
|
10950
10950
|
}
|
|
10951
10951
|
async requestPasswordReset(email, redirectUrl) {
|
|
10952
|
-
|
|
10953
|
-
|
|
10954
|
-
|
|
10955
|
-
|
|
10956
|
-
|
|
10952
|
+
console.log('[AuthKit:API] requestPasswordReset called', { clientId: this.clientId, email, redirectUrl });
|
|
10953
|
+
try {
|
|
10954
|
+
const result = await smartlinks.authKit.requestPasswordReset(this.clientId, {
|
|
10955
|
+
email,
|
|
10956
|
+
redirectUrl,
|
|
10957
|
+
clientName: this.clientName
|
|
10958
|
+
});
|
|
10959
|
+
console.log('[AuthKit:API] requestPasswordReset resolved:', JSON.stringify(result));
|
|
10960
|
+
return result;
|
|
10961
|
+
}
|
|
10962
|
+
catch (error) {
|
|
10963
|
+
const err = error;
|
|
10964
|
+
console.error('[AuthKit:API] requestPasswordReset threw:', {
|
|
10965
|
+
type: typeof error,
|
|
10966
|
+
message: err?.message,
|
|
10967
|
+
statusCode: err?.statusCode ?? err?.response?.status,
|
|
10968
|
+
errorCode: err?.errorCode ?? err?.details?.errorCode,
|
|
10969
|
+
details: err?.details ?? err?.response?.data,
|
|
10970
|
+
keys: err ? Object.keys(err) : [],
|
|
10971
|
+
});
|
|
10972
|
+
throw error;
|
|
10973
|
+
}
|
|
10957
10974
|
}
|
|
10958
10975
|
async verifyResetToken(token) {
|
|
10959
|
-
|
|
10976
|
+
console.log('[AuthKit:API] verifyResetToken called');
|
|
10977
|
+
try {
|
|
10978
|
+
const result = await smartlinks.authKit.verifyResetToken(this.clientId, token);
|
|
10979
|
+
console.log('[AuthKit:API] verifyResetToken resolved:', JSON.stringify(result));
|
|
10980
|
+
return result;
|
|
10981
|
+
}
|
|
10982
|
+
catch (error) {
|
|
10983
|
+
const err = error;
|
|
10984
|
+
console.error('[AuthKit:API] verifyResetToken threw:', {
|
|
10985
|
+
type: typeof error,
|
|
10986
|
+
message: err?.message,
|
|
10987
|
+
statusCode: err?.statusCode ?? err?.response?.status,
|
|
10988
|
+
errorCode: err?.errorCode ?? err?.details?.errorCode,
|
|
10989
|
+
});
|
|
10990
|
+
throw error;
|
|
10991
|
+
}
|
|
10960
10992
|
}
|
|
10961
10993
|
async completePasswordReset(token, newPassword) {
|
|
10962
10994
|
return smartlinks.authKit.completePasswordReset(this.clientId, token, newPassword);
|
|
@@ -10992,7 +11024,6 @@ class AuthAPI {
|
|
|
10992
11024
|
this.log.warn('Failed to fetch UI config, using defaults:', error);
|
|
10993
11025
|
return {
|
|
10994
11026
|
branding: {
|
|
10995
|
-
title: 'Smartlinks Auth',
|
|
10996
11027
|
subtitle: 'Sign in to your account',
|
|
10997
11028
|
primaryColor: '#3B82F6',
|
|
10998
11029
|
secondaryColor: '#1D4ED8',
|
|
@@ -12388,6 +12419,10 @@ function getFriendlyErrorMessage(error) {
|
|
|
12388
12419
|
if (isApiErrorLike(error)) {
|
|
12389
12420
|
// First, check for specific error code (most precise)
|
|
12390
12421
|
const errorCode = error.errorCode || error.details?.errorCode || error.details?.error;
|
|
12422
|
+
// For rate-limit errors, prefer the backend's message as it includes specific wait times
|
|
12423
|
+
if (errorCode === 'RATE_LIMIT_EXCEEDED' && error.message && error.message !== '[object Object]') {
|
|
12424
|
+
return error.message;
|
|
12425
|
+
}
|
|
12391
12426
|
if (errorCode && ERROR_CODE_MESSAGES[errorCode]) {
|
|
12392
12427
|
return ERROR_CODE_MESSAGES[errorCode];
|
|
12393
12428
|
}
|
|
@@ -12395,6 +12430,10 @@ function getFriendlyErrorMessage(error) {
|
|
|
12395
12430
|
if (error.statusCode >= 500) {
|
|
12396
12431
|
return 'Server error. Please try again later.';
|
|
12397
12432
|
}
|
|
12433
|
+
// For 429 status, prefer backend message (may include wait time)
|
|
12434
|
+
if (error.statusCode === 429 && error.message && error.message !== '[object Object]') {
|
|
12435
|
+
return error.message;
|
|
12436
|
+
}
|
|
12398
12437
|
if (STATUS_MESSAGES[error.statusCode]) {
|
|
12399
12438
|
return STATUS_MESSAGES[error.statusCode];
|
|
12400
12439
|
}
|
|
@@ -12521,7 +12560,7 @@ function requiresEmailVerification(error) {
|
|
|
12521
12560
|
}
|
|
12522
12561
|
|
|
12523
12562
|
// VERSION: Update this when making changes to help identify which version is running
|
|
12524
|
-
const AUTH_UI_VERSION = '
|
|
12563
|
+
const AUTH_UI_VERSION = '46';
|
|
12525
12564
|
const LOG_PREFIX = `[SmartlinksAuthUI:v${AUTH_UI_VERSION}]`;
|
|
12526
12565
|
// Helper to check for URL auth params synchronously (runs during initialization)
|
|
12527
12566
|
// This prevents the form from flashing before detecting deep-link flows
|
|
@@ -12545,6 +12584,24 @@ const getExpirationFromResponse = (response) => {
|
|
|
12545
12584
|
return Date.now() + response.expiresIn;
|
|
12546
12585
|
return undefined; // Will use 7-day default in tokenStorage
|
|
12547
12586
|
};
|
|
12587
|
+
const getActionResultErrorMessage = (result) => {
|
|
12588
|
+
if (!result || typeof result !== 'object')
|
|
12589
|
+
return null;
|
|
12590
|
+
const candidate = result;
|
|
12591
|
+
const numericStatusCode = typeof candidate.statusCode === 'string'
|
|
12592
|
+
? Number(candidate.statusCode)
|
|
12593
|
+
: candidate.statusCode;
|
|
12594
|
+
const hasFailureStatus = typeof numericStatusCode === 'number' && !Number.isNaN(numericStatusCode) && numericStatusCode >= 400;
|
|
12595
|
+
const isFailure = candidate.success === false || candidate.ok === false || !!candidate.errorCode || hasFailureStatus;
|
|
12596
|
+
if (!isFailure)
|
|
12597
|
+
return null;
|
|
12598
|
+
return getFriendlyErrorMessage({
|
|
12599
|
+
statusCode: hasFailureStatus ? numericStatusCode : 400,
|
|
12600
|
+
errorCode: candidate.errorCode,
|
|
12601
|
+
message: candidate.message || 'Request failed. Please try again.',
|
|
12602
|
+
details: candidate.details,
|
|
12603
|
+
});
|
|
12604
|
+
};
|
|
12548
12605
|
// Default Smartlinks Google OAuth Client ID (public - safe to expose)
|
|
12549
12606
|
const DEFAULT_GOOGLE_CLIENT_ID = '696509063554-jdlbjl8vsjt7cr0vgkjkjf3ffnvi3a70.apps.googleusercontent.com';
|
|
12550
12607
|
// Default Google OAuth proxy URL (hosted on our whitelisted domain)
|
|
@@ -12720,7 +12777,7 @@ const checkSilentGoogleSignIn = async (clientId, googleClientId) => {
|
|
|
12720
12777
|
});
|
|
12721
12778
|
};
|
|
12722
12779
|
// getFriendlyErrorMessage is now imported from ../utils/errorHandling
|
|
12723
|
-
const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAuthSuccess, onAuthError, onRedirect, enabledProviders = ['email', 'google', 'phone'], initialMode, signupProminence, redirectUrl, theme = '
|
|
12780
|
+
const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAuthSuccess, onAuthError, onRedirect, enabledProviders = ['email', 'google', 'phone'], initialMode, signupProminence, redirectUrl, theme = 'light', className, customization, skipConfigFetch = false, minimal = false, logger, proxyMode = false, collectionId, disableConfigCache = false, enableSilentGoogleSignIn = false, }) => {
|
|
12724
12781
|
// Resolve signup prominence from props, customization, config, or default
|
|
12725
12782
|
const resolvedSignupProminence = signupProminence || customization?.signupProminence || 'minimal';
|
|
12726
12783
|
// Determine initial mode based on signupProminence setting
|
|
@@ -13079,10 +13136,9 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
|
|
|
13079
13136
|
log.log('Verifying reset token:', token);
|
|
13080
13137
|
// Verify token is valid, then show password reset form
|
|
13081
13138
|
const verifyResult = await api.verifyResetToken(token);
|
|
13082
|
-
|
|
13083
|
-
|
|
13084
|
-
|
|
13085
|
-
throw new Error(verifyResult.message || 'Invalid or expired token');
|
|
13139
|
+
// Guard against undefined result (proxy mode may resolve without data)
|
|
13140
|
+
if (!verifyResult || !verifyResult.valid) {
|
|
13141
|
+
throw new Error(verifyResult?.message || 'Invalid or expired token');
|
|
13086
13142
|
}
|
|
13087
13143
|
setUrlAuthProcessing(false); // Clear processing state - showing reset form
|
|
13088
13144
|
setResetToken(token); // Store token for use in password reset
|
|
@@ -13360,17 +13416,46 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
|
|
|
13360
13416
|
return;
|
|
13361
13417
|
setLoading(true);
|
|
13362
13418
|
setError(undefined);
|
|
13419
|
+
setAuthSuccess(false);
|
|
13420
|
+
setResetSuccess(false);
|
|
13421
|
+
setSuccessMessage(undefined);
|
|
13422
|
+
setShowResendVerification(false);
|
|
13363
13423
|
try {
|
|
13364
13424
|
const result = await api.requestPasswordReset(resetRequestEmail, getRedirectUrl());
|
|
13365
|
-
|
|
13425
|
+
const resultError = getActionResultErrorMessage(result);
|
|
13426
|
+
if (resultError) {
|
|
13427
|
+
setAuthSuccess(false);
|
|
13428
|
+
setResetSuccess(false);
|
|
13429
|
+
setSuccessMessage(undefined);
|
|
13430
|
+
setError(resultError);
|
|
13431
|
+
setShowRequestNewReset(true);
|
|
13432
|
+
return;
|
|
13433
|
+
}
|
|
13434
|
+
const resultAny = result;
|
|
13435
|
+
const isConfirmedSuccess = result && (resultAny.success === true ||
|
|
13436
|
+
resultAny.ok === true ||
|
|
13437
|
+
(resultAny.message && !resultAny.errorCode && !resultAny.statusCode));
|
|
13438
|
+
if (!isConfirmedSuccess) {
|
|
13439
|
+
setAuthSuccess(false);
|
|
13440
|
+
setResetSuccess(false);
|
|
13441
|
+
setSuccessMessage(undefined);
|
|
13442
|
+
setError(resultAny?.message || 'Unable to send password reset email. Please try again.');
|
|
13443
|
+
setShowRequestNewReset(true);
|
|
13444
|
+
return;
|
|
13445
|
+
}
|
|
13446
|
+
setAuthSuccess(false);
|
|
13447
|
+
setMode('reset-password');
|
|
13366
13448
|
setResetSuccess(true);
|
|
13367
|
-
// Use backend message if available, otherwise default
|
|
13368
13449
|
setSuccessMessage(result?.message || 'Password reset email sent! Please check your inbox.');
|
|
13369
13450
|
setShowRequestNewReset(false);
|
|
13370
13451
|
setResetRequestEmail('');
|
|
13371
13452
|
}
|
|
13372
13453
|
catch (err) {
|
|
13454
|
+
setAuthSuccess(false);
|
|
13455
|
+
setResetSuccess(false);
|
|
13456
|
+
setSuccessMessage(undefined);
|
|
13373
13457
|
setError(getFriendlyErrorMessage(err));
|
|
13458
|
+
setShowRequestNewReset(true);
|
|
13374
13459
|
onAuthError?.(err instanceof Error ? err : new Error(getFriendlyErrorMessage(err)));
|
|
13375
13460
|
}
|
|
13376
13461
|
finally {
|
|
@@ -13697,9 +13782,13 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
|
|
|
13697
13782
|
client_id: googleClientId,
|
|
13698
13783
|
origin: window.location.origin,
|
|
13699
13784
|
});
|
|
13785
|
+
// Track whether the credential callback has fired (user selected an account)
|
|
13786
|
+
// so we don't show the "blocked" fallback when the prompt closes after a successful selection
|
|
13787
|
+
let credentialCallbackFired = false;
|
|
13700
13788
|
google.accounts.id.initialize({
|
|
13701
13789
|
client_id: googleClientId,
|
|
13702
13790
|
callback: async (response) => {
|
|
13791
|
+
credentialCallbackFired = true;
|
|
13703
13792
|
try {
|
|
13704
13793
|
const idToken = response.credential;
|
|
13705
13794
|
const authResponse = await api.loginWithGoogle(idToken);
|
|
@@ -13727,23 +13816,29 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
|
|
|
13727
13816
|
cancel_on_tap_outside: true,
|
|
13728
13817
|
use_fedcm_for_prompt: true, // Enable FedCM for future browser compatibility
|
|
13729
13818
|
});
|
|
13730
|
-
// Use timeout fallback — if no prompt interaction after
|
|
13819
|
+
// Use timeout fallback — if no prompt interaction after 15s, assume FedCM was blocked
|
|
13820
|
+
// (15s gives users enough time to choose a Google account from the picker)
|
|
13731
13821
|
const promptTimeout = setTimeout(() => {
|
|
13822
|
+
if (credentialCallbackFired)
|
|
13823
|
+
return; // Auth is already in progress, don't show fallback
|
|
13732
13824
|
log.log('Google OneTap prompt timed out — FedCM may be blocked or unavailable');
|
|
13733
13825
|
setGoogleFallbackToPopup(true);
|
|
13734
13826
|
setLoading(false);
|
|
13735
|
-
},
|
|
13827
|
+
}, 15000);
|
|
13736
13828
|
google.accounts.id.prompt((notification) => {
|
|
13737
13829
|
clearTimeout(promptTimeout);
|
|
13830
|
+
// If the credential callback already fired, the user successfully selected an account
|
|
13831
|
+
// The prompt closing with 'dismissed' is expected — don't show fallback
|
|
13832
|
+
if (credentialCallbackFired) {
|
|
13833
|
+
log.log('Google OneTap prompt closed after credential selection — ignoring');
|
|
13834
|
+
return;
|
|
13835
|
+
}
|
|
13738
13836
|
// Check for FedCM/OneTap dismissal or blocking
|
|
13739
|
-
// notification may have getMomentType(), getDismissedReason(), getSkippedReason()
|
|
13740
13837
|
const momentType = notification?.getMomentType?.();
|
|
13741
13838
|
const dismissedReason = notification?.getDismissedReason?.();
|
|
13742
13839
|
const skippedReason = notification?.getSkippedReason?.();
|
|
13743
13840
|
log.log('Google OneTap prompt notification:', { momentType, dismissedReason, skippedReason });
|
|
13744
13841
|
if (momentType === 'skipped' || momentType === 'dismissed') {
|
|
13745
|
-
// User dismissed the prompt, or browser blocked it (FedCM disabled)
|
|
13746
|
-
// Offer popup flow as alternative
|
|
13747
13842
|
log.log('Google OneTap was dismissed/skipped, offering popup fallback');
|
|
13748
13843
|
setGoogleFallbackToPopup(true);
|
|
13749
13844
|
}
|
|
@@ -13805,6 +13900,9 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
|
|
|
13805
13900
|
const handlePasswordReset = async (emailOrPassword, confirmPassword) => {
|
|
13806
13901
|
setLoading(true);
|
|
13807
13902
|
setError(undefined);
|
|
13903
|
+
setAuthSuccess(false);
|
|
13904
|
+
setResetSuccess(false);
|
|
13905
|
+
setSuccessMessage(undefined);
|
|
13808
13906
|
const effectiveRedirectUrl = getRedirectUrl();
|
|
13809
13907
|
try {
|
|
13810
13908
|
if (resetToken && confirmPassword) {
|
|
@@ -13813,6 +13911,7 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
|
|
|
13813
13911
|
// Auto-login with the new password if we have the email
|
|
13814
13912
|
if (resetEmail) {
|
|
13815
13913
|
try {
|
|
13914
|
+
log.log('Auto-login after password reset for:', resetEmail);
|
|
13816
13915
|
const loginResponse = await api.login(resetEmail, emailOrPassword);
|
|
13817
13916
|
if (loginResponse.token) {
|
|
13818
13917
|
await auth.login(loginResponse.token, loginResponse.user, loginResponse.accountData, false);
|
|
@@ -13825,9 +13924,12 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
|
|
|
13825
13924
|
}
|
|
13826
13925
|
}
|
|
13827
13926
|
catch (loginErr) {
|
|
13828
|
-
|
|
13927
|
+
log.warn('Auto-login after password reset failed, requiring manual login:', loginErr);
|
|
13829
13928
|
}
|
|
13830
13929
|
}
|
|
13930
|
+
else {
|
|
13931
|
+
log.warn('No resetEmail available for auto-login after password reset');
|
|
13932
|
+
}
|
|
13831
13933
|
// Fallback: show success but require manual login
|
|
13832
13934
|
setResetSuccess(true);
|
|
13833
13935
|
setSuccessMessage('Password reset successful! Please sign in with your new password.');
|
|
@@ -13837,14 +13939,35 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
|
|
|
13837
13939
|
else {
|
|
13838
13940
|
// Request password reset email
|
|
13839
13941
|
const result = await api.requestPasswordReset(emailOrPassword, effectiveRedirectUrl);
|
|
13942
|
+
const resultError = getActionResultErrorMessage(result);
|
|
13943
|
+
if (resultError) {
|
|
13944
|
+
setAuthSuccess(false);
|
|
13945
|
+
setResetSuccess(false);
|
|
13946
|
+
setSuccessMessage(undefined);
|
|
13947
|
+
setError(resultError);
|
|
13948
|
+
return;
|
|
13949
|
+
}
|
|
13950
|
+
const resultAny = result;
|
|
13951
|
+
const isConfirmedSuccess = result && (resultAny.success === true ||
|
|
13952
|
+
resultAny.ok === true ||
|
|
13953
|
+
(resultAny.message && !resultAny.errorCode && !resultAny.statusCode));
|
|
13954
|
+
if (!isConfirmedSuccess) {
|
|
13955
|
+
setAuthSuccess(false);
|
|
13956
|
+
setResetSuccess(false);
|
|
13957
|
+
setSuccessMessage(undefined);
|
|
13958
|
+
setError(resultAny?.message || 'Unable to send password reset email. Please try again.');
|
|
13959
|
+
return;
|
|
13960
|
+
}
|
|
13840
13961
|
setResetSuccess(true);
|
|
13841
|
-
// Use backend message if available
|
|
13842
13962
|
if (result?.message) {
|
|
13843
13963
|
setSuccessMessage(result.message);
|
|
13844
13964
|
}
|
|
13845
13965
|
}
|
|
13846
13966
|
}
|
|
13847
13967
|
catch (err) {
|
|
13968
|
+
setAuthSuccess(false);
|
|
13969
|
+
setResetSuccess(false);
|
|
13970
|
+
setSuccessMessage(undefined);
|
|
13848
13971
|
setError(getFriendlyErrorMessage(err));
|
|
13849
13972
|
onAuthError?.(err instanceof Error ? err : new Error(getFriendlyErrorMessage(err)));
|
|
13850
13973
|
}
|
|
@@ -13908,7 +14031,7 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
|
|
|
13908
14031
|
setResetToken(undefined); // Clear token when going back
|
|
13909
14032
|
setResetEmail(undefined); // Clear email when going back
|
|
13910
14033
|
setSuccessMessage(undefined); // Clear success message
|
|
13911
|
-
}, loading: loading, error: error, success: resetSuccess, successMessage: successMessage, token: resetToken })) : (mode === 'login' || mode === 'register') ? (jsx(Fragment, { children: showResendVerification ? (jsxs("div", { style: {
|
|
14034
|
+
}, loading: loading, error: error, success: resetSuccess, successMessage: successMessage, token: resetToken, resetEmail: resetEmail })) : (mode === 'login' || mode === 'register') ? (jsx(Fragment, { children: showResendVerification ? (jsxs("div", { style: {
|
|
13912
14035
|
marginTop: '1rem',
|
|
13913
14036
|
padding: '1.5rem',
|
|
13914
14037
|
backgroundColor: config?.branding?.inheritHostStyles
|
|
@@ -14006,7 +14129,16 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
|
|
|
14006
14129
|
color: config?.branding?.inheritHostStyles
|
|
14007
14130
|
? 'hsl(var(--foreground, 215 25% 15%))'
|
|
14008
14131
|
: (resolvedTheme === 'dark' ? '#f1f5f9' : '#374151')
|
|
14009
|
-
}, children: "Password Reset Link Expired" }), jsx("
|
|
14132
|
+
}, children: "Password Reset Link Expired" }), error && (jsx("div", { style: {
|
|
14133
|
+
marginBottom: '1rem',
|
|
14134
|
+
padding: '0.75rem',
|
|
14135
|
+
backgroundColor: resolvedTheme === 'dark' ? 'rgba(239, 68, 68, 0.15)' : 'rgba(239, 68, 68, 0.1)',
|
|
14136
|
+
border: `1px solid ${resolvedTheme === 'dark' ? 'rgba(239, 68, 68, 0.3)' : 'rgba(239, 68, 68, 0.2)'}`,
|
|
14137
|
+
borderRadius: '0.375rem',
|
|
14138
|
+
color: resolvedTheme === 'dark' ? '#fca5a5' : '#dc2626',
|
|
14139
|
+
fontSize: '0.875rem',
|
|
14140
|
+
lineHeight: '1.5',
|
|
14141
|
+
}, children: error })), jsx("p", { style: {
|
|
14010
14142
|
marginBottom: '1rem',
|
|
14011
14143
|
fontSize: '0.875rem',
|
|
14012
14144
|
color: config?.branding?.inheritHostStyles
|
|
@@ -14142,6 +14274,11 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
|
|
|
14142
14274
|
const emailDisplayMode = config?.emailDisplayMode || 'form';
|
|
14143
14275
|
const providerOrder = config?.providerOrder || (config?.enabledProviders || enabledProviders);
|
|
14144
14276
|
const actualProviders = config?.enabledProviders || enabledProviders;
|
|
14277
|
+
const hasEmailProvider = actualProviders.includes('email');
|
|
14278
|
+
// If email provider is not enabled, only show provider buttons (no email/password form)
|
|
14279
|
+
if (!hasEmailProvider) {
|
|
14280
|
+
return (jsx(ProviderButtons, { enabledProviders: actualProviders, providerOrder: providerOrder, onGoogleLogin: handleGoogleLogin, onPhoneLogin: () => setMode('phone'), onMagicLinkLogin: () => setMode('magic-link'), loading: loading }));
|
|
14281
|
+
}
|
|
14145
14282
|
// Button mode: show provider selection first, then email form if email is selected
|
|
14146
14283
|
if (emailDisplayMode === 'button' && !showEmailForm) {
|
|
14147
14284
|
return (jsx(ProviderButtons, { enabledProviders: actualProviders, providerOrder: providerOrder, onEmailLogin: () => setShowEmailForm(true), onGoogleLogin: handleGoogleLogin, onPhoneLogin: () => setMode('phone'), onMagicLinkLogin: () => setMode('magic-link'), loading: loading }));
|
|
@@ -14163,7 +14300,7 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
|
|
|
14163
14300
|
setShowResendVerification(false);
|
|
14164
14301
|
setShowRequestNewReset(false);
|
|
14165
14302
|
setError(undefined);
|
|
14166
|
-
}, onForgotPassword: () => setMode('reset-password'), loading: loading, error: error, signupProminence: resolvedSignupProminence, schema: contactSchema, registrationFieldsConfig: config?.registrationFields, additionalFields: config?.signupAdditionalFields }), emailDisplayMode === 'form' && actualProviders.length > 1 && (jsx(ProviderButtons, { enabledProviders: actualProviders.filter((p) => p !== 'email'), providerOrder: providerOrder, onGoogleLogin: handleGoogleLogin, onPhoneLogin: () => setMode('phone'), onMagicLinkLogin: () => setMode('magic-link'), loading: loading }))] }));
|
|
14303
|
+
}, onForgotPassword: () => setMode('reset-password'), loading: loading, error: error, signupProminence: resolvedSignupProminence, signupRedirectUrl: config?.signupRedirectUrl || customization?.signupRedirectUrl, schema: contactSchema, registrationFieldsConfig: config?.registrationFields, additionalFields: config?.signupAdditionalFields }), emailDisplayMode === 'form' && actualProviders.length > 1 && (jsx(ProviderButtons, { enabledProviders: actualProviders.filter((p) => p !== 'email'), providerOrder: providerOrder, onGoogleLogin: handleGoogleLogin, onPhoneLogin: () => setMode('phone'), onMagicLinkLogin: () => setMode('magic-link'), loading: loading }))] }));
|
|
14167
14304
|
})()] })) })) : null }));
|
|
14168
14305
|
};
|
|
14169
14306
|
|