@main12/auth-login 0.4.2 → 1.0.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 (66) hide show
  1. package/README.md +54 -7
  2. package/dist/components/AuthCard.d.ts +41 -0
  3. package/dist/components/AuthCard.js +28 -0
  4. package/dist/components/AuthCardServer.d.ts +29 -0
  5. package/dist/components/AuthCardServer.js +57 -0
  6. package/dist/components/AuthLayout.d.ts +23 -13
  7. package/dist/components/AuthLayout.js +26 -87
  8. package/dist/components/AuthPages.d.ts +4 -29
  9. package/dist/components/AuthPages.js +23 -105
  10. package/dist/components/AuthPagesServer.d.ts +3 -4
  11. package/dist/components/AuthPagesServer.js +15 -8
  12. package/dist/components/auth-card/AuthCardShell.d.ts +21 -0
  13. package/dist/components/auth-card/AuthCardShell.js +104 -0
  14. package/dist/components/auth-card/FormRenderer.d.ts +32 -0
  15. package/dist/components/auth-card/FormRenderer.js +88 -0
  16. package/dist/components/auth-card/formConfigs.d.ts +25 -0
  17. package/dist/components/auth-card/formConfigs.js +56 -0
  18. package/dist/components/auth-card/index.d.ts +3 -0
  19. package/dist/components/auth-card/index.js +3 -0
  20. package/dist/components/forms/ForgotPasswordForm.d.ts +7 -0
  21. package/dist/components/forms/ForgotPasswordForm.js +56 -0
  22. package/dist/components/forms/LoginForm.d.ts +15 -0
  23. package/dist/components/forms/LoginForm.js +247 -0
  24. package/dist/components/forms/SetPasswordForm.d.ts +7 -0
  25. package/dist/components/forms/SetPasswordForm.js +75 -0
  26. package/dist/components/forms/SignupForm.d.ts +13 -0
  27. package/dist/components/forms/SignupForm.js +152 -0
  28. package/dist/components/forms/VerifyOtpForm.d.ts +9 -0
  29. package/dist/components/forms/VerifyOtpForm.js +107 -0
  30. package/dist/components/forms/index.d.ts +19 -0
  31. package/dist/components/forms/index.js +21 -0
  32. package/dist/components/pages/ForgotPasswordPage.d.ts +2 -1
  33. package/dist/components/pages/ForgotPasswordPageHero.d.ts +3 -2
  34. package/dist/components/pages/ForgotPasswordPageHero.js +70 -64
  35. package/dist/components/pages/ForgotPasswordPageTailwind.d.ts +3 -2
  36. package/dist/components/pages/ForgotPasswordPageTailwind.js +42 -36
  37. package/dist/components/pages/LoginPage.d.ts +2 -1
  38. package/dist/components/pages/LoginPageHero.d.ts +2 -1
  39. package/dist/components/pages/LoginPageHero.js +297 -291
  40. package/dist/components/pages/LoginPageTailwind.d.ts +2 -1
  41. package/dist/components/pages/LoginPageTailwind.js +197 -191
  42. package/dist/components/pages/SetPasswordPage.d.ts +2 -1
  43. package/dist/components/pages/SetPasswordPageHero.d.ts +3 -2
  44. package/dist/components/pages/SetPasswordPageHero.js +98 -92
  45. package/dist/components/pages/SetPasswordPageTailwind.d.ts +3 -2
  46. package/dist/components/pages/SetPasswordPageTailwind.js +63 -57
  47. package/dist/components/pages/SignupPage.d.ts +2 -1
  48. package/dist/components/pages/SignupPageHero.d.ts +3 -2
  49. package/dist/components/pages/SignupPageHero.js +139 -133
  50. package/dist/components/pages/SignupPageTailwind.d.ts +3 -2
  51. package/dist/components/pages/SignupPageTailwind.js +123 -117
  52. package/dist/components/pages/VerifyOtpPage.d.ts +2 -1
  53. package/dist/components/pages/VerifyOtpPageHero.d.ts +2 -1
  54. package/dist/components/pages/VerifyOtpPageHero.js +110 -104
  55. package/dist/components/pages/VerifyOtpPageTailwind.d.ts +2 -1
  56. package/dist/components/pages/VerifyOtpPageTailwind.js +60 -54
  57. package/dist/components/ui/translations.d.ts +9 -0
  58. package/dist/components/ui/translations.js +18 -0
  59. package/dist/config.d.ts +12 -0
  60. package/dist/config.js +11 -0
  61. package/dist/exports/client.d.ts +5 -0
  62. package/dist/exports/client.js +5 -0
  63. package/dist/exports/rsc.d.ts +7 -0
  64. package/dist/exports/rsc.js +8 -0
  65. package/dist/index.js +12 -2
  66. package/package.json +3 -2
