@djangocfg/api 2.1.37 → 2.1.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +94 -56
- package/dist/auth.cjs +12 -65
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.d.cts +5 -7
- package/dist/auth.d.ts +5 -7
- package/dist/auth.mjs +12 -65
- package/dist/auth.mjs.map +1 -1
- package/package.json +3 -3
- package/src/auth/context/AuthContext.tsx +8 -71
- package/src/auth/context/types.ts +1 -9
- package/src/auth/hooks/useAuthForm.ts +11 -7
package/README.md
CHANGED
|
@@ -88,13 +88,13 @@ This is handled automatically by `createExtensionAPI()` from `@djangocfg/ext-bas
|
|
|
88
88
|
|
|
89
89
|
## Auth Module
|
|
90
90
|
|
|
91
|
-
Complete authentication system with React contexts, hooks, and utilities.
|
|
91
|
+
Complete OTP-based authentication system with React contexts, hooks, and utilities.
|
|
92
92
|
|
|
93
93
|
### Setup
|
|
94
94
|
|
|
95
95
|
```tsx
|
|
96
96
|
// app/layout.tsx
|
|
97
|
-
import { AuthProvider
|
|
97
|
+
import { AuthProvider } from '@djangocfg/api/auth';
|
|
98
98
|
|
|
99
99
|
export default function RootLayout({ children }) {
|
|
100
100
|
return (
|
|
@@ -108,9 +108,7 @@ export default function RootLayout({ children }) {
|
|
|
108
108
|
}
|
|
109
109
|
}}
|
|
110
110
|
>
|
|
111
|
-
|
|
112
|
-
{children}
|
|
113
|
-
</AccountsProvider>
|
|
111
|
+
{children}
|
|
114
112
|
</AuthProvider>
|
|
115
113
|
</body>
|
|
116
114
|
</html>
|
|
@@ -122,9 +120,9 @@ export default function RootLayout({ children }) {
|
|
|
122
120
|
|
|
123
121
|
```typescript
|
|
124
122
|
import {
|
|
125
|
-
useAuth, // Main auth context (user, isAuthenticated,
|
|
123
|
+
useAuth, // Main auth context (user, isAuthenticated, OTP methods)
|
|
126
124
|
useAuthGuard, // Protect routes (redirect if not authenticated)
|
|
127
|
-
useAuthForm, //
|
|
125
|
+
useAuthForm, // OTP form state management (identifier, otp, steps)
|
|
128
126
|
useGithubAuth, // GitHub OAuth integration
|
|
129
127
|
useAutoAuth, // Auto-authentication on mount
|
|
130
128
|
useLocalStorage, // localStorage helper
|
|
@@ -134,7 +132,7 @@ import {
|
|
|
134
132
|
|
|
135
133
|
### useAuth
|
|
136
134
|
|
|
137
|
-
Main authentication hook:
|
|
135
|
+
Main authentication hook with OTP support:
|
|
138
136
|
|
|
139
137
|
```tsx
|
|
140
138
|
'use client';
|
|
@@ -145,16 +143,15 @@ export function UserProfile() {
|
|
|
145
143
|
user, // UserProfile | null
|
|
146
144
|
isAuthenticated, // boolean
|
|
147
145
|
isLoading, // boolean
|
|
148
|
-
|
|
146
|
+
requestOTP, // (identifier, channel, sourceUrl?) => Promise<{ success, message }>
|
|
147
|
+
verifyOTP, // (identifier, otp, channel, sourceUrl?, redirectUrl?) => Promise<{ success, message, user? }>
|
|
149
148
|
logout, // () => Promise<void>
|
|
150
|
-
register, // (data) => Promise<void>
|
|
151
|
-
updateProfile, // (data) => Promise<void>
|
|
152
149
|
} = useAuth();
|
|
153
150
|
|
|
154
151
|
if (isLoading) return <div>Loading...</div>;
|
|
155
152
|
|
|
156
153
|
if (!isAuthenticated) {
|
|
157
|
-
return <
|
|
154
|
+
return <div>Please sign in</div>;
|
|
158
155
|
}
|
|
159
156
|
|
|
160
157
|
return (
|
|
@@ -188,46 +185,98 @@ export default function DashboardPage() {
|
|
|
188
185
|
|
|
189
186
|
### useAuthForm
|
|
190
187
|
|
|
191
|
-
Manage authentication form state:
|
|
188
|
+
Manage OTP authentication form state (two-step flow):
|
|
192
189
|
|
|
193
190
|
```tsx
|
|
194
191
|
'use client';
|
|
195
192
|
import { useAuthForm } from '@djangocfg/api/auth';
|
|
196
193
|
|
|
197
|
-
export function
|
|
194
|
+
export function OTPLoginForm() {
|
|
198
195
|
const {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
196
|
+
// State
|
|
197
|
+
identifier, // Email or phone number
|
|
198
|
+
channel, // 'email' | 'phone'
|
|
199
|
+
otp, // 6-digit OTP code
|
|
200
|
+
step, // 'identifier' | 'otp'
|
|
202
201
|
isLoading,
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
202
|
+
error,
|
|
203
|
+
acceptedTerms,
|
|
204
|
+
|
|
205
|
+
// Setters
|
|
206
|
+
setIdentifier,
|
|
207
|
+
setChannel,
|
|
208
|
+
setOtp,
|
|
209
|
+
setAcceptedTerms,
|
|
210
|
+
|
|
211
|
+
// Handlers
|
|
212
|
+
handleIdentifierSubmit, // Request OTP
|
|
213
|
+
handleOTPSubmit, // Verify OTP
|
|
214
|
+
handleResendOTP, // Resend OTP
|
|
215
|
+
handleBackToIdentifier, // Go back to step 1
|
|
216
|
+
|
|
217
|
+
// Utilities
|
|
218
|
+
detectChannelFromIdentifier,
|
|
219
|
+
validateIdentifier,
|
|
220
|
+
} = useAuthForm({
|
|
221
|
+
sourceUrl: window.location.origin,
|
|
222
|
+
requireTermsAcceptance: false, // Set true if terms/privacy links provided
|
|
223
|
+
onIdentifierSuccess: (identifier, channel) => {
|
|
224
|
+
console.log('OTP sent to', identifier);
|
|
225
|
+
},
|
|
226
|
+
onOTPSuccess: () => {
|
|
227
|
+
console.log('Login successful');
|
|
228
|
+
},
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
if (step === 'identifier') {
|
|
232
|
+
return (
|
|
233
|
+
<form onSubmit={handleIdentifierSubmit}>
|
|
234
|
+
<input
|
|
235
|
+
type="email"
|
|
236
|
+
value={identifier}
|
|
237
|
+
onChange={(e) => setIdentifier(e.target.value)}
|
|
238
|
+
placeholder="Enter email"
|
|
239
|
+
/>
|
|
240
|
+
{error && <p className="text-red-500">{error}</p>}
|
|
241
|
+
<button type="submit" disabled={isLoading}>
|
|
242
|
+
{isLoading ? 'Sending...' : 'Send verification code'}
|
|
243
|
+
</button>
|
|
244
|
+
</form>
|
|
245
|
+
);
|
|
246
|
+
}
|
|
209
247
|
|
|
210
248
|
return (
|
|
211
|
-
<form onSubmit={
|
|
249
|
+
<form onSubmit={handleOTPSubmit}>
|
|
250
|
+
<p>Enter the code sent to {identifier}</p>
|
|
212
251
|
<input
|
|
213
|
-
type="
|
|
214
|
-
value={
|
|
215
|
-
onChange={(e) =>
|
|
252
|
+
type="text"
|
|
253
|
+
value={otp}
|
|
254
|
+
onChange={(e) => setOtp(e.target.value)}
|
|
255
|
+
placeholder="000000"
|
|
256
|
+
maxLength={6}
|
|
216
257
|
/>
|
|
217
|
-
<
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
onChange={(e) => setPassword(e.target.value)}
|
|
221
|
-
/>
|
|
222
|
-
{error && <p>{error}</p>}
|
|
223
|
-
<button type="submit" disabled={isLoading}>
|
|
224
|
-
{isLoading ? 'Loading...' : 'Login'}
|
|
258
|
+
{error && <p className="text-red-500">{error}</p>}
|
|
259
|
+
<button type="submit" disabled={isLoading || otp.length < 6}>
|
|
260
|
+
{isLoading ? 'Verifying...' : 'Verify'}
|
|
225
261
|
</button>
|
|
262
|
+
<button type="button" onClick={handleResendOTP}>Resend</button>
|
|
263
|
+
<button type="button" onClick={handleBackToIdentifier}>Back</button>
|
|
226
264
|
</form>
|
|
227
265
|
);
|
|
228
266
|
}
|
|
229
267
|
```
|
|
230
268
|
|
|
269
|
+
#### useAuthForm Options
|
|
270
|
+
|
|
271
|
+
| Option | Type | Default | Description |
|
|
272
|
+
|--------|------|---------|-------------|
|
|
273
|
+
| `sourceUrl` | `string` | required | Application URL for OTP emails |
|
|
274
|
+
| `redirectUrl` | `string` | - | URL to redirect after successful OTP verification |
|
|
275
|
+
| `requireTermsAcceptance` | `boolean` | `false` | Require terms acceptance before submit |
|
|
276
|
+
| `onIdentifierSuccess` | `function` | - | Callback after OTP sent |
|
|
277
|
+
| `onOTPSuccess` | `function` | - | Callback after successful verification |
|
|
278
|
+
| `onError` | `function` | - | Callback on error |
|
|
279
|
+
|
|
231
280
|
### useGithubAuth
|
|
232
281
|
|
|
233
282
|
GitHub OAuth integration:
|
|
@@ -238,34 +287,23 @@ import { useGithubAuth } from '@djangocfg/api/auth';
|
|
|
238
287
|
|
|
239
288
|
export function GithubLoginButton() {
|
|
240
289
|
const {
|
|
241
|
-
|
|
242
|
-
isLoading,
|
|
243
|
-
error,
|
|
244
|
-
} = useGithubAuth(
|
|
290
|
+
startGithubAuth, // () => void - redirects to GitHub
|
|
291
|
+
isLoading, // boolean
|
|
292
|
+
error, // string | null
|
|
293
|
+
} = useGithubAuth({
|
|
294
|
+
sourceUrl: window.location.origin,
|
|
295
|
+
});
|
|
245
296
|
|
|
246
297
|
return (
|
|
247
|
-
<button onClick={
|
|
248
|
-
{isLoading ? 'Connecting...' : '
|
|
298
|
+
<button onClick={startGithubAuth} disabled={isLoading}>
|
|
299
|
+
{isLoading ? 'Connecting...' : 'Continue with GitHub'}
|
|
249
300
|
</button>
|
|
250
301
|
);
|
|
251
302
|
}
|
|
252
|
-
|
|
253
|
-
// app/auth/callback/github/page.tsx
|
|
254
|
-
'use client';
|
|
255
|
-
import { useGithubAuth } from '@djangocfg/api/auth';
|
|
256
|
-
import { useEffect } from 'react';
|
|
257
|
-
|
|
258
|
-
export default function GithubCallbackPage() {
|
|
259
|
-
const { handleGithubCallback } = useGithubAuth();
|
|
260
|
-
|
|
261
|
-
useEffect(() => {
|
|
262
|
-
handleGithubCallback();
|
|
263
|
-
}, []);
|
|
264
|
-
|
|
265
|
-
return <div>Processing GitHub login...</div>;
|
|
266
|
-
}
|
|
267
303
|
```
|
|
268
304
|
|
|
305
|
+
OAuth callback is handled automatically by `@djangocfg/layouts` AuthLayout component.
|
|
306
|
+
|
|
269
307
|
## Server Components & API Routes
|
|
270
308
|
|
|
271
309
|
Use fetchers for server-side data fetching:
|
package/dist/auth.cjs
CHANGED
|
@@ -3953,7 +3953,6 @@ var defaultRoutes = {
|
|
|
3953
3953
|
var AuthContext = (0, import_react2.createContext)(void 0);
|
|
3954
3954
|
var EMAIL_STORAGE_KEY = "auth_email";
|
|
3955
3955
|
var PHONE_STORAGE_KEY = "auth_phone";
|
|
3956
|
-
var AUTH_REDIRECT_KEY = "auth_redirect_url";
|
|
3957
3956
|
var hasValidTokens = /* @__PURE__ */ __name(() => {
|
|
3958
3957
|
if (typeof window === "undefined") return false;
|
|
3959
3958
|
return api.isAuthenticated();
|
|
@@ -3973,7 +3972,6 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
|
3973
3972
|
const queryParams = (0, import_hooks2.useQueryParams)();
|
|
3974
3973
|
const [storedEmail, setStoredEmail, clearStoredEmail] = (0, import_hooks2.useLocalStorage)(EMAIL_STORAGE_KEY, null);
|
|
3975
3974
|
const [storedPhone, setStoredPhone, clearStoredPhone] = (0, import_hooks2.useLocalStorage)(PHONE_STORAGE_KEY, null);
|
|
3976
|
-
const [redirectUrl, setRedirectUrl, clearRedirectUrl] = (0, import_hooks2.useLocalStorage)(AUTH_REDIRECT_KEY, null);
|
|
3977
3975
|
const user = accounts.profile;
|
|
3978
3976
|
const userRef = (0, import_react2.useRef)(user);
|
|
3979
3977
|
const configRef = (0, import_react2.useRef)(config);
|
|
@@ -4155,7 +4153,7 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
|
4155
4153
|
[accounts]
|
|
4156
4154
|
);
|
|
4157
4155
|
const verifyOTP = (0, import_react2.useCallback)(
|
|
4158
|
-
async (identifier, otpCode, channel, sourceUrl) => {
|
|
4156
|
+
async (identifier, otpCode, channel, sourceUrl, redirectUrl) => {
|
|
4159
4157
|
try {
|
|
4160
4158
|
const channelValue = channel === "phone" ? enums_exports.OTPVerifyRequestChannel.PHONE : enums_exports.OTPVerifyRequestChannel.EMAIL;
|
|
4161
4159
|
const result = await accounts.verifyOTP({
|
|
@@ -4185,13 +4183,8 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
|
4185
4183
|
if (result.user?.id) {
|
|
4186
4184
|
Analytics.setUser(String(result.user.id));
|
|
4187
4185
|
}
|
|
4188
|
-
const
|
|
4189
|
-
|
|
4190
|
-
clearRedirectUrl();
|
|
4191
|
-
router.hardPush(redirectUrl);
|
|
4192
|
-
} else {
|
|
4193
|
-
router.hardPush(defaultCallback);
|
|
4194
|
-
}
|
|
4186
|
+
const finalRedirectUrl = redirectUrl || config?.routes?.defaultCallback || defaultRoutes.defaultCallback;
|
|
4187
|
+
router.hardPush(finalRedirectUrl);
|
|
4195
4188
|
return {
|
|
4196
4189
|
success: true,
|
|
4197
4190
|
message: "Login successful",
|
|
@@ -4209,7 +4202,7 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
|
4209
4202
|
};
|
|
4210
4203
|
}
|
|
4211
4204
|
},
|
|
4212
|
-
[setStoredEmail, setStoredPhone, clearStoredEmail, clearStoredPhone,
|
|
4205
|
+
[setStoredEmail, setStoredPhone, clearStoredEmail, clearStoredPhone, config?.routes?.defaultCallback, accounts, router]
|
|
4213
4206
|
);
|
|
4214
4207
|
const refreshToken = (0, import_react2.useCallback)(async () => {
|
|
4215
4208
|
try {
|
|
@@ -4244,15 +4237,6 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
|
4244
4237
|
};
|
|
4245
4238
|
}
|
|
4246
4239
|
}, [clearAuthState, accounts]);
|
|
4247
|
-
const clearRedirect = (0, import_react2.useCallback)(() => {
|
|
4248
|
-
clearRedirectUrl();
|
|
4249
|
-
}, [clearRedirectUrl]);
|
|
4250
|
-
const saveCurrentUrlForRedirect = (0, import_react2.useCallback)(() => {
|
|
4251
|
-
if (typeof window !== "undefined") {
|
|
4252
|
-
const currentUrl = window.location.pathname + window.location.search;
|
|
4253
|
-
setRedirectUrl(currentUrl);
|
|
4254
|
-
}
|
|
4255
|
-
}, [setRedirectUrl]);
|
|
4256
4240
|
const logout = (0, import_react2.useCallback)(async () => {
|
|
4257
4241
|
const performLogout = /* @__PURE__ */ __name(() => {
|
|
4258
4242
|
Analytics.event("auth_logout" /* AUTH_LOGOUT */, {
|
|
@@ -4282,31 +4266,6 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
|
4282
4266
|
}
|
|
4283
4267
|
}
|
|
4284
4268
|
}, [accounts, config?.routes?.defaultAuthCallback, router]);
|
|
4285
|
-
const getSavedRedirectUrl = (0, import_react2.useCallback)(() => {
|
|
4286
|
-
if (typeof window !== "undefined") {
|
|
4287
|
-
return sessionStorage.getItem(AUTH_REDIRECT_KEY);
|
|
4288
|
-
}
|
|
4289
|
-
return null;
|
|
4290
|
-
}, []);
|
|
4291
|
-
const saveRedirectUrl = (0, import_react2.useCallback)((url) => {
|
|
4292
|
-
if (typeof window !== "undefined") {
|
|
4293
|
-
sessionStorage.setItem(AUTH_REDIRECT_KEY, url);
|
|
4294
|
-
}
|
|
4295
|
-
}, []);
|
|
4296
|
-
const clearSavedRedirectUrl = (0, import_react2.useCallback)(() => {
|
|
4297
|
-
if (typeof window !== "undefined") {
|
|
4298
|
-
sessionStorage.removeItem(AUTH_REDIRECT_KEY);
|
|
4299
|
-
}
|
|
4300
|
-
}, []);
|
|
4301
|
-
const getFinalRedirectUrl = (0, import_react2.useCallback)(() => {
|
|
4302
|
-
const savedUrl = getSavedRedirectUrl();
|
|
4303
|
-
return savedUrl || (config?.routes?.defaultCallback || defaultRoutes.defaultCallback);
|
|
4304
|
-
}, [getSavedRedirectUrl, config?.routes?.defaultCallback]);
|
|
4305
|
-
const useAndClearRedirectUrl = (0, import_react2.useCallback)(() => {
|
|
4306
|
-
const finalUrl = getFinalRedirectUrl();
|
|
4307
|
-
clearSavedRedirectUrl();
|
|
4308
|
-
return finalUrl;
|
|
4309
|
-
}, [getFinalRedirectUrl, clearSavedRedirectUrl]);
|
|
4310
4269
|
const isAdminUser = (0, import_react2.useMemo)(() => {
|
|
4311
4270
|
return Boolean(user?.is_staff || user?.is_superuser);
|
|
4312
4271
|
}, [user]);
|
|
@@ -4330,13 +4289,7 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
|
4330
4289
|
requestOTP,
|
|
4331
4290
|
verifyOTP,
|
|
4332
4291
|
refreshToken,
|
|
4333
|
-
logout
|
|
4334
|
-
getSavedRedirectUrl,
|
|
4335
|
-
saveRedirectUrl,
|
|
4336
|
-
clearSavedRedirectUrl,
|
|
4337
|
-
getFinalRedirectUrl,
|
|
4338
|
-
useAndClearRedirectUrl,
|
|
4339
|
-
saveCurrentUrlForRedirect
|
|
4292
|
+
logout
|
|
4340
4293
|
}),
|
|
4341
4294
|
[
|
|
4342
4295
|
user,
|
|
@@ -4353,13 +4306,7 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
|
|
|
4353
4306
|
requestOTP,
|
|
4354
4307
|
verifyOTP,
|
|
4355
4308
|
refreshToken,
|
|
4356
|
-
logout
|
|
4357
|
-
getSavedRedirectUrl,
|
|
4358
|
-
saveRedirectUrl,
|
|
4359
|
-
clearSavedRedirectUrl,
|
|
4360
|
-
getFinalRedirectUrl,
|
|
4361
|
-
useAndClearRedirectUrl,
|
|
4362
|
-
saveCurrentUrlForRedirect
|
|
4309
|
+
logout
|
|
4363
4310
|
]
|
|
4364
4311
|
);
|
|
4365
4312
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AuthContext.Provider, { value, children });
|
|
@@ -4517,10 +4464,10 @@ function useSessionStorage(key, initialValue) {
|
|
|
4517
4464
|
__name(useSessionStorage, "useSessionStorage");
|
|
4518
4465
|
|
|
4519
4466
|
// src/auth/hooks/useAuthRedirect.ts
|
|
4520
|
-
var
|
|
4467
|
+
var AUTH_REDIRECT_KEY = "auth_redirect_url";
|
|
4521
4468
|
var useAuthRedirectManager = /* @__PURE__ */ __name((options = {}) => {
|
|
4522
4469
|
const { fallbackUrl = "/dashboard", clearOnUse = true } = options;
|
|
4523
|
-
const [redirectUrl, setRedirectUrl, removeRedirectUrl] = useSessionStorage(
|
|
4470
|
+
const [redirectUrl, setRedirectUrl, removeRedirectUrl] = useSessionStorage(AUTH_REDIRECT_KEY, "");
|
|
4524
4471
|
const setRedirect = /* @__PURE__ */ __name((url) => {
|
|
4525
4472
|
setRedirectUrl(url);
|
|
4526
4473
|
}, "setRedirect");
|
|
@@ -4764,7 +4711,7 @@ var useAutoAuth = /* @__PURE__ */ __name((options = {}) => {
|
|
|
4764
4711
|
|
|
4765
4712
|
// src/auth/hooks/useAuthForm.ts
|
|
4766
4713
|
var useAuthForm = /* @__PURE__ */ __name((options) => {
|
|
4767
|
-
const { onIdentifierSuccess, onOTPSuccess, onError, sourceUrl } = options;
|
|
4714
|
+
const { onIdentifierSuccess, onOTPSuccess, onError, sourceUrl, redirectUrl, requireTermsAcceptance = false } = options;
|
|
4768
4715
|
const [identifier, setIdentifier] = (0, import_react7.useState)("");
|
|
4769
4716
|
const [channel, setChannel] = (0, import_react7.useState)("email");
|
|
4770
4717
|
const [otp, setOtp] = (0, import_react7.useState)("");
|
|
@@ -4833,7 +4780,7 @@ var useAuthForm = /* @__PURE__ */ __name((options) => {
|
|
|
4833
4780
|
onError?.(message);
|
|
4834
4781
|
return;
|
|
4835
4782
|
}
|
|
4836
|
-
if (!acceptedTerms) {
|
|
4783
|
+
if (requireTermsAcceptance && !acceptedTerms) {
|
|
4837
4784
|
const message = "Please accept the Terms of Service and Privacy Policy";
|
|
4838
4785
|
setError(message);
|
|
4839
4786
|
onError?.(message);
|
|
@@ -4877,7 +4824,7 @@ var useAuthForm = /* @__PURE__ */ __name((options) => {
|
|
|
4877
4824
|
setIsLoading(true);
|
|
4878
4825
|
clearError();
|
|
4879
4826
|
try {
|
|
4880
|
-
const result = await verifyOTP(identifier, otp, channel, sourceUrl);
|
|
4827
|
+
const result = await verifyOTP(identifier, otp, channel, sourceUrl, redirectUrl);
|
|
4881
4828
|
if (result.success) {
|
|
4882
4829
|
if (channel === "email") {
|
|
4883
4830
|
setSavedEmail(identifier);
|
|
@@ -4898,7 +4845,7 @@ var useAuthForm = /* @__PURE__ */ __name((options) => {
|
|
|
4898
4845
|
} finally {
|
|
4899
4846
|
setIsLoading(false);
|
|
4900
4847
|
}
|
|
4901
|
-
}, [identifier, otp, channel, verifyOTP, clearError, setSavedEmail, onOTPSuccess, onError, sourceUrl]);
|
|
4848
|
+
}, [identifier, otp, channel, verifyOTP, clearError, setSavedEmail, onOTPSuccess, onError, sourceUrl, redirectUrl]);
|
|
4902
4849
|
const handleResendOTP = (0, import_react7.useCallback)(async () => {
|
|
4903
4850
|
setIsLoading(true);
|
|
4904
4851
|
clearError();
|