@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 CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
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;IAEpC,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,CA8QtD,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"}
@@ -8,6 +8,7 @@ interface PasswordResetFormProps {
8
8
  success?: boolean;
9
9
  successMessage?: string;
10
10
  token?: string;
11
+ resetEmail?: string;
11
12
  }
12
13
  export declare const PasswordResetForm: React.FC<PasswordResetFormProps>;
13
14
  export {};
@@ -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;CAChB;AAED,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAyL9D,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;AA+L7I,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,CAgyD5D,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
- return smartlinks.authKit.requestPasswordReset(this.clientId, {
10953
- email,
10954
- redirectUrl,
10955
- clientName: this.clientName
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
- return smartlinks.authKit.verifyResetToken(this.clientId, token);
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 = '45';
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 = 'auto', className, customization, skipConfigFetch = false, minimal = false, logger, proxyMode = false, collectionId, disableConfigCache = false, enableSilentGoogleSignIn = false, }) => {
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
- log.log('Reset token verification result:', { valid: verifyResult.valid, hasEmail: !!verifyResult.email, message: verifyResult.message });
13083
- // Check if token is valid before proceeding
13084
- if (!verifyResult.valid) {
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
- // Use resetSuccess (not authSuccess) to show password reset confirmation, not "Login successful"
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 5s, assume FedCM was blocked
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
- }, 5000);
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
- // Auto-login failed, fall back to showing success message
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("p", { style: {
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