@@ -7,8 +7,9 @@ import { Icon } from '@iconify/react';
7
7
  import { motion } from 'framer-motion';
8
8
  import { useVerifyOtpFlow } from '../../auth/application/hooks/useVerifyOtpFlow.js';
9
9
  import { AuthLayout } from '../AuthLayout.js';
10
+ import { AuthCard } from '../AuthCard.js';
10
11
  import { getUiTranslations } from '../ui/translations.js';
11
- function VerifyOtpHeroContent({ loginUrl = '/login', logo, poweredBy, cardClassName, backgroundClass, locale, messages }) {
12
+ function VerifyOtpHeroContent({ loginUrl = '/login', logo, poweredBy, cardClassName, removeBorder, removeShadow, mobileVariant, backgroundClass, locale, messages }) {
12
13
  const searchParams = useSearchParams();
13
14
  const email = searchParams.get('email') || '';
14
15
  const purpose = searchParams.get('purpose') || 'login';
@@ -21,110 +22,115 @@ function VerifyOtpHeroContent({ loginUrl = '/login', logo, poweredBy, cardClassN
21
22
  const t = getUiTranslations(locale, messages).verifyOtp;
22
23
  if (!email) return null;
23
24
  return /*#__PURE__*/ _jsx(AuthLayout, {
24
- logo: logo,
25
- title: purpose === 'password-reset' ? t.passwordResetTitle : t.title,
26
- subtitle: purpose === 'password-reset' ? t.passwordResetSubtitle : t.subtitle,
27
- poweredBy: poweredBy,
28
- cardClassName: cardClassName,
29
25
  backgroundClass: backgroundClass,
30
- footer: /*#__PURE__*/ _jsxs("a", {
31
- href: loginUrl,
32
- className: "text-sm text-gray-600 hover:text-gray-900 flex items-center gap-1",
33
- children: [
34
- /*#__PURE__*/ _jsx(Icon, {
35
- icon: "lucide:arrow-left",
36
- width: 16
37
- }),
38
- t.backToLogin
39
- ]
40
- }),
41
- children: /*#__PURE__*/ _jsxs("div", {
42
- className: "flex flex-col items-center gap-4",
43
- children: [
44
- /*#__PURE__*/ _jsx("p", {
45
- className: "text-gray-700 text-sm font-medium",
46
- children: email
47
- }),
48
- /*#__PURE__*/ _jsxs(InputOTP, {
49
- maxLength: 6,
50
- value: otp,
51
- onChange: setOtp,
52
- isDisabled: isLoading,
53
- autoFocus: true,
54
- variant: "secondary",
55
- children: [
56
- /*#__PURE__*/ _jsxs(InputOTP.Group, {
57
- children: [
58
- /*#__PURE__*/ _jsx(InputOTP.Slot, {
59
- index: 0
60
- }),
61
- /*#__PURE__*/ _jsx(InputOTP.Slot, {
62
- index: 1
63
- }),
64
- /*#__PURE__*/ _jsx(InputOTP.Slot, {
65
- index: 2
66
- })
67
- ]
68
- }),
69
- /*#__PURE__*/ _jsx(InputOTP.Separator, {}),
70
- /*#__PURE__*/ _jsxs(InputOTP.Group, {
71
- children: [
72
- /*#__PURE__*/ _jsx(InputOTP.Slot, {
73
- index: 3
74
- }),
75
- /*#__PURE__*/ _jsx(InputOTP.Slot, {
76
- index: 4
77
- }),
78
- /*#__PURE__*/ _jsx(InputOTP.Slot, {
79
- index: 5
80
- })
81
- ]
82
- })
83
- ]
84
- }),
85
- error && /*#__PURE__*/ _jsx(motion.div, {
86
- className: "w-full bg-red-50 text-red-600 border border-red-200 rounded-lg p-3 text-sm",
87
- initial: {
88
- opacity: 0
89
- },
90
- animate: {
91
- opacity: 1
92
- },
93
- children: error
94
- }),
95
- /*#__PURE__*/ _jsx(Button, {
96
- fullWidth: true,
97
- size: "lg",
98
- isPending: isLoading,
99
- isDisabled: otp.length !== 6,
100
- onPress: handleSubmit,
101
- className: "h-12 font-semibold",
102
- children: ({ isPending })=>/*#__PURE__*/ _jsxs(_Fragment, {
103
- children: [
104
- isPending && /*#__PURE__*/ _jsx(Spinner, {
105
- color: "current",
106
- size: "sm"
107
- }),
108
- t.verify
109
- ]
110
- })
111
- }),
112
- /*#__PURE__*/ _jsxs("div", {
113
- className: "text-center",
114
- children: [
115
- /*#__PURE__*/ _jsx("p", {
116
- className: "text-gray-600 text-sm mb-2",
117
- children: t.noCodeReceived
118
- }),
119
- /*#__PURE__*/ _jsx("button", {
120
- onClick: handleResendCode,
121
- disabled: isResending || resendCooldown > 0,
122
- className: "text-primary font-medium text-sm hover:underline disabled:opacity-50",
123
- children: isResending ? t.resending : resendCooldown > 0 ? t.resendIn.replace('{seconds}', String(resendCooldown)) : t.resendCode
124
- })
125
- ]
126
- })
127
- ]
26
+ children: /*#__PURE__*/ _jsx(AuthCard, {
27
+ logo: logo,
28
+ title: purpose === 'password-reset' ? t.passwordResetTitle : t.title,
29
+ subtitle: purpose === 'password-reset' ? t.passwordResetSubtitle : t.subtitle,
30
+ poweredBy: poweredBy,
31
+ cardClassName: cardClassName,
32
+ removeBorder: removeBorder,
33
+ removeShadow: removeShadow,
34
+ mobileVariant: mobileVariant,
35
+ footer: /*#__PURE__*/ _jsxs("a", {
36
+ href: loginUrl,
37
+ className: "text-sm text-gray-600 hover:text-gray-900 flex items-center gap-1",
38
+ children: [
39
+ /*#__PURE__*/ _jsx(Icon, {
40
+ icon: "lucide:arrow-left",
41
+ width: 16
42
+ }),
43
+ t.backToLogin
44
+ ]
45
+ }),
46
+ children: /*#__PURE__*/ _jsxs("div", {
47
+ className: "flex flex-col items-center gap-4",
48
+ children: [
49
+ /*#__PURE__*/ _jsx("p", {
50
+ className: "text-gray-700 text-sm font-medium",
51
+ children: email
52
+ }),
53
+ /*#__PURE__*/ _jsxs(InputOTP, {
54
+ maxLength: 6,
55
+ value: otp,
56
+ onChange: setOtp,
57
+ isDisabled: isLoading,
58
+ autoFocus: true,
59
+ variant: "secondary",
60
+ children: [
61
+ /*#__PURE__*/ _jsxs(InputOTP.Group, {
62
+ children: [
63
+ /*#__PURE__*/ _jsx(InputOTP.Slot, {
64
+ index: 0
65
+ }),
66
+ /*#__PURE__*/ _jsx(InputOTP.Slot, {
67
+ index: 1
68
+ }),
69
+ /*#__PURE__*/ _jsx(InputOTP.Slot, {
70
+ index: 2
71
+ })
72
+ ]
73
+ }),
74
+ /*#__PURE__*/ _jsx(InputOTP.Separator, {}),
75
+ /*#__PURE__*/ _jsxs(InputOTP.Group, {
76
+ children: [
77
+ /*#__PURE__*/ _jsx(InputOTP.Slot, {
78
+ index: 3
79
+ }),
80
+ /*#__PURE__*/ _jsx(InputOTP.Slot, {
81
+ index: 4
82
+ }),
83
+ /*#__PURE__*/ _jsx(InputOTP.Slot, {
84
+ index: 5
85
+ })
86
+ ]
87
+ })
88
+ ]
89
+ }),
90
+ error && /*#__PURE__*/ _jsx(motion.div, {
91
+ className: "w-full bg-red-50 text-red-600 border border-red-200 rounded-lg p-3 text-sm",
92
+ initial: {
93
+ opacity: 0
94
+ },
95
+ animate: {
96
+ opacity: 1
97
+ },
98
+ children: error
99
+ }),
100
+ /*#__PURE__*/ _jsx(Button, {
101
+ fullWidth: true,
102
+ size: "lg",
103
+ isPending: isLoading,
104
+ isDisabled: otp.length !== 6,
105
+ onPress: handleSubmit,
106
+ className: "h-12 font-semibold",
107
+ children: ({ isPending })=>/*#__PURE__*/ _jsxs(_Fragment, {
108
+ children: [
109
+ isPending && /*#__PURE__*/ _jsx(Spinner, {
110
+ color: "current",
111
+ size: "sm"
112
+ }),
113
+ t.verify
114
+ ]
115
+ })
116
+ }),
117
+ /*#__PURE__*/ _jsxs("div", {
118
+ className: "text-center",
119
+ children: [
120
+ /*#__PURE__*/ _jsx("p", {
121
+ className: "text-gray-600 text-sm mb-2",
122
+ children: t.noCodeReceived
123
+ }),
124
+ /*#__PURE__*/ _jsx("button", {
125
+ onClick: handleResendCode,
126
+ disabled: isResending || resendCooldown > 0,
127
+ className: "text-primary font-medium text-sm hover:underline disabled:opacity-50",
128
+ children: isResending ? t.resending : resendCooldown > 0 ? t.resendIn.replace('{seconds}', String(resendCooldown)) : t.resendCode
129
+ })
130
+ ]
131
+ })
132
+ ]
133
+ })
128
134
  })
129
135
  });
130
136
  }
@@ -1,5 +1,6 @@
1
1
  import type { AuthLayoutConfig } from '../AuthLayout';
2
- export interface VerifyOtpPageProps extends AuthLayoutConfig {
2
+ import type { AuthCardConfig } from '../AuthCard';
3
+ export interface VerifyOtpPageProps extends AuthLayoutConfig, AuthCardConfig {
3
4
  loginUrl?: string;
4
5
  }
5
6
  export default function VerifyOtpPage(props: VerifyOtpPageProps): import("react/jsx-runtime").JSX.Element;
@@ -5,8 +5,9 @@ import { useSearchParams } from 'next/navigation';
5
5
  import { Button, OtpInput, Spinner } from '../ui/index.js';
6
6
  import { useVerifyOtpFlow } from '../../auth/application/hooks/useVerifyOtpFlow.js';
7
7
  import { AuthLayout } from '../AuthLayout.js';
8
+ import { AuthCard } from '../AuthCard.js';
8
9
  import { getUiTranslations } from '../ui/translations.js';
9
- function VerifyOtpContent({ loginUrl = '/login', logo, poweredBy, cardClassName, backgroundClass, locale, messages }) {
10
+ function VerifyOtpContent({ loginUrl = '/login', logo, poweredBy, cardClassName, removeBorder, removeShadow, mobileVariant, backgroundClass, locale, messages }) {
10
11
  const searchParams = useSearchParams();
11
12
  const email = searchParams.get('email') || '';
12
13
  const purpose = searchParams.get('purpose') || 'login';
@@ -20,60 +21,65 @@ function VerifyOtpContent({ loginUrl = '/login', logo, poweredBy, cardClassName,
20
21
  if (!email) return null;
21
22
  const isPasswordReset = purpose === 'password-reset';
22
23
  return /*#__PURE__*/ _jsx(AuthLayout, {
23
- logo: logo,
24
- title: isPasswordReset ? t.passwordResetTitle : t.title,
25
- subtitle: isPasswordReset ? t.passwordResetSubtitle : t.subtitle,
26
- poweredBy: poweredBy,
27
- cardClassName: cardClassName,
28
24
  backgroundClass: backgroundClass,
29
- footer: /*#__PURE__*/ _jsxs("a", {
30
- href: loginUrl,
31
- className: "text-sm text-gray-600 hover:text-gray-900 flex items-center gap-1",
32
- children: [
33
- "← ",
34
- t.backToLogin
35
- ]
36
- }),
37
- children: /*#__PURE__*/ _jsxs("div", {
38
- className: "flex flex-col items-center gap-4",
39
- children: [
40
- /*#__PURE__*/ _jsx("p", {
41
- className: "text-gray-700 text-sm font-medium",
42
- children: email
43
- }),
44
- /*#__PURE__*/ _jsx(OtpInput, {
45
- value: otp,
46
- onValueChange: setOtp,
47
- isDisabled: isLoading,
48
- autoFocus: true
49
- }),
50
- error && /*#__PURE__*/ _jsx("div", {
51
- className: "w-full bg-red-50 text-red-600 border border-red-200 rounded-lg p-3 text-sm animate-[fadeIn_0.2s_ease-out]",
52
- children: error
53
- }),
54
- /*#__PURE__*/ _jsx(Button, {
55
- variant: "primary",
56
- isLoading: isLoading,
57
- isDisabled: otp.length !== 6,
58
- onPress: handleSubmit,
59
- children: t.verify
60
- }),
61
- /*#__PURE__*/ _jsxs("div", {
62
- className: "text-center",
63
- children: [
64
- /*#__PURE__*/ _jsx("p", {
65
- className: "text-gray-600 text-sm mb-2",
66
- children: t.noCodeReceived
67
- }),
68
- /*#__PURE__*/ _jsx("button", {
69
- onClick: handleResendCode,
70
- disabled: isResending || resendCooldown > 0,
71
- className: "text-[#0071e3] font-medium text-sm hover:underline disabled:opacity-50 disabled:cursor-not-allowed",
72
- children: isResending ? t.resending : resendCooldown > 0 ? t.resendIn.replace('{seconds}', String(resendCooldown)) : t.resendCode
73
- })
74
- ]
75
- })
76
- ]
25
+ children: /*#__PURE__*/ _jsx(AuthCard, {
26
+ logo: logo,
27
+ title: isPasswordReset ? t.passwordResetTitle : t.title,
28
+ subtitle: isPasswordReset ? t.passwordResetSubtitle : t.subtitle,
29
+ poweredBy: poweredBy,
30
+ cardClassName: cardClassName,
31
+ removeBorder: removeBorder,
32
+ removeShadow: removeShadow,
33
+ mobileVariant: mobileVariant,
34
+ footer: /*#__PURE__*/ _jsxs("a", {
35
+ href: loginUrl,
36
+ className: "text-sm text-gray-600 hover:text-gray-900 flex items-center gap-1",
37
+ children: [
38
+ "← ",
39
+ t.backToLogin
40
+ ]
41
+ }),
42
+ children: /*#__PURE__*/ _jsxs("div", {
43
+ className: "flex flex-col items-center gap-4",
44
+ children: [
45
+ /*#__PURE__*/ _jsx("p", {
46
+ className: "text-gray-700 text-sm font-medium",
47
+ children: email
48
+ }),
49
+ /*#__PURE__*/ _jsx(OtpInput, {
50
+ value: otp,
51
+ onValueChange: setOtp,
52
+ isDisabled: isLoading,
53
+ autoFocus: true
54
+ }),
55
+ error && /*#__PURE__*/ _jsx("div", {
56
+ className: "w-full bg-red-50 text-red-600 border border-red-200 rounded-lg p-3 text-sm animate-[fadeIn_0.2s_ease-out]",
57
+ children: error
58
+ }),
59
+ /*#__PURE__*/ _jsx(Button, {
60
+ variant: "primary",
61
+ isLoading: isLoading,
62
+ isDisabled: otp.length !== 6,
63
+ onPress: handleSubmit,
64
+ children: t.verify
65
+ }),
66
+ /*#__PURE__*/ _jsxs("div", {
67
+ className: "text-center",
68
+ children: [
69
+ /*#__PURE__*/ _jsx("p", {
70
+ className: "text-gray-600 text-sm mb-2",
71
+ children: t.noCodeReceived
72
+ }),
73
+ /*#__PURE__*/ _jsx("button", {
74
+ onClick: handleResendCode,
75
+ disabled: isResending || resendCooldown > 0,
76
+ className: "text-[#0071e3] font-medium text-sm hover:underline disabled:opacity-50 disabled:cursor-not-allowed",
77
+ children: isResending ? t.resending : resendCooldown > 0 ? t.resendIn.replace('{seconds}', String(resendCooldown)) : t.resendCode
78
+ })
79
+ ]
80
+ })
81
+ ]
82
+ })
77
83
  })
78
84
  });
79
85
  }
@@ -27,6 +27,15 @@ export interface UiTranslations {
27
27
  noAccount: string;
28
28
  signUpLink: string;
29
29
  };
30
+ errors: {
31
+ noAccountFound: string;
32
+ otpSendFailed: string;
33
+ genericError: string;
34
+ invalidCredentials: string;
35
+ passwordMismatch: string;
36
+ invalidOtp: string;
37
+ otpExpired: string;
38
+ };
30
39
  signup: {
31
40
  title: string;
32
41
  subtitle: string;
@@ -26,6 +26,15 @@
26
26
  noAccount: "Don't have an account?",
27
27
  signUpLink: 'Sign up'
28
28
  },
29
+ errors: {
30
+ noAccountFound: 'No account found with this email. Please sign up.',
31
+ otpSendFailed: 'Failed to send verification code. Please try again.',
32
+ genericError: 'Something went wrong. Please try again.',
33
+ invalidCredentials: 'Invalid email or password.',
34
+ passwordMismatch: 'Passwords do not match.',
35
+ invalidOtp: 'Invalid verification code. Please try again.',
36
+ otpExpired: 'Verification code has expired. Please request a new one.'
37
+ },
29
38
  signup: {
30
39
  title: 'Create Account',
31
40
  subtitle: 'Enter your details to get started',
@@ -90,6 +99,15 @@ const es = {
90
99
  noAccount: '¿No tienes una cuenta?',
91
100
  signUpLink: 'Regístrate'
92
101
  },
102
+ errors: {
103
+ noAccountFound: 'No se encontró una cuenta con este correo. Por favor regístrate.',
104
+ otpSendFailed: 'Error al enviar el código de verificación. Intenta de nuevo.',
105
+ genericError: 'Algo salió mal. Por favor intenta de nuevo.',
106
+ invalidCredentials: 'Correo o contraseña inválidos.',
107
+ passwordMismatch: 'Las contraseñas no coinciden.',
108
+ invalidOtp: 'Código de verificación inválido. Intenta de nuevo.',
109
+ otpExpired: 'El código de verificación ha expirado. Solicita uno nuevo.'
110
+ },
93
111
  signup: {
94
112
  title: 'Crear Cuenta',
95
113
  subtitle: 'Ingresa tus datos para comenzar',
package/dist/config.d.ts CHANGED
@@ -4,7 +4,16 @@ import type React from 'react';
4
4
  * read by all client components at render time.
5
5
  */
6
6
  export type AuthStyle = 'tailwind' | 'hero-ui';
7
+ /** Serializable auth config that can be written to/read from file */
8
+ export interface SerializableAuthConfig {
9
+ googleOAuthEnabled: boolean;
10
+ style: AuthStyle;
11
+ allowSignup: boolean;
12
+ passwordLogin: boolean;
13
+ otpLogin: boolean;
14
+ }
7
15
  export declare const pluginConfig: {
16
+ _initialized: boolean;
8
17
  style: AuthStyle;
9
18
  logoUrl?: string;
10
19
  Logo?: React.ComponentType;
@@ -15,6 +24,9 @@ export declare const pluginConfig: {
15
24
  otpLogin: boolean;
16
25
  allowSignup: boolean;
17
26
  };
27
+ /** Resolve config across Payload and Next server module boundaries. */
28
+ export declare function getServerAllowSignup(): boolean;
29
+ export declare function getServerGoogleOAuthEnabled(): boolean;
18
30
  /** Call this client-side to mirror the server plugin config. */
19
31
  export declare function initClientConfig(opts: {
20
32
  style?: AuthStyle;
package/dist/config.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export const pluginConfig = {
2
+ _initialized: false,
2
3
  style: 'tailwind',
3
4
  googleOAuthEnabled: false,
4
5
  routeRedirects: false,
@@ -7,6 +8,16 @@ export const pluginConfig = {
7
8
  otpLogin: true,
8
9
  allowSignup: true
9
10
  };
11
+ /** Resolve config across Payload and Next server module boundaries. */ export function getServerAllowSignup() {
12
+ if (process.env.AUTH_LOGIN_ALLOW_SIGNUP === 'false') return false;
13
+ if (process.env.AUTH_LOGIN_ALLOW_SIGNUP === 'true') return true;
14
+ return pluginConfig.allowSignup;
15
+ }
16
+ export function getServerGoogleOAuthEnabled() {
17
+ if (process.env.AUTH_LOGIN_GOOGLE_OAUTH === 'false') return false;
18
+ if (process.env.AUTH_LOGIN_GOOGLE_OAUTH === 'true') return true;
19
+ return pluginConfig.googleOAuthEnabled || Boolean(process.env.GOOGLE_CLIENT_ID && process.env.GOOGLE_CLIENT_SECRET);
20
+ }
10
21
  /** Call this client-side to mirror the server plugin config. */ export function initClientConfig(opts) {
11
22
  if (opts.style) pluginConfig.style = opts.style;
12
23
  if (opts.googleOAuthEnabled !== undefined) pluginConfig.googleOAuthEnabled = opts.googleOAuthEnabled;
@@ -18,7 +18,12 @@ export { default as SetPasswordPage } from '../components/pages/SetPasswordPage'
18
18
  export { default as AuthPages } from '../components/AuthPages';
19
19
  export type { AuthPagesProps } from '../components/AuthPages';
20
20
  export { AuthLayout } from '../components/AuthLayout';
21
+ export { AuthCard } from '../components/AuthCard';
22
+ export type { AuthCardProps, AuthCardConfig, AuthCardWithSlugProps, AuthCardWithChildrenProps } from '../components/AuthCard';
21
23
  export { PoweredBy } from '../components/PoweredBy';
24
+ export { LoginForm, SignupForm, ForgotPasswordForm, VerifyOtpForm, SetPasswordForm } from '../components/forms/index';
25
+ export type { LoginFormProps, SignupFormProps, ForgotPasswordFormProps, VerifyOtpFormProps, SetPasswordFormProps } from '../components/forms/index';
26
+ export { AUTH_FORMS, getFormBySlug, type AuthFormSlug } from '../components/forms/index';
22
27
  export type { LoginStep, OTPPurpose, CheckEmailResponse, SendOtpResponse, VerifyOtpResponse, SetPasswordResponse, SignupResponse, PasswordStrengthResult, } from '../auth/domain/types';
23
28
  export type { UseLoginFlowOptions } from '../auth/application/hooks/useLoginFlow';
24
29
  export type { UseVerifyOtpFlowOptions } from '../auth/application/hooks/useVerifyOtpFlow';
@@ -27,4 +27,9 @@ export { default as SetPasswordPage } from '../components/pages/SetPasswordPage.
27
27
  export { default as AuthPages } from '../components/AuthPages.js';
28
28
  // Layout & shared components
29
29
  export { AuthLayout } from '../components/AuthLayout.js';
30
+ export { AuthCard } from '../components/AuthCard.js';
30
31
  export { PoweredBy } from '../components/PoweredBy.js';
32
+ // Form components (for custom compositions)
33
+ export { LoginForm, SignupForm, ForgotPasswordForm, VerifyOtpForm, SetPasswordForm } from '../components/forms/index.js';
34
+ // Form registry (for advanced usage / extending)
35
+ export { AUTH_FORMS, getFormBySlug } from '../components/forms/index.js';
@@ -1,5 +1,12 @@
1
1
  export { default as AuthPages } from '../components/AuthPagesServer';
2
2
  export type { AuthPagesProps } from '../components/AuthPagesServer';
3
+ export { AuthCard } from '../components/AuthCardServer';
4
+ export type { AuthCardProps, AuthCardWithSlugProps, AuthCardWithChildrenProps } from '../components/AuthCardServer';
5
+ export { AuthLayout } from '../components/AuthLayout';
6
+ export type { AuthLayoutConfig, AuthLayoutProps } from '../components/AuthLayout';
7
+ export { LoginForm, SignupForm, ForgotPasswordForm, VerifyOtpForm, SetPasswordForm } from '../components/forms/index';
8
+ export type { LoginFormProps, SignupFormProps, ForgotPasswordFormProps, VerifyOtpFormProps, SetPasswordFormProps } from '../components/forms/index';
9
+ export { AUTH_FORMS, getFormBySlug, type AuthFormSlug } from '../components/forms/index';
3
10
  export { wrapInBaseTemplate, DEFAULT_COLORS, SOCIAL_ICONS, getBaseUrl, getSenderEmail, getEmailTranslations, generateOtpEmail, generateWelcomeEmail, generatePasswordResetEmail, generatePasswordChangedEmail, } from '../components/email/index';
4
11
  export type { BaseTemplateOptions, } from '../components/email/baseTemplate';
5
12
  export type { EmailColors, SocialLink, SocialPlatform, } from '../components/email/constants';
@@ -3,5 +3,13 @@
3
3
  // ============================================================
4
4
  // Server component auth pages (reads plugin config automatically)
5
5
  export { default as AuthPages } from '../components/AuthPagesServer.js';
6
+ // Server component auth card (reads plugin config automatically)
7
+ export { AuthCard } from '../components/AuthCardServer.js';
8
+ // Layout component (can be used in server or client components)
9
+ export { AuthLayout } from '../components/AuthLayout.js';
10
+ // Form components (for custom compositions — re-exported from client)
11
+ export { LoginForm, SignupForm, ForgotPasswordForm, VerifyOtpForm, SetPasswordForm } from '../components/forms/index.js';
12
+ // Form registry (for advanced usage / extending)
13
+ export { AUTH_FORMS, getFormBySlug } from '../components/forms/index.js';
6
14
  // Email template system (server-only — uses Node APIs)
7
15
  export { wrapInBaseTemplate, DEFAULT_COLORS, SOCIAL_ICONS, getBaseUrl, getSenderEmail, getEmailTranslations, generateOtpEmail, generateWelcomeEmail, generatePasswordResetEmail, generatePasswordChangedEmail } from '../components/email/index.js';
package/dist/index.js CHANGED
@@ -48,14 +48,21 @@ function resolveGoogleConfig(providers) {
48
48
  process.env.GOOGLE_CLIENT_SECRET = googleConfig.clientSecret;
49
49
  }
50
50
  }
51
- export const authLoginPlugin = (options = {})=>async (config)=>{
51
+ export const authLoginPlugin = (options = {})=>{
52
+ if (options.enabled !== false) {
53
+ process.env.AUTH_LOGIN_ALLOW_SIGNUP = String(options.allowSignup !== false);
54
+ const googleConfig = resolveGoogleConfig(options.providers);
55
+ process.env.AUTH_LOGIN_GOOGLE_OAUTH = String(googleConfig.enabled);
56
+ }
57
+ return async (config)=>{
52
58
  if (options.enabled === false) return config;
53
59
  // Resolve provider config
54
60
  const googleConfig = resolveGoogleConfig(options.providers);
55
61
  setOAuthEnv(googleConfig);
56
62
  // Set global config — all components (server and client) read this
57
63
  // shared singleton directly at render time. This is the single source
58
- // of truth; no env vars are used to propagate these settings.
64
+ // of truth for the main entry point.
65
+ pluginConfig._initialized = true;
59
66
  pluginConfig.style = options.style || 'tailwind';
60
67
  if (typeof options.logo === 'string') {
61
68
  pluginConfig.logoUrl = options.logo;
@@ -63,7 +70,9 @@ export const authLoginPlugin = (options = {})=>async (config)=>{
63
70
  pluginConfig.Logo = options.logo;
64
71
  }
65
72
  pluginConfig.googleOAuthEnabled = googleConfig.enabled;
73
+ process.env.AUTH_LOGIN_GOOGLE_OAUTH = String(pluginConfig.googleOAuthEnabled);
66
74
  pluginConfig.allowSignup = options.allowSignup !== false;
75
+ process.env.AUTH_LOGIN_ALLOW_SIGNUP = String(pluginConfig.allowSignup);
67
76
  pluginConfig.passwordLogin = options.passwordLogin !== false;
68
77
  pluginConfig.otpLogin = options.otpLogin !== false;
69
78
  // Route redirects config
@@ -160,4 +169,5 @@ export const authLoginPlugin = (options = {})=>async (config)=>{
160
169
  };
161
170
  return config;
162
171
  };
172
+ };
163
173
  export { pluginConfig };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@main12/auth-login",
3
- "version": "0.4.2",
3
+ "version": "1.0.1",
4
4
  "description": "Reusable Payload CMS auth plugin — login, signup, OTP, forgot password, branded emails, Powered by Main12",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -131,6 +131,7 @@
131
131
  "@main12/brevo-adapter": "^0.1.1",
132
132
  "axios": "^1.20.0",
133
133
  "jose": "^6.2.12",
134
- "payload-oauth2": "^1.0.21"
134
+ "payload-oauth2": "^1.0.21",
135
+ "server-only": "^0.0.1"
135
136
  }
136
137
  }