@edge-base/auth-ui-react 0.1.1

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.
Files changed (52) hide show
  1. package/README.md +180 -0
  2. package/dist/components/AuthForm.d.ts +11 -0
  3. package/dist/components/AuthForm.d.ts.map +1 -0
  4. package/dist/components/AuthForm.js +71 -0
  5. package/dist/components/AuthForm.js.map +1 -0
  6. package/dist/components/EmailOTP.d.ts +11 -0
  7. package/dist/components/EmailOTP.d.ts.map +1 -0
  8. package/dist/components/EmailOTP.js +56 -0
  9. package/dist/components/EmailOTP.js.map +1 -0
  10. package/dist/components/ForgotPassword.d.ts +9 -0
  11. package/dist/components/ForgotPassword.d.ts.map +1 -0
  12. package/dist/components/ForgotPassword.js +36 -0
  13. package/dist/components/ForgotPassword.js.map +1 -0
  14. package/dist/components/MFAChallenge.d.ts +17 -0
  15. package/dist/components/MFAChallenge.d.ts.map +1 -0
  16. package/dist/components/MFAChallenge.js +44 -0
  17. package/dist/components/MFAChallenge.js.map +1 -0
  18. package/dist/components/MagicLink.d.ts +9 -0
  19. package/dist/components/MagicLink.d.ts.map +1 -0
  20. package/dist/components/MagicLink.js +39 -0
  21. package/dist/components/MagicLink.js.map +1 -0
  22. package/dist/components/PhoneOTP.d.ts +11 -0
  23. package/dist/components/PhoneOTP.d.ts.map +1 -0
  24. package/dist/components/PhoneOTP.js +56 -0
  25. package/dist/components/PhoneOTP.js.map +1 -0
  26. package/dist/components/SignIn.d.ts +16 -0
  27. package/dist/components/SignIn.d.ts.map +1 -0
  28. package/dist/components/SignIn.js +39 -0
  29. package/dist/components/SignIn.js.map +1 -0
  30. package/dist/components/SignUp.d.ts +11 -0
  31. package/dist/components/SignUp.d.ts.map +1 -0
  32. package/dist/components/SignUp.js +43 -0
  33. package/dist/components/SignUp.js.map +1 -0
  34. package/dist/components/SocialButtons.d.ts +6 -0
  35. package/dist/components/SocialButtons.d.ts.map +1 -0
  36. package/dist/components/SocialButtons.js +39 -0
  37. package/dist/components/SocialButtons.js.map +1 -0
  38. package/dist/context.d.ts +80 -0
  39. package/dist/context.d.ts.map +1 -0
  40. package/dist/context.js +69 -0
  41. package/dist/context.js.map +1 -0
  42. package/dist/hooks/useAuth.d.ts +11 -0
  43. package/dist/hooks/useAuth.d.ts.map +1 -0
  44. package/dist/hooks/useAuth.js +34 -0
  45. package/dist/hooks/useAuth.js.map +1 -0
  46. package/dist/index.d.ts +49 -0
  47. package/dist/index.d.ts.map +1 -0
  48. package/dist/index.js +41 -0
  49. package/dist/index.js.map +1 -0
  50. package/dist/styles.css +344 -0
  51. package/llms.txt +106 -0
  52. package/package.json +65 -0
