@liedsonc/core-auth-kit 2.1.4 → 2.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/README.md +802 -0
  2. package/dist/components/auth-card.d.ts +9 -0
  3. package/dist/components/auth-card.d.ts.map +1 -0
  4. package/dist/components/auth-card.js +9 -0
  5. package/dist/components/auth-form.d.ts +10 -0
  6. package/dist/components/auth-form.d.ts.map +1 -0
  7. package/dist/components/auth-form.js +21 -0
  8. package/dist/components/error-message.d.ts +6 -0
  9. package/dist/components/error-message.d.ts.map +1 -0
  10. package/dist/components/error-message.js +8 -0
  11. package/dist/components/form-field.d.ts +9 -0
  12. package/dist/components/form-field.d.ts.map +1 -0
  13. package/dist/components/form-field.js +7 -0
  14. package/dist/components/index.d.ts +9 -0
  15. package/dist/components/index.d.ts.map +1 -0
  16. package/{components/index.ts → dist/components/index.js} +8 -8
  17. package/dist/components/loading-spinner.d.ts +5 -0
  18. package/dist/components/loading-spinner.d.ts.map +1 -0
  19. package/dist/components/loading-spinner.js +6 -0
  20. package/dist/components/oauth-buttons.d.ts +11 -0
  21. package/dist/components/oauth-buttons.d.ts.map +1 -0
  22. package/dist/components/oauth-buttons.js +14 -0
  23. package/dist/components/password-input.d.ts +8 -0
  24. package/dist/components/password-input.d.ts.map +1 -0
  25. package/dist/components/password-input.js +36 -0
  26. package/dist/components/success-message.d.ts +6 -0
  27. package/dist/components/success-message.d.ts.map +1 -0
  28. package/dist/components/success-message.js +8 -0
  29. package/dist/components/ui/button.d.ts +12 -0
  30. package/dist/components/ui/button.d.ts.map +1 -0
  31. package/dist/components/ui/button.js +33 -0
  32. package/dist/components/ui/card.d.ts +9 -0
  33. package/dist/components/ui/card.d.ts.map +1 -0
  34. package/dist/components/ui/card.js +16 -0
  35. package/dist/components/ui/input.d.ts +4 -0
  36. package/dist/components/ui/input.d.ts.map +1 -0
  37. package/dist/components/ui/input.js +8 -0
  38. package/dist/components/ui/label.d.ts +6 -0
  39. package/dist/components/ui/label.d.ts.map +1 -0
  40. package/dist/components/ui/label.js +10 -0
  41. package/dist/context.d.ts +8 -0
  42. package/dist/context.d.ts.map +1 -0
  43. package/dist/context.js +13 -0
  44. package/dist/hooks/use-auth.d.ts +22 -0
  45. package/dist/hooks/use-auth.d.ts.map +1 -0
  46. package/dist/hooks/use-auth.js +112 -0
  47. package/dist/hooks/use-oauth.d.ts +6 -0
  48. package/dist/hooks/use-oauth.d.ts.map +1 -0
  49. package/dist/hooks/use-oauth.js +18 -0
  50. package/dist/index.d.ts +7 -0
  51. package/dist/index.d.ts.map +1 -0
  52. package/dist/index.js +5 -0
  53. package/dist/pages/forgot-password/index.d.ts +2 -0
  54. package/dist/pages/forgot-password/index.d.ts.map +1 -0
  55. package/dist/pages/forgot-password/index.js +30 -0
  56. package/dist/pages/index.d.ts +6 -0
  57. package/dist/pages/index.d.ts.map +1 -0
  58. package/{pages/index.ts → dist/pages/index.js} +5 -5
  59. package/dist/pages/login/index.d.ts +2 -0
  60. package/dist/pages/login/index.d.ts.map +1 -0
  61. package/dist/pages/login/index.js +45 -0
  62. package/dist/pages/register/index.d.ts +2 -0
  63. package/dist/pages/register/index.d.ts.map +1 -0
  64. package/dist/pages/register/index.js +59 -0
  65. package/dist/pages/reset-password/index.d.ts +2 -0
  66. package/dist/pages/reset-password/index.d.ts.map +1 -0
  67. package/dist/pages/reset-password/index.js +48 -0
  68. package/dist/pages/verify-email/index.d.ts +2 -0
  69. package/dist/pages/verify-email/index.d.ts.map +1 -0
  70. package/dist/pages/verify-email/index.js +47 -0
  71. package/dist/tsconfig.build.tsbuildinfo +1 -0
  72. package/dist/types/index.d.ts +60 -0
  73. package/dist/types/index.d.ts.map +1 -0
  74. package/dist/types/index.js +1 -0
  75. package/dist/utils.d.ts +3 -0
  76. package/dist/utils.d.ts.map +1 -0
  77. package/dist/utils.js +5 -0
  78. package/package.json +15 -11
  79. package/components/auth-card.tsx +0 -49
  80. package/components/auth-form.tsx +0 -53
  81. package/components/error-message.tsx +0 -24
  82. package/components/form-field.tsx +0 -39
  83. package/components/loading-spinner.tsx +0 -19
  84. package/components/oauth-buttons.tsx +0 -49
  85. package/components/password-input.tsx +0 -93
  86. package/components/success-message.tsx +0 -24
  87. package/components/ui/button.tsx +0 -52
  88. package/components/ui/card.tsx +0 -75
  89. package/components/ui/input.tsx +0 -21
  90. package/components/ui/label.tsx +0 -25
  91. package/context.tsx +0 -26
  92. package/hooks/use-auth.ts +0 -131
  93. package/hooks/use-oauth.ts +0 -25
  94. package/index.ts +0 -28
  95. package/pages/forgot-password/index.tsx +0 -83
  96. package/pages/login/index.tsx +0 -119
  97. package/pages/register/index.tsx +0 -149
  98. package/pages/reset-password/index.tsx +0 -133
  99. package/pages/verify-email/index.tsx +0 -143
  100. package/types/index.ts +0 -34
  101. package/utils.ts +0 -6
