authtara-sdk 1.1.14 → 1.1.17
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/react.d.mts +18 -3
- package/dist/react.d.ts +18 -3
- package/dist/react.js +223 -11
- package/dist/react.mjs +223 -11
- package/package.json +1 -1
package/dist/react.d.mts
CHANGED
|
@@ -37,21 +37,36 @@ declare function useAuth(): AuthTaraContextValue;
|
|
|
37
37
|
* AuthTaraAuth Component
|
|
38
38
|
*
|
|
39
39
|
* Embeddable login/register component
|
|
40
|
-
* Renders social login buttons and
|
|
40
|
+
* Renders social login buttons and email/password form
|
|
41
|
+
* Handles OAuth popup flow and credentials authentication
|
|
41
42
|
*/
|
|
43
|
+
type AuthMode = 'oauth' | 'credentials';
|
|
42
44
|
interface AuthTaraAuthProps {
|
|
45
|
+
/** Display mode: 'modal' for popup, 'redirect' for full page redirect */
|
|
43
46
|
mode?: 'modal' | 'redirect';
|
|
47
|
+
/** Initial auth mode: 'oauth' for social buttons, 'credentials' for email/password */
|
|
48
|
+
initialAuthMode?: AuthMode;
|
|
49
|
+
/** Show email/password option */
|
|
50
|
+
showCredentials?: boolean;
|
|
51
|
+
/** Appearance customization */
|
|
44
52
|
appearance?: {
|
|
45
53
|
theme?: 'light' | 'dark';
|
|
46
54
|
variables?: Record<string, string>;
|
|
47
55
|
};
|
|
56
|
+
/** URL to redirect after successful auth */
|
|
48
57
|
redirectUrl?: string;
|
|
58
|
+
/** Callback when auth succeeds */
|
|
49
59
|
onSuccess?: (session: {
|
|
50
60
|
user: any;
|
|
51
61
|
}) => void;
|
|
62
|
+
/** Callback when auth fails */
|
|
52
63
|
onError?: (error: Error) => void;
|
|
64
|
+
/** Custom API URL for credentials login (defaults to /api/auth/login) */
|
|
65
|
+
credentialsApiUrl?: string;
|
|
66
|
+
/** Custom API URL for registration (defaults to /api/auth/register) */
|
|
67
|
+
registerApiUrl?: string;
|
|
53
68
|
}
|
|
54
|
-
declare function AuthTaraAuth({ appearance, redirectUrl, onSuccess, onError, }: AuthTaraAuthProps): react_jsx_runtime.JSX.Element;
|
|
69
|
+
declare function AuthTaraAuth({ initialAuthMode, showCredentials, appearance, redirectUrl, onSuccess, onError, credentialsApiUrl, }: AuthTaraAuthProps): react_jsx_runtime.JSX.Element;
|
|
55
70
|
|
|
56
71
|
interface AuthTaraBillingProps {
|
|
57
72
|
tenantId: string;
|
|
@@ -74,4 +89,4 @@ interface AuthTaraPricingProps {
|
|
|
74
89
|
}
|
|
75
90
|
declare function AuthTaraPricing({ appearance, onPlanSelect, }: AuthTaraPricingProps): react_jsx_runtime.JSX.Element;
|
|
76
91
|
|
|
77
|
-
export { AuthTaraAuth, type AuthTaraAuthProps, AuthTaraBilling, type AuthTaraBillingProps, type AuthTaraConfig, type AuthTaraContextValue, AuthTaraPricing, type AuthTaraPricingProps, AuthTaraProvider, type SignInOptions, type User, useAuth };
|
|
92
|
+
export { type AuthMode, AuthTaraAuth, type AuthTaraAuthProps, AuthTaraBilling, type AuthTaraBillingProps, type AuthTaraConfig, type AuthTaraContextValue, AuthTaraPricing, type AuthTaraPricingProps, AuthTaraProvider, type SignInOptions, type User, useAuth };
|
package/dist/react.d.ts
CHANGED
|
@@ -37,21 +37,36 @@ declare function useAuth(): AuthTaraContextValue;
|
|
|
37
37
|
* AuthTaraAuth Component
|
|
38
38
|
*
|
|
39
39
|
* Embeddable login/register component
|
|
40
|
-
* Renders social login buttons and
|
|
40
|
+
* Renders social login buttons and email/password form
|
|
41
|
+
* Handles OAuth popup flow and credentials authentication
|
|
41
42
|
*/
|
|
43
|
+
type AuthMode = 'oauth' | 'credentials';
|
|
42
44
|
interface AuthTaraAuthProps {
|
|
45
|
+
/** Display mode: 'modal' for popup, 'redirect' for full page redirect */
|
|
43
46
|
mode?: 'modal' | 'redirect';
|
|
47
|
+
/** Initial auth mode: 'oauth' for social buttons, 'credentials' for email/password */
|
|
48
|
+
initialAuthMode?: AuthMode;
|
|
49
|
+
/** Show email/password option */
|
|
50
|
+
showCredentials?: boolean;
|
|
51
|
+
/** Appearance customization */
|
|
44
52
|
appearance?: {
|
|
45
53
|
theme?: 'light' | 'dark';
|
|
46
54
|
variables?: Record<string, string>;
|
|
47
55
|
};
|
|
56
|
+
/** URL to redirect after successful auth */
|
|
48
57
|
redirectUrl?: string;
|
|
58
|
+
/** Callback when auth succeeds */
|
|
49
59
|
onSuccess?: (session: {
|
|
50
60
|
user: any;
|
|
51
61
|
}) => void;
|
|
62
|
+
/** Callback when auth fails */
|
|
52
63
|
onError?: (error: Error) => void;
|
|
64
|
+
/** Custom API URL for credentials login (defaults to /api/auth/login) */
|
|
65
|
+
credentialsApiUrl?: string;
|
|
66
|
+
/** Custom API URL for registration (defaults to /api/auth/register) */
|
|
67
|
+
registerApiUrl?: string;
|
|
53
68
|
}
|
|
54
|
-
declare function AuthTaraAuth({ appearance, redirectUrl, onSuccess, onError, }: AuthTaraAuthProps): react_jsx_runtime.JSX.Element;
|
|
69
|
+
declare function AuthTaraAuth({ initialAuthMode, showCredentials, appearance, redirectUrl, onSuccess, onError, credentialsApiUrl, }: AuthTaraAuthProps): react_jsx_runtime.JSX.Element;
|
|
55
70
|
|
|
56
71
|
interface AuthTaraBillingProps {
|
|
57
72
|
tenantId: string;
|
|
@@ -74,4 +89,4 @@ interface AuthTaraPricingProps {
|
|
|
74
89
|
}
|
|
75
90
|
declare function AuthTaraPricing({ appearance, onPlanSelect, }: AuthTaraPricingProps): react_jsx_runtime.JSX.Element;
|
|
76
91
|
|
|
77
|
-
export { AuthTaraAuth, type AuthTaraAuthProps, AuthTaraBilling, type AuthTaraBillingProps, type AuthTaraConfig, type AuthTaraContextValue, AuthTaraPricing, type AuthTaraPricingProps, AuthTaraProvider, type SignInOptions, type User, useAuth };
|
|
92
|
+
export { type AuthMode, AuthTaraAuth, type AuthTaraAuthProps, AuthTaraBilling, type AuthTaraBillingProps, type AuthTaraConfig, type AuthTaraContextValue, AuthTaraPricing, type AuthTaraPricingProps, AuthTaraProvider, type SignInOptions, type User, useAuth };
|
package/dist/react.js
CHANGED
|
@@ -213,6 +213,7 @@ function AuthTaraProvider({
|
|
|
213
213
|
} catch (error) {
|
|
214
214
|
if (error instanceof PopupBlockedError) {
|
|
215
215
|
console.warn("[AuthTara] Popup blocked, falling back to redirect mode");
|
|
216
|
+
sessionStorage.setItem("oauth_redirect_uri", callbackUrl);
|
|
216
217
|
window.location.href = authorizeUrl;
|
|
217
218
|
return;
|
|
218
219
|
}
|
|
@@ -267,15 +268,23 @@ var React2 = __toESM(require("react"));
|
|
|
267
268
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
268
269
|
function AuthTaraAuth({
|
|
269
270
|
// mode = 'modal', // Reserved for future use
|
|
271
|
+
initialAuthMode = "oauth",
|
|
272
|
+
showCredentials = true,
|
|
270
273
|
appearance,
|
|
271
274
|
redirectUrl = "/dashboard",
|
|
272
275
|
onSuccess,
|
|
273
|
-
onError
|
|
276
|
+
onError,
|
|
277
|
+
credentialsApiUrl = "/api/auth/login"
|
|
274
278
|
}) {
|
|
275
|
-
const { signIn, isLoading, user } = useAuth();
|
|
279
|
+
const { signIn, isLoading: oauthLoading, user } = useAuth();
|
|
276
280
|
const [error, setError] = React2.useState(null);
|
|
277
281
|
const [provider, setProvider] = React2.useState(null);
|
|
278
|
-
|
|
282
|
+
const [authMode, setAuthMode] = React2.useState(initialAuthMode);
|
|
283
|
+
const [isCredentialsLoading, setIsCredentialsLoading] = React2.useState(false);
|
|
284
|
+
const [email, setEmail] = React2.useState("");
|
|
285
|
+
const [password, setPassword] = React2.useState("");
|
|
286
|
+
const isLoading = oauthLoading || isCredentialsLoading;
|
|
287
|
+
async function handleOAuthSignIn(selectedProvider) {
|
|
279
288
|
setError(null);
|
|
280
289
|
setProvider(selectedProvider);
|
|
281
290
|
try {
|
|
@@ -292,7 +301,47 @@ function AuthTaraAuth({
|
|
|
292
301
|
setProvider(null);
|
|
293
302
|
}
|
|
294
303
|
}
|
|
295
|
-
|
|
304
|
+
async function handleCredentialsSignIn(e) {
|
|
305
|
+
e.preventDefault();
|
|
306
|
+
setError(null);
|
|
307
|
+
setIsCredentialsLoading(true);
|
|
308
|
+
try {
|
|
309
|
+
if (!email || !password) {
|
|
310
|
+
throw new Error("Email and password are required");
|
|
311
|
+
}
|
|
312
|
+
const response = await fetch(credentialsApiUrl, {
|
|
313
|
+
method: "POST",
|
|
314
|
+
headers: { "Content-Type": "application/json" },
|
|
315
|
+
credentials: "include",
|
|
316
|
+
body: JSON.stringify({
|
|
317
|
+
email,
|
|
318
|
+
password,
|
|
319
|
+
redirectUrl
|
|
320
|
+
})
|
|
321
|
+
});
|
|
322
|
+
const result = await response.json();
|
|
323
|
+
if (!response.ok || !result.success) {
|
|
324
|
+
throw new Error(result.message || result.error?.message || "Login failed");
|
|
325
|
+
}
|
|
326
|
+
onSuccess?.({ user: result.data?.user || result.user });
|
|
327
|
+
if (redirectUrl) {
|
|
328
|
+
window.location.href = redirectUrl;
|
|
329
|
+
}
|
|
330
|
+
} catch (err) {
|
|
331
|
+
const message = err instanceof Error ? err.message : "Authentication failed";
|
|
332
|
+
setError(message);
|
|
333
|
+
onError?.(err);
|
|
334
|
+
} finally {
|
|
335
|
+
setIsCredentialsLoading(false);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
const isProviderLoading = (p) => oauthLoading && provider === p;
|
|
339
|
+
const isDark = appearance?.theme === "dark";
|
|
340
|
+
const textColor = isDark ? "#ffffff" : "#111827";
|
|
341
|
+
const mutedColor = isDark ? "#9ca3af" : "#6b7280";
|
|
342
|
+
const bgColor = isDark ? "#1f2937" : "#ffffff";
|
|
343
|
+
const inputBgColor = isDark ? "#374151" : "#ffffff";
|
|
344
|
+
const inputBorderColor = isDark ? "#4b5563" : "#d1d5db";
|
|
296
345
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "authtara-auth-container", style: { maxWidth: "400px", margin: "0 auto" }, children: [
|
|
297
346
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
298
347
|
"div",
|
|
@@ -300,9 +349,9 @@ function AuthTaraAuth({
|
|
|
300
349
|
className: "authtara-auth-card",
|
|
301
350
|
style: {
|
|
302
351
|
padding: "2rem",
|
|
303
|
-
border:
|
|
352
|
+
border: `1px solid ${inputBorderColor}`,
|
|
304
353
|
borderRadius: "0.5rem",
|
|
305
|
-
backgroundColor:
|
|
354
|
+
backgroundColor: bgColor
|
|
306
355
|
},
|
|
307
356
|
children: [
|
|
308
357
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
@@ -312,7 +361,8 @@ function AuthTaraAuth({
|
|
|
312
361
|
fontSize: "1.5rem",
|
|
313
362
|
fontWeight: "bold",
|
|
314
363
|
marginBottom: "1.5rem",
|
|
315
|
-
color:
|
|
364
|
+
color: textColor,
|
|
365
|
+
textAlign: "center"
|
|
316
366
|
},
|
|
317
367
|
children: "Sign in to continue"
|
|
318
368
|
}
|
|
@@ -331,11 +381,57 @@ function AuthTaraAuth({
|
|
|
331
381
|
children: error
|
|
332
382
|
}
|
|
333
383
|
),
|
|
334
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: {
|
|
384
|
+
showCredentials && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: {
|
|
385
|
+
display: "flex",
|
|
386
|
+
marginBottom: "1.5rem",
|
|
387
|
+
borderRadius: "0.375rem",
|
|
388
|
+
border: `1px solid ${inputBorderColor}`,
|
|
389
|
+
overflow: "hidden"
|
|
390
|
+
}, children: [
|
|
391
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
392
|
+
"button",
|
|
393
|
+
{
|
|
394
|
+
type: "button",
|
|
395
|
+
onClick: () => setAuthMode("oauth"),
|
|
396
|
+
style: {
|
|
397
|
+
flex: 1,
|
|
398
|
+
padding: "0.5rem 1rem",
|
|
399
|
+
border: "none",
|
|
400
|
+
backgroundColor: authMode === "oauth" ? "#3b82f6" : "transparent",
|
|
401
|
+
color: authMode === "oauth" ? "#ffffff" : mutedColor,
|
|
402
|
+
fontSize: "0.875rem",
|
|
403
|
+
fontWeight: "500",
|
|
404
|
+
cursor: "pointer",
|
|
405
|
+
transition: "all 0.2s"
|
|
406
|
+
},
|
|
407
|
+
children: "Social Login"
|
|
408
|
+
}
|
|
409
|
+
),
|
|
410
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
411
|
+
"button",
|
|
412
|
+
{
|
|
413
|
+
type: "button",
|
|
414
|
+
onClick: () => setAuthMode("credentials"),
|
|
415
|
+
style: {
|
|
416
|
+
flex: 1,
|
|
417
|
+
padding: "0.5rem 1rem",
|
|
418
|
+
border: "none",
|
|
419
|
+
backgroundColor: authMode === "credentials" ? "#3b82f6" : "transparent",
|
|
420
|
+
color: authMode === "credentials" ? "#ffffff" : mutedColor,
|
|
421
|
+
fontSize: "0.875rem",
|
|
422
|
+
fontWeight: "500",
|
|
423
|
+
cursor: "pointer",
|
|
424
|
+
transition: "all 0.2s"
|
|
425
|
+
},
|
|
426
|
+
children: "Email & Password"
|
|
427
|
+
}
|
|
428
|
+
)
|
|
429
|
+
] }),
|
|
430
|
+
authMode === "oauth" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem" }, children: [
|
|
335
431
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
336
432
|
"button",
|
|
337
433
|
{
|
|
338
|
-
onClick: () =>
|
|
434
|
+
onClick: () => handleOAuthSignIn("google"),
|
|
339
435
|
disabled: isLoading,
|
|
340
436
|
style: {
|
|
341
437
|
display: "flex",
|
|
@@ -411,7 +507,7 @@ function AuthTaraAuth({
|
|
|
411
507
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
412
508
|
"button",
|
|
413
509
|
{
|
|
414
|
-
onClick: () =>
|
|
510
|
+
onClick: () => handleOAuthSignIn("github"),
|
|
415
511
|
disabled: isLoading,
|
|
416
512
|
style: {
|
|
417
513
|
display: "flex",
|
|
@@ -456,13 +552,129 @@ function AuthTaraAuth({
|
|
|
456
552
|
}
|
|
457
553
|
)
|
|
458
554
|
] }),
|
|
555
|
+
authMode === "credentials" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("form", { onSubmit: handleCredentialsSignIn, style: { display: "flex", flexDirection: "column", gap: "1rem" }, children: [
|
|
556
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
|
|
557
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
558
|
+
"label",
|
|
559
|
+
{
|
|
560
|
+
htmlFor: "authtara-email",
|
|
561
|
+
style: {
|
|
562
|
+
display: "block",
|
|
563
|
+
marginBottom: "0.375rem",
|
|
564
|
+
fontSize: "0.875rem",
|
|
565
|
+
fontWeight: "500",
|
|
566
|
+
color: textColor
|
|
567
|
+
},
|
|
568
|
+
children: "Email"
|
|
569
|
+
}
|
|
570
|
+
),
|
|
571
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
572
|
+
"input",
|
|
573
|
+
{
|
|
574
|
+
id: "authtara-email",
|
|
575
|
+
type: "email",
|
|
576
|
+
value: email,
|
|
577
|
+
onChange: (e) => setEmail(e.target.value),
|
|
578
|
+
placeholder: "you@example.com",
|
|
579
|
+
disabled: isLoading,
|
|
580
|
+
required: true,
|
|
581
|
+
style: {
|
|
582
|
+
width: "100%",
|
|
583
|
+
padding: "0.625rem 0.75rem",
|
|
584
|
+
border: `1px solid ${inputBorderColor}`,
|
|
585
|
+
borderRadius: "0.375rem",
|
|
586
|
+
backgroundColor: inputBgColor,
|
|
587
|
+
color: textColor,
|
|
588
|
+
fontSize: "0.875rem",
|
|
589
|
+
outline: "none",
|
|
590
|
+
boxSizing: "border-box"
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
)
|
|
594
|
+
] }),
|
|
595
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
|
|
596
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
597
|
+
"label",
|
|
598
|
+
{
|
|
599
|
+
htmlFor: "authtara-password",
|
|
600
|
+
style: {
|
|
601
|
+
display: "block",
|
|
602
|
+
marginBottom: "0.375rem",
|
|
603
|
+
fontSize: "0.875rem",
|
|
604
|
+
fontWeight: "500",
|
|
605
|
+
color: textColor
|
|
606
|
+
},
|
|
607
|
+
children: "Password"
|
|
608
|
+
}
|
|
609
|
+
),
|
|
610
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
611
|
+
"input",
|
|
612
|
+
{
|
|
613
|
+
id: "authtara-password",
|
|
614
|
+
type: "password",
|
|
615
|
+
value: password,
|
|
616
|
+
onChange: (e) => setPassword(e.target.value),
|
|
617
|
+
placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",
|
|
618
|
+
disabled: isLoading,
|
|
619
|
+
required: true,
|
|
620
|
+
style: {
|
|
621
|
+
width: "100%",
|
|
622
|
+
padding: "0.625rem 0.75rem",
|
|
623
|
+
border: `1px solid ${inputBorderColor}`,
|
|
624
|
+
borderRadius: "0.375rem",
|
|
625
|
+
backgroundColor: inputBgColor,
|
|
626
|
+
color: textColor,
|
|
627
|
+
fontSize: "0.875rem",
|
|
628
|
+
outline: "none",
|
|
629
|
+
boxSizing: "border-box"
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
)
|
|
633
|
+
] }),
|
|
634
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
635
|
+
"button",
|
|
636
|
+
{
|
|
637
|
+
type: "submit",
|
|
638
|
+
disabled: isLoading,
|
|
639
|
+
style: {
|
|
640
|
+
width: "100%",
|
|
641
|
+
padding: "0.75rem 1rem",
|
|
642
|
+
border: "none",
|
|
643
|
+
borderRadius: "0.375rem",
|
|
644
|
+
backgroundColor: "#3b82f6",
|
|
645
|
+
color: "#ffffff",
|
|
646
|
+
fontSize: "0.875rem",
|
|
647
|
+
fontWeight: "500",
|
|
648
|
+
cursor: isLoading ? "not-allowed" : "pointer",
|
|
649
|
+
opacity: isLoading ? 0.6 : 1,
|
|
650
|
+
transition: "all 0.2s"
|
|
651
|
+
},
|
|
652
|
+
children: isCredentialsLoading ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: { display: "flex", alignItems: "center", justifyContent: "center", gap: "0.5rem" }, children: [
|
|
653
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
654
|
+
"div",
|
|
655
|
+
{
|
|
656
|
+
style: {
|
|
657
|
+
width: "1rem",
|
|
658
|
+
height: "1rem",
|
|
659
|
+
border: "2px solid #ffffff40",
|
|
660
|
+
borderTopColor: "#ffffff",
|
|
661
|
+
borderRadius: "50%",
|
|
662
|
+
animation: "spin 1s linear infinite"
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
),
|
|
666
|
+
"Signing in..."
|
|
667
|
+
] }) : "Sign in"
|
|
668
|
+
}
|
|
669
|
+
)
|
|
670
|
+
] }),
|
|
459
671
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
460
672
|
"p",
|
|
461
673
|
{
|
|
462
674
|
style: {
|
|
463
675
|
marginTop: "1.5rem",
|
|
464
676
|
fontSize: "0.75rem",
|
|
465
|
-
color:
|
|
677
|
+
color: mutedColor,
|
|
466
678
|
textAlign: "center"
|
|
467
679
|
},
|
|
468
680
|
children: "By continuing, you agree to our Terms of Service and Privacy Policy"
|
package/dist/react.mjs
CHANGED
|
@@ -177,6 +177,7 @@ function AuthTaraProvider({
|
|
|
177
177
|
} catch (error) {
|
|
178
178
|
if (error instanceof PopupBlockedError) {
|
|
179
179
|
console.warn("[AuthTara] Popup blocked, falling back to redirect mode");
|
|
180
|
+
sessionStorage.setItem("oauth_redirect_uri", callbackUrl);
|
|
180
181
|
window.location.href = authorizeUrl;
|
|
181
182
|
return;
|
|
182
183
|
}
|
|
@@ -231,15 +232,23 @@ import * as React2 from "react";
|
|
|
231
232
|
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
232
233
|
function AuthTaraAuth({
|
|
233
234
|
// mode = 'modal', // Reserved for future use
|
|
235
|
+
initialAuthMode = "oauth",
|
|
236
|
+
showCredentials = true,
|
|
234
237
|
appearance,
|
|
235
238
|
redirectUrl = "/dashboard",
|
|
236
239
|
onSuccess,
|
|
237
|
-
onError
|
|
240
|
+
onError,
|
|
241
|
+
credentialsApiUrl = "/api/auth/login"
|
|
238
242
|
}) {
|
|
239
|
-
const { signIn, isLoading, user } = useAuth();
|
|
243
|
+
const { signIn, isLoading: oauthLoading, user } = useAuth();
|
|
240
244
|
const [error, setError] = React2.useState(null);
|
|
241
245
|
const [provider, setProvider] = React2.useState(null);
|
|
242
|
-
|
|
246
|
+
const [authMode, setAuthMode] = React2.useState(initialAuthMode);
|
|
247
|
+
const [isCredentialsLoading, setIsCredentialsLoading] = React2.useState(false);
|
|
248
|
+
const [email, setEmail] = React2.useState("");
|
|
249
|
+
const [password, setPassword] = React2.useState("");
|
|
250
|
+
const isLoading = oauthLoading || isCredentialsLoading;
|
|
251
|
+
async function handleOAuthSignIn(selectedProvider) {
|
|
243
252
|
setError(null);
|
|
244
253
|
setProvider(selectedProvider);
|
|
245
254
|
try {
|
|
@@ -256,7 +265,47 @@ function AuthTaraAuth({
|
|
|
256
265
|
setProvider(null);
|
|
257
266
|
}
|
|
258
267
|
}
|
|
259
|
-
|
|
268
|
+
async function handleCredentialsSignIn(e) {
|
|
269
|
+
e.preventDefault();
|
|
270
|
+
setError(null);
|
|
271
|
+
setIsCredentialsLoading(true);
|
|
272
|
+
try {
|
|
273
|
+
if (!email || !password) {
|
|
274
|
+
throw new Error("Email and password are required");
|
|
275
|
+
}
|
|
276
|
+
const response = await fetch(credentialsApiUrl, {
|
|
277
|
+
method: "POST",
|
|
278
|
+
headers: { "Content-Type": "application/json" },
|
|
279
|
+
credentials: "include",
|
|
280
|
+
body: JSON.stringify({
|
|
281
|
+
email,
|
|
282
|
+
password,
|
|
283
|
+
redirectUrl
|
|
284
|
+
})
|
|
285
|
+
});
|
|
286
|
+
const result = await response.json();
|
|
287
|
+
if (!response.ok || !result.success) {
|
|
288
|
+
throw new Error(result.message || result.error?.message || "Login failed");
|
|
289
|
+
}
|
|
290
|
+
onSuccess?.({ user: result.data?.user || result.user });
|
|
291
|
+
if (redirectUrl) {
|
|
292
|
+
window.location.href = redirectUrl;
|
|
293
|
+
}
|
|
294
|
+
} catch (err) {
|
|
295
|
+
const message = err instanceof Error ? err.message : "Authentication failed";
|
|
296
|
+
setError(message);
|
|
297
|
+
onError?.(err);
|
|
298
|
+
} finally {
|
|
299
|
+
setIsCredentialsLoading(false);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
const isProviderLoading = (p) => oauthLoading && provider === p;
|
|
303
|
+
const isDark = appearance?.theme === "dark";
|
|
304
|
+
const textColor = isDark ? "#ffffff" : "#111827";
|
|
305
|
+
const mutedColor = isDark ? "#9ca3af" : "#6b7280";
|
|
306
|
+
const bgColor = isDark ? "#1f2937" : "#ffffff";
|
|
307
|
+
const inputBgColor = isDark ? "#374151" : "#ffffff";
|
|
308
|
+
const inputBorderColor = isDark ? "#4b5563" : "#d1d5db";
|
|
260
309
|
return /* @__PURE__ */ jsxs("div", { className: "authtara-auth-container", style: { maxWidth: "400px", margin: "0 auto" }, children: [
|
|
261
310
|
/* @__PURE__ */ jsxs(
|
|
262
311
|
"div",
|
|
@@ -264,9 +313,9 @@ function AuthTaraAuth({
|
|
|
264
313
|
className: "authtara-auth-card",
|
|
265
314
|
style: {
|
|
266
315
|
padding: "2rem",
|
|
267
|
-
border:
|
|
316
|
+
border: `1px solid ${inputBorderColor}`,
|
|
268
317
|
borderRadius: "0.5rem",
|
|
269
|
-
backgroundColor:
|
|
318
|
+
backgroundColor: bgColor
|
|
270
319
|
},
|
|
271
320
|
children: [
|
|
272
321
|
/* @__PURE__ */ jsx2(
|
|
@@ -276,7 +325,8 @@ function AuthTaraAuth({
|
|
|
276
325
|
fontSize: "1.5rem",
|
|
277
326
|
fontWeight: "bold",
|
|
278
327
|
marginBottom: "1.5rem",
|
|
279
|
-
color:
|
|
328
|
+
color: textColor,
|
|
329
|
+
textAlign: "center"
|
|
280
330
|
},
|
|
281
331
|
children: "Sign in to continue"
|
|
282
332
|
}
|
|
@@ -295,11 +345,57 @@ function AuthTaraAuth({
|
|
|
295
345
|
children: error
|
|
296
346
|
}
|
|
297
347
|
),
|
|
298
|
-
/* @__PURE__ */ jsxs("div", { style: {
|
|
348
|
+
showCredentials && /* @__PURE__ */ jsxs("div", { style: {
|
|
349
|
+
display: "flex",
|
|
350
|
+
marginBottom: "1.5rem",
|
|
351
|
+
borderRadius: "0.375rem",
|
|
352
|
+
border: `1px solid ${inputBorderColor}`,
|
|
353
|
+
overflow: "hidden"
|
|
354
|
+
}, children: [
|
|
355
|
+
/* @__PURE__ */ jsx2(
|
|
356
|
+
"button",
|
|
357
|
+
{
|
|
358
|
+
type: "button",
|
|
359
|
+
onClick: () => setAuthMode("oauth"),
|
|
360
|
+
style: {
|
|
361
|
+
flex: 1,
|
|
362
|
+
padding: "0.5rem 1rem",
|
|
363
|
+
border: "none",
|
|
364
|
+
backgroundColor: authMode === "oauth" ? "#3b82f6" : "transparent",
|
|
365
|
+
color: authMode === "oauth" ? "#ffffff" : mutedColor,
|
|
366
|
+
fontSize: "0.875rem",
|
|
367
|
+
fontWeight: "500",
|
|
368
|
+
cursor: "pointer",
|
|
369
|
+
transition: "all 0.2s"
|
|
370
|
+
},
|
|
371
|
+
children: "Social Login"
|
|
372
|
+
}
|
|
373
|
+
),
|
|
374
|
+
/* @__PURE__ */ jsx2(
|
|
375
|
+
"button",
|
|
376
|
+
{
|
|
377
|
+
type: "button",
|
|
378
|
+
onClick: () => setAuthMode("credentials"),
|
|
379
|
+
style: {
|
|
380
|
+
flex: 1,
|
|
381
|
+
padding: "0.5rem 1rem",
|
|
382
|
+
border: "none",
|
|
383
|
+
backgroundColor: authMode === "credentials" ? "#3b82f6" : "transparent",
|
|
384
|
+
color: authMode === "credentials" ? "#ffffff" : mutedColor,
|
|
385
|
+
fontSize: "0.875rem",
|
|
386
|
+
fontWeight: "500",
|
|
387
|
+
cursor: "pointer",
|
|
388
|
+
transition: "all 0.2s"
|
|
389
|
+
},
|
|
390
|
+
children: "Email & Password"
|
|
391
|
+
}
|
|
392
|
+
)
|
|
393
|
+
] }),
|
|
394
|
+
authMode === "oauth" && /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem" }, children: [
|
|
299
395
|
/* @__PURE__ */ jsxs(
|
|
300
396
|
"button",
|
|
301
397
|
{
|
|
302
|
-
onClick: () =>
|
|
398
|
+
onClick: () => handleOAuthSignIn("google"),
|
|
303
399
|
disabled: isLoading,
|
|
304
400
|
style: {
|
|
305
401
|
display: "flex",
|
|
@@ -375,7 +471,7 @@ function AuthTaraAuth({
|
|
|
375
471
|
/* @__PURE__ */ jsxs(
|
|
376
472
|
"button",
|
|
377
473
|
{
|
|
378
|
-
onClick: () =>
|
|
474
|
+
onClick: () => handleOAuthSignIn("github"),
|
|
379
475
|
disabled: isLoading,
|
|
380
476
|
style: {
|
|
381
477
|
display: "flex",
|
|
@@ -420,13 +516,129 @@ function AuthTaraAuth({
|
|
|
420
516
|
}
|
|
421
517
|
)
|
|
422
518
|
] }),
|
|
519
|
+
authMode === "credentials" && /* @__PURE__ */ jsxs("form", { onSubmit: handleCredentialsSignIn, style: { display: "flex", flexDirection: "column", gap: "1rem" }, children: [
|
|
520
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
521
|
+
/* @__PURE__ */ jsx2(
|
|
522
|
+
"label",
|
|
523
|
+
{
|
|
524
|
+
htmlFor: "authtara-email",
|
|
525
|
+
style: {
|
|
526
|
+
display: "block",
|
|
527
|
+
marginBottom: "0.375rem",
|
|
528
|
+
fontSize: "0.875rem",
|
|
529
|
+
fontWeight: "500",
|
|
530
|
+
color: textColor
|
|
531
|
+
},
|
|
532
|
+
children: "Email"
|
|
533
|
+
}
|
|
534
|
+
),
|
|
535
|
+
/* @__PURE__ */ jsx2(
|
|
536
|
+
"input",
|
|
537
|
+
{
|
|
538
|
+
id: "authtara-email",
|
|
539
|
+
type: "email",
|
|
540
|
+
value: email,
|
|
541
|
+
onChange: (e) => setEmail(e.target.value),
|
|
542
|
+
placeholder: "you@example.com",
|
|
543
|
+
disabled: isLoading,
|
|
544
|
+
required: true,
|
|
545
|
+
style: {
|
|
546
|
+
width: "100%",
|
|
547
|
+
padding: "0.625rem 0.75rem",
|
|
548
|
+
border: `1px solid ${inputBorderColor}`,
|
|
549
|
+
borderRadius: "0.375rem",
|
|
550
|
+
backgroundColor: inputBgColor,
|
|
551
|
+
color: textColor,
|
|
552
|
+
fontSize: "0.875rem",
|
|
553
|
+
outline: "none",
|
|
554
|
+
boxSizing: "border-box"
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
)
|
|
558
|
+
] }),
|
|
559
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
560
|
+
/* @__PURE__ */ jsx2(
|
|
561
|
+
"label",
|
|
562
|
+
{
|
|
563
|
+
htmlFor: "authtara-password",
|
|
564
|
+
style: {
|
|
565
|
+
display: "block",
|
|
566
|
+
marginBottom: "0.375rem",
|
|
567
|
+
fontSize: "0.875rem",
|
|
568
|
+
fontWeight: "500",
|
|
569
|
+
color: textColor
|
|
570
|
+
},
|
|
571
|
+
children: "Password"
|
|
572
|
+
}
|
|
573
|
+
),
|
|
574
|
+
/* @__PURE__ */ jsx2(
|
|
575
|
+
"input",
|
|
576
|
+
{
|
|
577
|
+
id: "authtara-password",
|
|
578
|
+
type: "password",
|
|
579
|
+
value: password,
|
|
580
|
+
onChange: (e) => setPassword(e.target.value),
|
|
581
|
+
placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",
|
|
582
|
+
disabled: isLoading,
|
|
583
|
+
required: true,
|
|
584
|
+
style: {
|
|
585
|
+
width: "100%",
|
|
586
|
+
padding: "0.625rem 0.75rem",
|
|
587
|
+
border: `1px solid ${inputBorderColor}`,
|
|
588
|
+
borderRadius: "0.375rem",
|
|
589
|
+
backgroundColor: inputBgColor,
|
|
590
|
+
color: textColor,
|
|
591
|
+
fontSize: "0.875rem",
|
|
592
|
+
outline: "none",
|
|
593
|
+
boxSizing: "border-box"
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
)
|
|
597
|
+
] }),
|
|
598
|
+
/* @__PURE__ */ jsx2(
|
|
599
|
+
"button",
|
|
600
|
+
{
|
|
601
|
+
type: "submit",
|
|
602
|
+
disabled: isLoading,
|
|
603
|
+
style: {
|
|
604
|
+
width: "100%",
|
|
605
|
+
padding: "0.75rem 1rem",
|
|
606
|
+
border: "none",
|
|
607
|
+
borderRadius: "0.375rem",
|
|
608
|
+
backgroundColor: "#3b82f6",
|
|
609
|
+
color: "#ffffff",
|
|
610
|
+
fontSize: "0.875rem",
|
|
611
|
+
fontWeight: "500",
|
|
612
|
+
cursor: isLoading ? "not-allowed" : "pointer",
|
|
613
|
+
opacity: isLoading ? 0.6 : 1,
|
|
614
|
+
transition: "all 0.2s"
|
|
615
|
+
},
|
|
616
|
+
children: isCredentialsLoading ? /* @__PURE__ */ jsxs("span", { style: { display: "flex", alignItems: "center", justifyContent: "center", gap: "0.5rem" }, children: [
|
|
617
|
+
/* @__PURE__ */ jsx2(
|
|
618
|
+
"div",
|
|
619
|
+
{
|
|
620
|
+
style: {
|
|
621
|
+
width: "1rem",
|
|
622
|
+
height: "1rem",
|
|
623
|
+
border: "2px solid #ffffff40",
|
|
624
|
+
borderTopColor: "#ffffff",
|
|
625
|
+
borderRadius: "50%",
|
|
626
|
+
animation: "spin 1s linear infinite"
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
),
|
|
630
|
+
"Signing in..."
|
|
631
|
+
] }) : "Sign in"
|
|
632
|
+
}
|
|
633
|
+
)
|
|
634
|
+
] }),
|
|
423
635
|
/* @__PURE__ */ jsx2(
|
|
424
636
|
"p",
|
|
425
637
|
{
|
|
426
638
|
style: {
|
|
427
639
|
marginTop: "1.5rem",
|
|
428
640
|
fontSize: "0.75rem",
|
|
429
|
-
color:
|
|
641
|
+
color: mutedColor,
|
|
430
642
|
textAlign: "center"
|
|
431
643
|
},
|
|
432
644
|
children: "By continuing, you agree to our Terms of Service and Privacy Policy"
|
package/package.json
CHANGED