package/README.md ADDED
@@ -0,0 +1,180 @@
1
+ <h1 align="center">@edge-base/auth-ui-react</h1>
2
+
3
+ <p align="center">
4
+ <b>Pre-built React authentication UI for EdgeBase</b><br>
5
+ Drop in a provider, forms, and auth helpers on top of the EdgeBase web client
6
+ </p>
7
+
8
+ <p align="center">
9
+ <a href="https://www.npmjs.com/package/@edge-base/auth-ui-react"><img src="https://img.shields.io/npm/v/%40edge-base%2Fauth-ui-react?color=brightgreen" alt="npm"></a>&nbsp;
10
+ <a href="https://edgebase.fun/docs/authentication"><img src="https://img.shields.io/badge/docs-auth-blue" alt="Docs"></a>&nbsp;
11
+ <a href="https://github.com/edge-base/edgebase/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="MIT License"></a>
12
+ </p>
13
+
14
+ <p align="center">
15
+ React · Vite · Next.js · SPA auth flows · Email/password · OAuth · MFA
16
+ </p>
17
+
18
+ <p align="center">
19
+ <a href="https://edgebase.fun/docs/authentication"><b>Authentication</b></a> ·
20
+ <a href="https://edgebase.fun/docs/authentication/email-password"><b>Email/Password</b></a> ·
21
+ <a href="https://edgebase.fun/docs/authentication/magic-link"><b>Magic Link</b></a> ·
22
+ <a href="https://edgebase.fun/docs/authentication/mfa"><b>MFA</b></a> ·
23
+ <a href="https://edgebase.fun/docs/sdks/nextjs"><b>Next.js Guide</b></a>
24
+ </p>
25
+
26
+ ---
27
+
28
+ `@edge-base/auth-ui-react` adds ready-to-use React auth components on top of [`@edge-base/web`](https://www.npmjs.com/package/@edge-base/web).
29
+
30
+ It is a good fit when you want:
31
+
32
+ - a working sign-in and sign-up UI quickly
33
+ - OAuth, magic link, OTP, and MFA flows without rebuilding every screen
34
+ - a headless-first component set that still ships a default stylesheet
35
+ - a simple auth context and `useAuth()` hook for the current user
36
+
37
+ This package is for React in browser-oriented apps. It is not the admin SDK, and it is not a React Native package.
38
+
39
+ > Beta: the package is already usable, but some APIs and components may still evolve before general availability.
40
+
41
+ ## Documentation Map
42
+
43
+ - [Authentication Overview](https://edgebase.fun/docs/authentication)
44
+ Core auth concepts and flow selection
45
+ - [Email/Password](https://edgebase.fun/docs/authentication/email-password)
46
+ Standard credential sign-in flows
47
+ - [Magic Link](https://edgebase.fun/docs/authentication/magic-link)
48
+ Passwordless email flows
49
+ - [Email OTP](https://edgebase.fun/docs/authentication/email-otp)
50
+ One-time code flows
51
+ - [MFA](https://edgebase.fun/docs/authentication/mfa)
52
+ Multi-factor authentication setup and verification
53
+ - [Next.js Integration](https://edgebase.fun/docs/sdks/nextjs)
54
+ Example integration in a full React framework
55
+
56
+ ## For AI Coding Assistants
57
+
58
+ This package ships with an `llms.txt` file for AI-assisted React auth integration.
59
+
60
+ You can find it:
61
+
62
+ - after install: `node_modules/@edge-base/auth-ui-react/llms.txt`
63
+ - in the repository: [llms.txt](https://github.com/edge-base/edgebase/blob/main/packages/sdk/js/packages/auth-ui-react/llms.txt)
64
+
65
+ Use it when you want an agent to:
66
+
67
+ - wrap the app with `AuthProvider` correctly
68
+ - pair this package with `@edge-base/web` instead of `admin` or `ssr`
69
+ - choose between `AuthForm`, individual components, and `useAuth()`
70
+ - avoid guessing config field names or default views
71
+
72
+ ## Installation
73
+
74
+ ```bash
75
+ npm install @edge-base/web @edge-base/auth-ui-react
76
+ ```
77
+
78
+ Make sure your app already has React and React DOM.
79
+
80
+ ## Quick Start
81
+
82
+ ```tsx
83
+ import { createClient } from '@edge-base/web';
84
+ import { AuthProvider, AuthForm } from '@edge-base/auth-ui-react';
85
+ import '@edge-base/auth-ui-react/styles.css';
86
+
87
+ const client = createClient('https://your-project.edgebase.fun');
88
+
89
+ export function LoginScreen() {
90
+ return (
91
+ <AuthProvider
92
+ client={client}
93
+ config={{
94
+ providers: ['google', 'github'],
95
+ magicLinkEnabled: true,
96
+ }}
97
+ >
98
+ <AuthForm onSuccess={() => window.location.assign('/dashboard')} />
99
+ </AuthProvider>
100
+ );
101
+ }
102
+ ```
103
+
104
+ ## Core Building Blocks
105
+
106
+ | Export | Use it for |
107
+ | --- | --- |
108
+ | `AuthProvider` | Provide the EdgeBase web client and shared UI config |
109
+ | `AuthForm` | A full auth flow wrapper that switches between common views |
110
+ | `SignIn`, `SignUp` | Individual credential screens |
111
+ | `SocialButtons` | OAuth provider buttons |
112
+ | `MagicLink`, `EmailOTP`, `PhoneOTP` | Alternative sign-in flows |
113
+ | `ForgotPassword`, `MFAChallenge` | Recovery and multi-factor flows |
114
+ | `useAuth()` | Read the current user, loading state, and sign out |
115
+ | `useAuthContext()` | Access the raw provider context when building custom UI |
116
+
117
+ ## Auth Context
118
+
119
+ If you want your own UI while still using the provided auth state hook:
120
+
121
+ ```tsx
122
+ import { useAuth } from '@edge-base/auth-ui-react';
123
+
124
+ function HeaderActions() {
125
+ const { user, loading, signOut } = useAuth();
126
+
127
+ if (loading) return <span>Loading...</span>;
128
+ if (!user) return <a href="/login">Sign in</a>;
129
+
130
+ return (
131
+ <button onClick={() => void signOut()}>
132
+ Sign out {user.displayName ?? user.email}
133
+ </button>
134
+ );
135
+ }
136
+ ```
137
+
138
+ ## Configuration
139
+
140
+ `AuthProvider` accepts a `config` object for common flow choices:
141
+
142
+ - `providers`
143
+ - `defaultView`
144
+ - `showForgotPassword`
145
+ - `showToggle`
146
+ - `oauthRedirectUrl`
147
+ - `magicLinkEnabled`
148
+ - `emailOtpEnabled`
149
+ - `phoneOtpEnabled`
150
+ - `classPrefix`
151
+ - `localization`
152
+
153
+ The default `classPrefix` is `eb-auth`.
154
+
155
+ ## Styling
156
+
157
+ You have two good options:
158
+
159
+ 1. import the default stylesheet:
160
+
161
+ ```tsx
162
+ import '@edge-base/auth-ui-react/styles.css';
163
+ ```
164
+
165
+ 2. keep the components headless-first and target the generated CSS classes using your own design system
166
+
167
+ The generated classes use the configured prefix, so the default form class names look like `eb-auth-form`, `eb-auth-button`, and `eb-auth-error`.
168
+
169
+ ## Choose The Right Package
170
+
171
+ | Package | Use it for |
172
+ | --- | --- |
173
+ | `@edge-base/web` | The underlying browser SDK and auth client |
174
+ | `@edge-base/auth-ui-react` | Pre-built React auth components on top of the web SDK |
175
+ | `@edge-base/ssr` | Cookie-based server-side auth handling |
176
+ | `@edge-base/admin` | Trusted server-side admin tasks |
177
+
178
+ ## License
179
+
180
+ MIT
@@ -0,0 +1,11 @@
1
+ import type { AuthView } from '../context.js';
2
+ export interface AuthFormProps {
3
+ /** Called after successful authentication */
4
+ onSuccess?: () => void;
5
+ /** Override initial view (default uses config.defaultView or 'sign_in') */
6
+ defaultView?: AuthView;
7
+ /** Additional CSS class */
8
+ className?: string;
9
+ }
10
+ export declare function AuthForm({ onSuccess, defaultView, className }: AuthFormProps): import("react/jsx-runtime").JSX.Element | null;
11
+ //# sourceMappingURL=AuthForm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuthForm.d.ts","sourceRoot":"","sources":["../../src/components/AuthForm.tsx"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAW9C,MAAM,WAAW,aAAa;IAC5B,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,2EAA2E;IAC3E,WAAW,CAAC,EAAE,QAAQ,CAAC;IACvB,2BAA2B;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,QAAQ,CAAC,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,EAAE,aAAa,kDA8H5E"}
@@ -0,0 +1,71 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * AuthForm — full authentication flow orchestrator.
4
+ *
5
+ * Manages view state and renders the appropriate sub-component.
6
+ * Combines SignIn, SignUp, SocialButtons, MFAChallenge, ForgotPassword,
7
+ * MagicLink, EmailOTP, and PhoneOTP into a single cohesive flow.
8
+ *
9
+ * Usage:
10
+ * ```tsx
11
+ * <AuthProvider client={client} config={{ providers: ['google', 'github'] }}>
12
+ * <AuthForm onSuccess={() => navigate('/dashboard')} />
13
+ * </AuthProvider>
14
+ * ```
15
+ */
16
+ import { useState, useCallback } from 'react';
17
+ import { useAuthContext } from '../context.js';
18
+ import { useAuth } from '../hooks/useAuth.js';
19
+ import { SignIn } from './SignIn.js';
20
+ import { SignUp } from './SignUp.js';
21
+ import { SocialButtons } from './SocialButtons.js';
22
+ import { MFAChallenge } from './MFAChallenge.js';
23
+ import { ForgotPassword } from './ForgotPassword.js';
24
+ import { MagicLink } from './MagicLink.js';
25
+ import { EmailOTP } from './EmailOTP.js';
26
+ import { PhoneOTP } from './PhoneOTP.js';
27
+ export function AuthForm({ onSuccess, defaultView, className }) {
28
+ const { config } = useAuthContext();
29
+ const { user, loading } = useAuth();
30
+ const cx = config.classPrefix;
31
+ const [view, setView] = useState(defaultView || config.defaultView || 'sign_in');
32
+ const [mfaTicket, setMfaTicket] = useState(null);
33
+ const [mfaFactors, setMfaFactors] = useState([]);
34
+ const handleViewChange = useCallback((newView) => {
35
+ setView(newView);
36
+ }, []);
37
+ const handleSuccess = useCallback(() => {
38
+ onSuccess?.();
39
+ }, [onSuccess]);
40
+ const handleMfaRequired = useCallback((ticket, factors) => {
41
+ setMfaTicket(ticket);
42
+ setMfaFactors(factors);
43
+ setView('mfa_challenge');
44
+ }, []);
45
+ const handleMfaCancel = useCallback(() => {
46
+ setMfaTicket(null);
47
+ setMfaFactors([]);
48
+ setView('sign_in');
49
+ }, []);
50
+ // Loading state
51
+ if (loading) {
52
+ return (_jsx("div", { className: `${cx}-container ${cx}-loading ${className || ''}`.trim(), children: _jsx("p", { children: config.localization?.loading || 'Loading...' }) }));
53
+ }
54
+ // Already authenticated
55
+ if (user) {
56
+ return null;
57
+ }
58
+ // Build alternative sign-in methods links
59
+ const altMethods = [];
60
+ if (config.magicLinkEnabled && view !== 'magic_link') {
61
+ altMethods.push({ view: 'magic_link', label: 'Sign in with Magic Link' });
62
+ }
63
+ if (config.emailOtpEnabled && view !== 'email_otp') {
64
+ altMethods.push({ view: 'email_otp', label: 'Sign in with Email Code' });
65
+ }
66
+ if (config.phoneOtpEnabled && view !== 'phone_otp') {
67
+ altMethods.push({ view: 'phone_otp', label: 'Sign in with Phone' });
68
+ }
69
+ return (_jsxs("div", { className: `${cx}-container ${className || ''}`.trim(), children: [view === 'sign_in' && (_jsx(SignIn, { onSuccess: handleSuccess, onMfaRequired: handleMfaRequired, onViewChange: handleViewChange })), view === 'sign_up' && (_jsx(SignUp, { onSuccess: handleSuccess, onViewChange: handleViewChange })), view === 'forgot_password' && (_jsx(ForgotPassword, { onViewChange: handleViewChange })), view === 'magic_link' && (_jsx(MagicLink, { onViewChange: handleViewChange })), view === 'email_otp' && (_jsx(EmailOTP, { onSuccess: handleSuccess, onViewChange: handleViewChange })), view === 'phone_otp' && (_jsx(PhoneOTP, { onSuccess: handleSuccess, onViewChange: handleViewChange })), view === 'mfa_challenge' && mfaTicket && (_jsx(MFAChallenge, { mfaTicket: mfaTicket, factors: mfaFactors, onSuccess: handleSuccess, onCancel: handleMfaCancel })), (view === 'sign_in' || view === 'sign_up') && (_jsx(SocialButtons, {})), (view === 'sign_in' || view === 'sign_up') && altMethods.length > 0 && (_jsx("div", { className: `${cx}-alt-methods`, children: altMethods.map(({ view: altView, label }) => (_jsx("button", { type: "button", className: `${cx}-link ${cx}-alt-method`, onClick: () => handleViewChange(altView), children: label }, altView))) }))] }));
70
+ }
71
+ //# sourceMappingURL=AuthForm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuthForm.js","sourceRoot":"","sources":["../../src/components/AuthForm.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { AuthView } from '../context.js';
2
+ export interface EmailOTPProps {
3
+ /** Called after successful sign-in */
4
+ onSuccess?: () => void;
5
+ /** Called to switch to another view */
6
+ onViewChange?: (view: AuthView) => void;
7
+ /** Additional CSS class */
8
+ className?: string;
9
+ }
10
+ export declare function EmailOTP({ onSuccess, onViewChange, className }: EmailOTPProps): import("react/jsx-runtime").JSX.Element;
11
+ //# sourceMappingURL=EmailOTP.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EmailOTP.d.ts","sourceRoot":"","sources":["../../src/components/EmailOTP.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,MAAM,WAAW,aAAa;IAC5B,sCAAsC;IACtC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,uCAAuC;IACvC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC;IACxC,2BAA2B;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,QAAQ,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,EAAE,aAAa,2CA4I7E"}
@@ -0,0 +1,56 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * EmailOTP — email one-time-password sign-in form.
4
+ *
5
+ * Two-step flow: 1) Enter email → send code, 2) Enter code → verify.
6
+ */
7
+ import { useState, useCallback } from 'react';
8
+ import { useAuthContext } from '../context.js';
9
+ export function EmailOTP({ onSuccess, onViewChange, className }) {
10
+ const { client, config, labels } = useAuthContext();
11
+ const cx = config.classPrefix;
12
+ const [email, setEmail] = useState('');
13
+ const [code, setCode] = useState('');
14
+ const [step, setStep] = useState('email');
15
+ const [error, setError] = useState(null);
16
+ const [loading, setLoading] = useState(false);
17
+ const handleSendCode = useCallback(async (e) => {
18
+ e.preventDefault();
19
+ setError(null);
20
+ setLoading(true);
21
+ try {
22
+ await client.auth.signInWithEmailOtp({ email });
23
+ setStep('code');
24
+ }
25
+ catch (err) {
26
+ setError(err.message || 'Failed to send code');
27
+ }
28
+ finally {
29
+ setLoading(false);
30
+ }
31
+ }, [client, email]);
32
+ const handleVerify = useCallback(async (e) => {
33
+ e.preventDefault();
34
+ setError(null);
35
+ setLoading(true);
36
+ try {
37
+ await client.auth.verifyEmailOtp({ email, code });
38
+ onSuccess?.();
39
+ }
40
+ catch (err) {
41
+ setError(err.message || 'Verification failed');
42
+ }
43
+ finally {
44
+ setLoading(false);
45
+ }
46
+ }, [client, email, code, onSuccess]);
47
+ if (step === 'code') {
48
+ return (_jsxs("form", { className: `${cx}-form ${cx}-email-otp ${className || ''}`.trim(), onSubmit: handleVerify, children: [_jsx("h2", { className: `${cx}-title`, children: labels.verifyCode }), _jsxs("p", { className: `${cx}-description`, children: ["Enter the code sent to ", email] }), error && _jsx("div", { className: `${cx}-error`, children: error }), _jsxs("div", { className: `${cx}-field`, children: [_jsx("label", { className: `${cx}-label`, htmlFor: `${cx}-email-otp-code`, children: labels.code }), _jsx("input", { id: `${cx}-email-otp-code`, className: `${cx}-input ${cx}-input-code`, type: "text", inputMode: "numeric", value: code, onChange: (e) => setCode(e.target.value), required: true, autoComplete: "one-time-code", placeholder: "000000", disabled: loading, autoFocus: true })] }), _jsx("button", { type: "submit", className: `${cx}-button ${cx}-button-primary`, disabled: loading, children: loading ? labels.loading : labels.verifyCode }), _jsx("button", { type: "button", className: `${cx}-link`, onClick: () => {
49
+ setStep('email');
50
+ setCode('');
51
+ setError(null);
52
+ }, children: "Change email" })] }));
53
+ }
54
+ return (_jsxs("form", { className: `${cx}-form ${cx}-email-otp ${className || ''}`.trim(), onSubmit: handleSendCode, children: [_jsx("h2", { className: `${cx}-title`, children: labels.sendOTP }), _jsx("p", { className: `${cx}-description`, children: "Enter your email to receive a one-time sign-in code." }), error && _jsx("div", { className: `${cx}-error`, children: error }), _jsxs("div", { className: `${cx}-field`, children: [_jsx("label", { className: `${cx}-label`, htmlFor: `${cx}-email-otp-email`, children: labels.email }), _jsx("input", { id: `${cx}-email-otp-email`, className: `${cx}-input`, type: "email", value: email, onChange: (e) => setEmail(e.target.value), required: true, autoComplete: "email", disabled: loading })] }), _jsx("button", { type: "submit", className: `${cx}-button ${cx}-button-primary`, disabled: loading, children: loading ? labels.loading : labels.sendOTP }), _jsx("button", { type: "button", className: `${cx}-link`, onClick: () => onViewChange?.('sign_in'), children: labels.backToSignIn })] }));
55
+ }
56
+ //# sourceMappingURL=EmailOTP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EmailOTP.js","sourceRoot":"","sources":["../../src/components/EmailOTP.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { AuthView } from '../context.js';
2
+ export interface ForgotPasswordProps {
3
+ /** Called to switch to another view */
4
+ onViewChange?: (view: AuthView) => void;
5
+ /** Additional CSS class */
6
+ className?: string;
7
+ }
8
+ export declare function ForgotPassword({ onViewChange, className }: ForgotPasswordProps): import("react/jsx-runtime").JSX.Element;
9
+ //# sourceMappingURL=ForgotPassword.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ForgotPassword.d.ts","sourceRoot":"","sources":["../../src/components/ForgotPassword.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,MAAM,WAAW,mBAAmB;IAClC,uCAAuC;IACvC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC;IACxC,2BAA2B;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,cAAc,CAAC,EAAE,YAAY,EAAE,SAAS,EAAE,EAAE,mBAAmB,2CAuF9E"}
@@ -0,0 +1,36 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * ForgotPassword — password reset request form.
4
+ *
5
+ * Sends a reset email to the user.
6
+ */
7
+ import { useState, useCallback } from 'react';
8
+ import { useAuthContext } from '../context.js';
9
+ export function ForgotPassword({ onViewChange, className }) {
10
+ const { client, config, labels } = useAuthContext();
11
+ const cx = config.classPrefix;
12
+ const [email, setEmail] = useState('');
13
+ const [error, setError] = useState(null);
14
+ const [success, setSuccess] = useState(false);
15
+ const [loading, setLoading] = useState(false);
16
+ const handleSubmit = useCallback(async (e) => {
17
+ e.preventDefault();
18
+ setError(null);
19
+ setLoading(true);
20
+ try {
21
+ await client.auth.requestPasswordReset(email);
22
+ setSuccess(true);
23
+ }
24
+ catch (err) {
25
+ setError(err.message || 'Failed to send reset email');
26
+ }
27
+ finally {
28
+ setLoading(false);
29
+ }
30
+ }, [client, email]);
31
+ if (success) {
32
+ return (_jsxs("div", { className: `${cx}-form ${cx}-forgot-password ${cx}-success ${className || ''}`.trim(), children: [_jsx("h2", { className: `${cx}-title`, children: labels.resetPassword }), _jsx("p", { className: `${cx}-description`, children: "Check your email for a password reset link." }), _jsx("button", { type: "button", className: `${cx}-link`, onClick: () => onViewChange?.('sign_in'), children: labels.backToSignIn })] }));
33
+ }
34
+ return (_jsxs("form", { className: `${cx}-form ${cx}-forgot-password ${className || ''}`.trim(), onSubmit: handleSubmit, children: [_jsx("h2", { className: `${cx}-title`, children: labels.resetPassword }), _jsx("p", { className: `${cx}-description`, children: "Enter your email address and we'll send you a link to reset your password." }), error && _jsx("div", { className: `${cx}-error`, children: error }), _jsxs("div", { className: `${cx}-field`, children: [_jsx("label", { className: `${cx}-label`, htmlFor: `${cx}-reset-email`, children: labels.email }), _jsx("input", { id: `${cx}-reset-email`, className: `${cx}-input`, type: "email", value: email, onChange: (e) => setEmail(e.target.value), required: true, autoComplete: "email", disabled: loading })] }), _jsx("button", { type: "submit", className: `${cx}-button ${cx}-button-primary`, disabled: loading, children: loading ? labels.loading : labels.sendResetLink }), _jsx("button", { type: "button", className: `${cx}-link`, onClick: () => onViewChange?.('sign_in'), children: labels.backToSignIn })] }));
35
+ }
36
+ //# sourceMappingURL=ForgotPassword.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ForgotPassword.js","sourceRoot":"","sources":["../../src/components/ForgotPassword.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ export interface MFAChallengeProps {
2
+ /** MFA ticket from sign-in result */
3
+ mfaTicket: string;
4
+ /** Available MFA factors */
5
+ factors: Array<{
6
+ id: string;
7
+ type: string;
8
+ }>;
9
+ /** Called after successful MFA verification */
10
+ onSuccess?: () => void;
11
+ /** Called when user wants to go back */
12
+ onCancel?: () => void;
13
+ /** Additional CSS class */
14
+ className?: string;
15
+ }
16
+ export declare function MFAChallenge({ mfaTicket, factors, onSuccess, onCancel, className, }: MFAChallengeProps): import("react/jsx-runtime").JSX.Element;
17
+ //# sourceMappingURL=MFAChallenge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MFAChallenge.d.ts","sourceRoot":"","sources":["../../src/components/MFAChallenge.tsx"],"names":[],"mappings":"AAQA,MAAM,WAAW,iBAAiB;IAChC,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,4BAA4B;IAC5B,OAAO,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7C,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,wCAAwC;IACxC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,2BAA2B;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,YAAY,CAAC,EAC3B,SAAS,EACT,OAAO,EACP,SAAS,EACT,QAAQ,EACR,SAAS,GACV,EAAE,iBAAiB,2CA+FnB"}
@@ -0,0 +1,44 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * MFAChallenge — TOTP verification form shown when MFA is required during sign-in.
4
+ *
5
+ * Supports TOTP code entry and recovery code fallback.
6
+ */
7
+ import { useState, useCallback } from 'react';
8
+ import { useAuthContext } from '../context.js';
9
+ export function MFAChallenge({ mfaTicket, factors, onSuccess, onCancel, className, }) {
10
+ const { client, config, labels } = useAuthContext();
11
+ const cx = config.classPrefix;
12
+ const [code, setCode] = useState('');
13
+ const [error, setError] = useState(null);
14
+ const [loading, setLoading] = useState(false);
15
+ const [useRecovery, setUseRecovery] = useState(false);
16
+ const handleSubmit = useCallback(async (e) => {
17
+ e.preventDefault();
18
+ setError(null);
19
+ setLoading(true);
20
+ try {
21
+ if (useRecovery) {
22
+ await client.auth.mfa.useRecoveryCode(mfaTicket, code);
23
+ }
24
+ else {
25
+ await client.auth.mfa.verifyTotp(mfaTicket, code);
26
+ }
27
+ onSuccess?.();
28
+ }
29
+ catch (err) {
30
+ setError(err.message || 'Verification failed');
31
+ }
32
+ finally {
33
+ setLoading(false);
34
+ }
35
+ }, [client, mfaTicket, code, useRecovery, onSuccess]);
36
+ return (_jsxs("form", { className: `${cx}-form ${cx}-mfa-challenge ${className || ''}`.trim(), onSubmit: handleSubmit, children: [_jsx("h2", { className: `${cx}-title`, children: useRecovery ? 'Recovery Code' : 'Two-Factor Authentication' }), _jsx("p", { className: `${cx}-description`, children: useRecovery
37
+ ? 'Enter one of your recovery codes to sign in.'
38
+ : 'Enter the 6-digit code from your authenticator app.' }), error && _jsx("div", { className: `${cx}-error`, children: error }), _jsxs("div", { className: `${cx}-field`, children: [_jsx("label", { className: `${cx}-label`, htmlFor: `${cx}-mfa-code`, children: useRecovery ? 'Recovery Code' : labels.code }), _jsx("input", { id: `${cx}-mfa-code`, className: `${cx}-input ${cx}-input-code`, type: "text", value: code, onChange: (e) => setCode(e.target.value), required: true, autoComplete: "one-time-code", placeholder: useRecovery ? 'XXXXX-XXXXX' : '000000', disabled: loading, autoFocus: true })] }), _jsx("button", { type: "submit", className: `${cx}-button ${cx}-button-primary`, disabled: loading, children: loading ? labels.loading : labels.verifyCode }), _jsxs("div", { className: `${cx}-mfa-actions`, children: [_jsx("button", { type: "button", className: `${cx}-link`, onClick: () => {
39
+ setUseRecovery(!useRecovery);
40
+ setCode('');
41
+ setError(null);
42
+ }, children: useRecovery ? 'Use authenticator code' : 'Use recovery code' }), onCancel && (_jsx("button", { type: "button", className: `${cx}-link`, onClick: onCancel, children: labels.backToSignIn }))] })] }));
43
+ }
44
+ //# sourceMappingURL=MFAChallenge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MFAChallenge.js","sourceRoot":"","sources":["../../src/components/MFAChallenge.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { AuthView } from '../context.js';
2
+ export interface MagicLinkProps {
3
+ /** Called to switch to another view */
4
+ onViewChange?: (view: AuthView) => void;
5
+ /** Additional CSS class */
6
+ className?: string;
7
+ }
8
+ export declare function MagicLink({ onViewChange, className }: MagicLinkProps): import("react/jsx-runtime").JSX.Element;
9
+ //# sourceMappingURL=MagicLink.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MagicLink.d.ts","sourceRoot":"","sources":["../../src/components/MagicLink.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,MAAM,WAAW,cAAc;IAC7B,uCAAuC;IACvC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC;IACxC,2BAA2B;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,SAAS,CAAC,EAAE,YAAY,EAAE,SAAS,EAAE,EAAE,cAAc,2CA0FpE"}
@@ -0,0 +1,39 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * MagicLink — passwordless sign-in via email link.
4
+ *
5
+ * Sends a magic link to the user's email.
6
+ */
7
+ import { useState, useCallback } from 'react';
8
+ import { useAuthContext } from '../context.js';
9
+ export function MagicLink({ onViewChange, className }) {
10
+ const { client, config, labels } = useAuthContext();
11
+ const cx = config.classPrefix;
12
+ const [email, setEmail] = useState('');
13
+ const [error, setError] = useState(null);
14
+ const [success, setSuccess] = useState(false);
15
+ const [loading, setLoading] = useState(false);
16
+ const handleSubmit = useCallback(async (e) => {
17
+ e.preventDefault();
18
+ setError(null);
19
+ setLoading(true);
20
+ try {
21
+ await client.auth.signInWithMagicLink({ email });
22
+ setSuccess(true);
23
+ }
24
+ catch (err) {
25
+ setError(err.message || 'Failed to send magic link');
26
+ }
27
+ finally {
28
+ setLoading(false);
29
+ }
30
+ }, [client, email]);
31
+ if (success) {
32
+ return (_jsxs("div", { className: `${cx}-form ${cx}-magic-link ${cx}-success ${className || ''}`.trim(), children: [_jsx("h2", { className: `${cx}-title`, children: labels.sendMagicLink }), _jsx("p", { className: `${cx}-description`, children: "Check your email for a sign-in link." }), _jsx("button", { type: "button", className: `${cx}-link`, onClick: () => {
33
+ setSuccess(false);
34
+ setEmail('');
35
+ }, children: "Send another link" })] }));
36
+ }
37
+ return (_jsxs("form", { className: `${cx}-form ${cx}-magic-link ${className || ''}`.trim(), onSubmit: handleSubmit, children: [_jsx("h2", { className: `${cx}-title`, children: labels.sendMagicLink }), _jsx("p", { className: `${cx}-description`, children: "Enter your email and we'll send you a link to sign in." }), error && _jsx("div", { className: `${cx}-error`, children: error }), _jsxs("div", { className: `${cx}-field`, children: [_jsx("label", { className: `${cx}-label`, htmlFor: `${cx}-magic-email`, children: labels.email }), _jsx("input", { id: `${cx}-magic-email`, className: `${cx}-input`, type: "email", value: email, onChange: (e) => setEmail(e.target.value), required: true, autoComplete: "email", disabled: loading })] }), _jsx("button", { type: "submit", className: `${cx}-button ${cx}-button-primary`, disabled: loading, children: loading ? labels.loading : labels.sendMagicLink }), _jsx("button", { type: "button", className: `${cx}-link`, onClick: () => onViewChange?.('sign_in'), children: labels.backToSignIn })] }));
38
+ }
39
+ //# sourceMappingURL=MagicLink.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MagicLink.js","sourceRoot":"","sources":["../../src/components/MagicLink.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { AuthView } from '../context.js';
2
+ export interface PhoneOTPProps {
3
+ /** Called after successful sign-in */
4
+ onSuccess?: () => void;
5
+ /** Called to switch to another view */
6
+ onViewChange?: (view: AuthView) => void;
7
+ /** Additional CSS class */
8
+ className?: string;
9
+ }
10
+ export declare function PhoneOTP({ onSuccess, onViewChange, className }: PhoneOTPProps): import("react/jsx-runtime").JSX.Element;
11
+ //# sourceMappingURL=PhoneOTP.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PhoneOTP.d.ts","sourceRoot":"","sources":["../../src/components/PhoneOTP.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,MAAM,WAAW,aAAa;IAC5B,sCAAsC;IACtC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,uCAAuC;IACvC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC;IACxC,2BAA2B;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,QAAQ,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,EAAE,aAAa,2CA6I7E"}