@@ -1,133 +0,0 @@
1
- "use client";
2
-
3
- import Link from "next/link";
4
- import { useAuth } from "../../hooks/use-auth";
5
- import { useSearchParams } from "next/navigation";
6
- import { AuthCard } from "../../components/auth-card";
7
- import { AuthForm } from "../../components/auth-form";
8
- import { FormField } from "../../components/form-field";
9
- import { PasswordInput } from "../../components/password-input";
10
- import { Button } from "../../components/ui/button";
11
- import { useState, Suspense } from "react";
12
-
13
- const genericError = "Something went wrong. Please request a new reset link.";
14
-
15
- function ResetPasswordForm() {
16
- const searchParams = useSearchParams();
17
- const token = searchParams.get("token") ?? "";
18
- const { resetPassword, loading, error, clearError } = useAuth();
19
- const [password, setPassword] = useState("");
20
- const [confirmPassword, setConfirmPassword] = useState("");
21
- const [fieldErrors, setFieldErrors] = useState<{ password?: string; confirm?: string }>({});
22
-
23
- const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
24
- e.preventDefault();
25
- clearError();
26
- setFieldErrors({});
27
- const err: { password?: string; confirm?: string } = {};
28
- if (!token) err.password = "Invalid or missing reset link.";
29
- if (!password) err.password = "Password is required.";
30
- if (password.length < 8) err.password = "Password must be at least 8 characters.";
31
- if (password !== confirmPassword) err.confirm = "Passwords do not match.";
32
- if (Object.keys(err).length) {
33
- setFieldErrors(err);
34
- return;
35
- }
36
- const result = await resetPassword(token, password);
37
- if (!result.success) setFieldErrors({ password: genericError });
38
- };
39
-
40
- if (!token) {
41
- return (
42
- <div className="flex min-h-screen flex-col items-center justify-center p-4">
43
- <AuthCard
44
- title="Reset password"
45
- subtitle="Invalid or expired link"
46
- footer={
47
- <Link
48
- href="/forgot-password"
49
- className="text-sm text-muted-foreground underline underline-offset-4 hover:text-foreground"
50
- >
51
- Request a new reset link
52
- </Link>
53
- }
54
- >
55
- <p className="text-sm text-muted-foreground">
56
- This reset link is invalid or has expired. Please request a new one.
57
- </p>
58
- </AuthCard>
59
- </div>
60
- );
61
- }
62
-
63
- return (
64
- <div className="flex min-h-screen flex-col items-center justify-center p-4">
65
- <AuthCard
66
- title="Reset password"
67
- subtitle="Enter your new password"
68
- footer={
69
- <div className="flex w-full justify-center text-sm text-muted-foreground">
70
- <Link
71
- href="/login"
72
- className="underline underline-offset-4 hover:text-foreground"
73
- >
74
- Back to sign in
75
- </Link>
76
- </div>
77
- }
78
- >
79
- <AuthForm onSubmit={handleSubmit} loading={loading} error={error ? genericError : undefined}>
80
- <FormField label="New password" htmlFor="reset-password" error={fieldErrors.password} required>
81
- <PasswordInput
82
- id="reset-password"
83
- placeholder="••••••••"
84
- autoComplete="new-password"
85
- value={password}
86
- onChange={(e) => setPassword(e.target.value)}
87
- disabled={loading}
88
- showStrength
89
- aria-invalid={!!fieldErrors.password}
90
- />
91
- </FormField>
92
- <FormField
93
- label="Confirm password"
94
- htmlFor="reset-confirm"
95
- error={fieldErrors.confirm}
96
- required
97
- >
98
- <PasswordInput
99
- id="reset-confirm"
100
- placeholder="••••••••"
101
- autoComplete="new-password"
102
- value={confirmPassword}
103
- onChange={(e) => setConfirmPassword(e.target.value)}
104
- disabled={loading}
105
- aria-invalid={!!fieldErrors.confirm}
106
- />
107
- </FormField>
108
- <Button type="submit" className="w-full" disabled={loading}>
109
- {loading ? (
110
- <span className="inline-block size-4 animate-spin rounded-full border-2 border-current border-t-transparent" />
111
- ) : (
112
- "Reset password"
113
- )}
114
- </Button>
115
- </AuthForm>
116
- </AuthCard>
117
- </div>
118
- );
119
- }
120
-
121
- export function ResetPasswordPage() {
122
- return (
123
- <Suspense
124
- fallback={
125
- <div className="flex min-h-screen items-center justify-center">
126
- <span className="inline-block size-8 animate-spin rounded-full border-2 border-current border-t-transparent" />
127
- </div>
128
- }
129
- >
130
- <ResetPasswordForm />
131
- </Suspense>
132
- );
133
- }
@@ -1,143 +0,0 @@
1
- "use client";
2
-
3
- import Link from "next/link";
4
- import { useAuth } from "../../hooks/use-auth";
5
- import { useSearchParams } from "next/navigation";
6
- import { AuthCard } from "../../components/auth-card";
7
- import { SuccessMessage } from "../../components/success-message";
8
- import { ErrorMessage } from "../../components/error-message";
9
- import { Button } from "../../components/ui/button";
10
- import { useEffect, useState, Suspense } from "react";
11
-
12
- type VerifyState = "idle" | "loading" | "success" | "expired" | "invalid";
13
-
14
- function VerifyEmailContent() {
15
- const searchParams = useSearchParams();
16
- const token = searchParams.get("token") ?? "";
17
- const { verifyEmail, loading } = useAuth();
18
- const [state, setState] = useState<VerifyState>("idle");
19
- const [checked, setChecked] = useState(false);
20
-
21
- useEffect(() => {
22
- if (!token || checked) return;
23
- setChecked(true);
24
- setState("loading");
25
- verifyEmail(token).then((result) => {
26
- if (result.success) setState("success");
27
- else if (result.error.code === "EXPIRED" || result.error.code === "TOKEN_EXPIRED")
28
- setState("expired");
29
- else setState("invalid");
30
- });
31
- }, [token, checked, verifyEmail]);
32
-
33
- if (!token) {
34
- return (
35
- <div className="flex min-h-screen flex-col items-center justify-center p-4">
36
- <AuthCard
37
- title="Verify email"
38
- subtitle="Invalid verification link"
39
- footer={
40
- <Link
41
- href="/login"
42
- className="text-sm text-muted-foreground underline underline-offset-4 hover:text-foreground"
43
- >
44
- Go to sign in
45
- </Link>
46
- }
47
- >
48
- <ErrorMessage>This verification link is invalid.</ErrorMessage>
49
- </AuthCard>
50
- </div>
51
- );
52
- }
53
-
54
- if (state === "loading" || (state === "idle" && loading)) {
55
- return (
56
- <div className="flex min-h-screen flex-col items-center justify-center p-4">
57
- <AuthCard title="Verify email" subtitle="Verifying your email...">
58
- <div className="flex justify-center py-4">
59
- <span
60
- role="status"
61
- aria-label="Verifying"
62
- className="inline-block size-8 animate-spin rounded-full border-2 border-current border-t-transparent"
63
- />
64
- </div>
65
- </AuthCard>
66
- </div>
67
- );
68
- }
69
-
70
- if (state === "success") {
71
- return (
72
- <div className="flex min-h-screen flex-col items-center justify-center p-4">
73
- <AuthCard
74
- title="Email verified"
75
- subtitle="Your account is ready"
76
- footer={
77
- <Button asChild className="w-full">
78
- <Link href="/login">Sign in</Link>
79
- </Button>
80
- }
81
- >
82
- <SuccessMessage>Your email has been verified. You can now sign in.</SuccessMessage>
83
- </AuthCard>
84
- </div>
85
- );
86
- }
87
-
88
- if (state === "expired") {
89
- return (
90
- <div className="flex min-h-screen flex-col items-center justify-center p-4">
91
- <AuthCard
92
- title="Link expired"
93
- subtitle="This verification link has expired"
94
- footer={
95
- <Link
96
- href="/login"
97
- className="text-sm text-muted-foreground underline underline-offset-4 hover:text-foreground"
98
- >
99
- Go to sign in
100
- </Link>
101
- }
102
- >
103
- <ErrorMessage>
104
- This verification link has expired. Please sign in to request a new one.
105
- </ErrorMessage>
106
- </AuthCard>
107
- </div>
108
- );
109
- }
110
-
111
- return (
112
- <div className="flex min-h-screen flex-col items-center justify-center p-4">
113
- <AuthCard
114
- title="Verification failed"
115
- subtitle="We couldn't verify your email"
116
- footer={
117
- <Link
118
- href="/login"
119
- className="text-sm text-muted-foreground underline underline-offset-4 hover:text-foreground"
120
- >
121
- Go to sign in
122
- </Link>
123
- }
124
- >
125
- <ErrorMessage>This verification link is invalid or has already been used.</ErrorMessage>
126
- </AuthCard>
127
- </div>
128
- );
129
- }
130
-
131
- export function VerifyEmailPage() {
132
- return (
133
- <Suspense
134
- fallback={
135
- <div className="flex min-h-screen items-center justify-center">
136
- <span className="inline-block size-8 animate-spin rounded-full border-2 border-current border-t-transparent" />
137
- </div>
138
- }
139
- >
140
- <VerifyEmailContent />
141
- </Suspense>
142
- );
143
- }
package/types/index.ts DELETED
@@ -1,34 +0,0 @@
1
- import type { ReactNode } from "react";
2
-
3
- export type OAuthProvider = "google" | "apple";
4
-
5
- export interface AuthError {
6
- code: string;
7
- message: string;
8
- }
9
-
10
- export interface AuthSession {
11
- user: { id: string; email?: string };
12
- expiresAt?: number;
13
- }
14
-
15
- export interface AuthClient {
16
- login: (email: string, password: string) => Promise<{ success: true } | { success: false; error: AuthError }>;
17
- register: (email: string, password: string) => Promise<{ success: true } | { success: false; error: AuthError }>;
18
- logout: () => Promise<void>;
19
- forgotPassword: (email: string) => Promise<{ success: true } | { success: false; error: AuthError }>;
20
- resetPassword: (token: string, newPassword: string) => Promise<{ success: true } | { success: false; error: AuthError }>;
21
- verifyEmail: (token: string) => Promise<{ success: true } | { success: false; error: AuthError }>;
22
- getSession?: () => Promise<AuthSession | null>;
23
- }
24
-
25
- export type AuthFormState = "idle" | "loading" | "success" | "error";
26
-
27
- export interface AuthUIConfig {
28
- authClient: AuthClient;
29
- oauthProviders?: { provider: OAuthProvider; enabled: boolean }[];
30
- logo?: ReactNode;
31
- redirectAfterLogin?: string;
32
- redirectAfterRegister?: string;
33
- redirectAfterReset?: string;
34
- }
package/utils.ts DELETED
@@ -1,6 +0,0 @@
1
- import { clsx, type ClassValue } from "clsx";
2
- import { twMerge } from "tailwind-merge";
3
-
4
- export function cn(...inputs: ClassValue[]) {
5
- return twMerge(clsx(inputs));
6
- }