@explita/cloud-auth-client 0.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 (89) hide show
  1. package/README.md +238 -0
  2. package/dist/components/change-password.d.ts +11 -0
  3. package/dist/components/change-password.js +101 -0
  4. package/dist/components/loader.d.ts +2 -0
  5. package/dist/components/loader.js +11 -0
  6. package/dist/components/logged-in.d.ts +3 -0
  7. package/dist/components/logged-in.js +9 -0
  8. package/dist/components/logged-out.d.ts +3 -0
  9. package/dist/components/logged-out.js +9 -0
  10. package/dist/components/login-form.d.ts +2 -0
  11. package/dist/components/login-form.js +102 -0
  12. package/dist/components/message.d.ts +6 -0
  13. package/dist/components/message.js +15 -0
  14. package/dist/components/must-login.d.ts +4 -0
  15. package/dist/components/must-login.js +23 -0
  16. package/dist/components/optional-otp-wrapper.d.ts +3 -0
  17. package/dist/components/optional-otp-wrapper.js +52 -0
  18. package/dist/components/optional-otp.d.ts +3 -0
  19. package/dist/components/optional-otp.js +70 -0
  20. package/dist/components/reset-password.d.ts +8 -0
  21. package/dist/components/reset-password.js +118 -0
  22. package/dist/components/roles.d.ts +6 -0
  23. package/dist/components/roles.js +54 -0
  24. package/dist/components/settings.d.ts +9 -0
  25. package/dist/components/settings.js +26 -0
  26. package/dist/components/signup-form.d.ts +11 -0
  27. package/dist/components/signup-form.js +138 -0
  28. package/dist/components/toggle-2fa.d.ts +7 -0
  29. package/dist/components/toggle-2fa.js +81 -0
  30. package/dist/components/toggle-account-status.d.ts +11 -0
  31. package/dist/components/toggle-account-status.js +91 -0
  32. package/dist/components/ui/button.d.ts +10 -0
  33. package/dist/components/ui/button.js +68 -0
  34. package/dist/components/ui/card.d.ts +9 -0
  35. package/dist/components/ui/card.js +65 -0
  36. package/dist/components/ui/dialog.d.ts +15 -0
  37. package/dist/components/ui/dialog.js +86 -0
  38. package/dist/components/ui/dropdown-menu.d.ts +11 -0
  39. package/dist/components/ui/dropdown-menu.js +63 -0
  40. package/dist/components/ui/input.d.ts +3 -0
  41. package/dist/components/ui/input.js +41 -0
  42. package/dist/components/ui/label.d.ts +3 -0
  43. package/dist/components/ui/label.js +42 -0
  44. package/dist/components/ui/switch.d.ts +4 -0
  45. package/dist/components/ui/switch.js +44 -0
  46. package/dist/components/user-card.d.ts +10 -0
  47. package/dist/components/user-card.js +67 -0
  48. package/dist/components/x-icon.d.ts +2 -0
  49. package/dist/components/x-icon.js +11 -0
  50. package/dist/contexts/auth-provider.d.ts +4 -0
  51. package/dist/contexts/auth-provider.js +208 -0
  52. package/dist/hooks/use-token-refresher.d.ts +2 -0
  53. package/dist/hooks/use-token-refresher.js +118 -0
  54. package/dist/index.d.ts +4 -0
  55. package/dist/index.js +21 -0
  56. package/dist/lib/api-client.d.ts +2 -0
  57. package/dist/lib/api-client.js +38 -0
  58. package/dist/lib/api-server.d.ts +2 -0
  59. package/dist/lib/api-server.js +39 -0
  60. package/dist/lib/api.d.ts +2 -0
  61. package/dist/lib/api.js +10 -0
  62. package/dist/lib/error.d.ts +6 -0
  63. package/dist/lib/error.js +15 -0
  64. package/dist/lib/refresh-helper.d.ts +12 -0
  65. package/dist/lib/refresh-helper.js +82 -0
  66. package/dist/lib/utils.d.ts +21 -0
  67. package/dist/lib/utils.js +148 -0
  68. package/dist/server/cookie.d.ts +1 -0
  69. package/dist/server/cookie.js +29 -0
  70. package/dist/server/index.d.ts +7 -0
  71. package/dist/server/index.js +23 -0
  72. package/dist/server/reset-password.d.ts +3 -0
  73. package/dist/server/reset-password.js +41 -0
  74. package/dist/server/role.d.ts +7 -0
  75. package/dist/server/role.js +63 -0
  76. package/dist/server/server-session.d.ts +8 -0
  77. package/dist/server/server-session.js +31 -0
  78. package/dist/server/server-token.d.ts +4 -0
  79. package/dist/server/server-token.js +39 -0
  80. package/dist/server/toggle-2fa.d.ts +4 -0
  81. package/dist/server/toggle-2fa.js +33 -0
  82. package/dist/server/users-accounts.d.ts +11 -0
  83. package/dist/server/users-accounts.js +94 -0
  84. package/dist/styles.css +1799 -0
  85. package/dist/types.d.ts +284 -0
  86. package/dist/types.js +2 -0
  87. package/dist/ui/index.d.ts +11 -0
  88. package/dist/ui/index.js +27 -0
  89. package/package.json +65 -0
package/README.md ADDED
@@ -0,0 +1,238 @@
1
+ ### Part of the Explita Cloud Auth Platform
2
+
3
+ A lightweight authentication library for React applications. Provides utilities to handle common authentication tasks like managing authentication tokens, verifying sessions, handling cookies, and supporting both OTP and token-based authentication.
4
+
5
+ ## ✨ Features
6
+
7
+ - 📱 OTP-based login support
8
+ - 🔐 JWT token session handling
9
+ - ⚛️ React hooks for seamless UX
10
+ - 💼 Works with Next.js API and server functions
11
+ - 💅 Minimal styles with Tailwind support
12
+
13
+ ---
14
+
15
+ ## 🚀 Installation
16
+
17
+ ```bash
18
+ npm install @explita/cloud-auth-client
19
+ ```
20
+
21
+ or
22
+
23
+ ```bash
24
+ yarn add @explita/cloud-auth-client
25
+ ```
26
+
27
+ or
28
+
29
+ ```bash
30
+ pnpm add @explita/cloud-auth-client
31
+ ```
32
+
33
+ ---
34
+
35
+ ### Add the CSS
36
+
37
+ ```bash
38
+ import '@explita/cloud-auth-client/styles.css';
39
+ ```
40
+
41
+ ### 📜 Session Management
42
+
43
+ The cloud-auth-client library handles session management by automatically storing and retrieving authentication tokens using HTTP-only cookies for better security.
44
+
45
+ Authentication tokens are stored in cookies, with the HttpOnly flag to prevent JavaScript access.
46
+
47
+ The useAuth hook allows easy access to session data in any component.
48
+
49
+ ---
50
+
51
+ ### 🔐 Authentication Methods
52
+
53
+ Use JWT tokens for stateless authentication. The library provides helpers to manage tokens and sessions using cookies.
54
+
55
+ ##### OTP-Based Authentication
56
+
57
+ The OTP is part of the cloud-auth-client library by default, all you have to do is install the cloud-otp-client library and users can enable OTP in their account settings.
58
+
59
+ ##### Add the CSS
60
+
61
+ ```bash
62
+ import '@explita/cloud-otp-client/styles.css';
63
+ ```
64
+
65
+ ### Usage
66
+
67
+ ```tsx
68
+ "use client";
69
+
70
+ import { AuthProvider } from "@explita/cloud-auth-client";
71
+
72
+ export default function Layout({ children }: { children: React.ReactNode }) {
73
+ return (
74
+ <AuthProvider
75
+ config={{
76
+ hostOverride: process.env.NEXT_PUBLIC_DOMAIN,
77
+ dashboardPath: "/dashboard", //default is /dashboard
78
+ loginPath: "/login", //default is /login
79
+ signupPath: "/signup", //default is /signup
80
+ resetPasswordPath: "/reset-password", //default is /reset-password
81
+ cookieOverride: cookieOverrideHandler, //included in the server-side functions and only needed if your app runs on localhost subdomain eg: http://console.localhost:3000
82
+ disableLoading: true, //default is false
83
+ excludedPaths: [], //array of strings of relative paths, all the paths mentioned above are already excluded.
84
+ }}
85
+ >
86
+ {children}
87
+ </AuthProvider>
88
+ );
89
+ }
90
+ ```
91
+
92
+ ```tsx
93
+ "use client";
94
+
95
+ import { Login } from "@explita/cloud-auth-client/ui";
96
+ import { useEffect } from "react";
97
+
98
+ export default function LoginPage() {
99
+ useEffect(() => {
100
+ document.title = "Login";
101
+ }, []);
102
+
103
+ return (
104
+ <>
105
+ <div className="h-screen flex items-center justify-center">
106
+ <Login />
107
+ </div>
108
+ </>
109
+ );
110
+ }
111
+ ```
112
+
113
+ ```tsx
114
+ "use client";
115
+
116
+ import { signup } from "@/app/actions";
117
+ import { Signup } from "@explita/cloud-auth-client/ui";
118
+ import { useEffect } from "react";
119
+
120
+ export default function SignupPage() {
121
+ useEffect(() => {
122
+ document.title = "Sign Up";
123
+ }, []);
124
+
125
+ return (
126
+ <div className="flex items-center justify-center min-h-screen p-3">
127
+ <Signup onSubmit={signup} />
128
+ </div>
129
+ );
130
+ }
131
+ ```
132
+
133
+ ```tsx
134
+ "use client";
135
+
136
+ import { ResetPassword } from "@explita/cloud-auth-client/ui";
137
+ import { useEffect } from "react";
138
+
139
+ export default function ResetPasswordPage() {
140
+ useEffect(() => {
141
+ document.title = "Reset Password";
142
+ }, []);
143
+
144
+ return (
145
+ <>
146
+ <div className="h-screen flex items-center justify-center">
147
+ <ResetPassword />
148
+ </div>
149
+ </>
150
+ );
151
+ }
152
+
153
+ //other available components for logged-in users
154
+ ChangePassword;
155
+ UserCard; //shows currently logged-in user
156
+ Settings;
157
+ Toggle2FA; //toggle 2FA for logged-in users
158
+ ToggleAccountStatus; //suspend or unsuspend a user
159
+ LoggedIn; //check if user is logged in
160
+ LoggedOut; //check if user is logged out
161
+ ```
162
+
163
+ ### Server-side functions
164
+
165
+ ```typescript
166
+ "use server";
167
+
168
+ import {
169
+ NewRole,
170
+ ResetPasswordWithToken,
171
+ ResetPasswordWithUserId,
172
+ Signup,
173
+ } from "@explita/cloud-auth-client";
174
+ import {
175
+ addRole,
176
+ assignPermission,
177
+ changePassword,
178
+ getRoles,
179
+ registerUser,
180
+ resetPassword,
181
+ setCookie,
182
+ toggle2FA,
183
+ toggleUserStatus,
184
+ updateRole,
185
+ } from "@explita/cloud-auth-client/server";
186
+
187
+ export async function cookieOverrideHandler(cookie?: string) {
188
+ await setCookie(cookie);
189
+ }
190
+
191
+ export async function resetUserPassword(data: ResetPasswordWithToken) {
192
+ return resetPassword(data);
193
+ }
194
+
195
+ export async function changeUserPassword(data: ResetPasswordWithUserId) {
196
+ return changePassword(data);
197
+ }
198
+
199
+ export async function signup(data: Signup) {
200
+ return registerUser(data);
201
+ }
202
+
203
+ export async function toggleUser2FA() {
204
+ return toggle2FA();
205
+ }
206
+
207
+ export async function toggleStatus(userId: string) {
208
+ return toggleUserStatus(userId);
209
+ }
210
+
211
+ export async function getAllRoles() {
212
+ return getRoles();
213
+ }
214
+
215
+ export async function addNewRole(data: NewRole) {
216
+ return addRole(data);
217
+ }
218
+
219
+ export async function editRole(id: string, data: NewRole) {
220
+ return updateRole(id, data);
221
+ }
222
+
223
+ export async function assignPermissions(roleId: string, permissions: string[]) {
224
+ return assignPermission(roleId, permissions);
225
+ }
226
+ ```
227
+
228
+ ---
229
+
230
+ ### Getting started
231
+
232
+ Sign up for an account at [Explita Cloud](https://cloud.explita.ng), create a project, add auth service and get your API key from the dashboard and add it to your environment variables.
233
+
234
+ ---
235
+
236
+ ### 📄 License
237
+
238
+ MIT — Made with ❤️ by [Explita](https://explita.ng)
@@ -0,0 +1,11 @@
1
+ import React from "react";
2
+ import { ResetPasswordWithUserId, FormResponse, User } from "../types";
3
+ type Props = {
4
+ open: boolean;
5
+ onOpenChange: (open: boolean) => void;
6
+ onSubmit?: (data: ResetPasswordWithUserId) => Promise<FormResponse>;
7
+ onSuccess?: () => void;
8
+ user?: User | null;
9
+ };
10
+ export declare function ChangePassword({ user, open, onOpenChange, onSubmit, onSuccess, }: Props): React.JSX.Element;
11
+ export {};
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.ChangePassword = ChangePassword;
37
+ const react_1 = __importStar(require("react"));
38
+ const dialog_1 = require("./ui/dialog");
39
+ const button_1 = require("./ui/button");
40
+ const label_1 = require("./ui/label");
41
+ const input_1 = require("./ui/input");
42
+ const auth_provider_1 = require("../contexts/auth-provider");
43
+ const message_1 = require("./message");
44
+ const must_login_1 = require("./must-login");
45
+ const utils_1 = require("../lib/utils");
46
+ function ChangePassword({ user, open, onOpenChange, onSubmit, onSuccess, }) {
47
+ var _a, _b;
48
+ const { user: loggedInUser } = (0, auth_provider_1.useAuth)();
49
+ const [state, handleSubmit, isPending] = (0, react_1.useActionState)(async function (prevState, formData) {
50
+ if (!onSubmit || typeof onSubmit !== "function") {
51
+ return {
52
+ message: "Password change handler is not defined. Please pass onSubmit handler to ChangePassword component. If you are using UserCard component, please pass onChangePassword handler to it.",
53
+ status: "failure",
54
+ };
55
+ }
56
+ try {
57
+ const result = await onSubmit({
58
+ userId: (user === null || user === void 0 ? void 0 : user.id) || loggedInUser.id,
59
+ password: formData.get("password"),
60
+ confirmPassword: formData.get("confirmPassword"),
61
+ });
62
+ onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess();
63
+ return result;
64
+ }
65
+ catch (error) {
66
+ console.log(error);
67
+ }
68
+ }, undefined);
69
+ return (react_1.default.createElement(dialog_1.Dialog, { open: open, onOpenChange: (state) => {
70
+ onOpenChange(state);
71
+ (0, utils_1.unstuckPointerEvents)();
72
+ } },
73
+ react_1.default.createElement(dialog_1.DialogContent, null, !loggedInUser ? (react_1.default.createElement(must_login_1.MustLogin, { onOpenChange: onOpenChange })) : (react_1.default.createElement("form", { action: handleSubmit },
74
+ react_1.default.createElement(dialog_1.DialogHeader, null,
75
+ !user || loggedInUser.id === user.id ? (react_1.default.createElement(dialog_1.DialogTitle, null, "Change your password")) : (react_1.default.createElement(dialog_1.DialogTitle, null,
76
+ "Change password for ",
77
+ user.firstName,
78
+ " ",
79
+ user.lastName)),
80
+ react_1.default.createElement(dialog_1.DialogDescription, null, "Please enter the new password"),
81
+ user && loggedInUser.id !== (user === null || user === void 0 ? void 0 : user.id) && (react_1.default.createElement(dialog_1.DialogDescription, { className: "ecpauth:mt-2 ecpauth:text-base" },
82
+ "Username: ",
83
+ (user === null || user === void 0 ? void 0 : user.username) || (user === null || user === void 0 ? void 0 : user.email)))),
84
+ (state === null || state === void 0 ? void 0 : state.status) === "success" ? (react_1.default.createElement(message_1.Message, { message: state === null || state === void 0 ? void 0 : state.message, className: "ecpauth:mt-2 ecpauth:font-semibold ecpauth:text-base", variant: "success" })) : (react_1.default.createElement(message_1.Message, { message: state === null || state === void 0 ? void 0 : state.message, className: "ecpauth:mt-2" })),
85
+ react_1.default.createElement("div", { className: "ecpauth:flex ecpauth:flex-col ecpauth:gap-6 ecpauth:my-5" },
86
+ react_1.default.createElement("div", { className: "ecpauth:grid ecpauth:gap-2" },
87
+ react_1.default.createElement(label_1.Label, { htmlFor: "password" }, "New Password"),
88
+ react_1.default.createElement(input_1.Input, { id: "password", type: "password", name: "password" }),
89
+ react_1.default.createElement(message_1.Message, { message: (state === null || state === void 0 ? void 0 : state.status) === "validation-error"
90
+ ? (_a = state === null || state === void 0 ? void 0 : state.errors) === null || _a === void 0 ? void 0 : _a.password
91
+ : "" })),
92
+ react_1.default.createElement("div", { className: "ecpauth:grid ecpauth:gap-2" },
93
+ react_1.default.createElement(label_1.Label, { htmlFor: "confirmPassword" }, "Confirm New Password"),
94
+ react_1.default.createElement(input_1.Input, { id: "confirmPassword", type: "password", name: "confirmPassword" }),
95
+ react_1.default.createElement(message_1.Message, { message: (state === null || state === void 0 ? void 0 : state.status) === "validation-error"
96
+ ? (_b = state === null || state === void 0 ? void 0 : state.errors) === null || _b === void 0 ? void 0 : _b.confirmPassword
97
+ : "" }))),
98
+ react_1.default.createElement("div", { className: "ecpauth:flex ecpauth:justify-end ecpauth:gap-2" },
99
+ react_1.default.createElement(button_1.Button, { type: "button", variant: "outline", onClick: () => onOpenChange(false) }, "Cancel"),
100
+ react_1.default.createElement(button_1.Button, { disabled: isPending, type: "submit" }, "Change Password")))))));
101
+ }
@@ -0,0 +1,2 @@
1
+ import React from "react";
2
+ export declare function Loader(): React.JSX.Element;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Loader = Loader;
7
+ const react_1 = __importDefault(require("react"));
8
+ function Loader() {
9
+ return (react_1.default.createElement("div", { className: "ecpauth:fixed ecpauth:top-0 ecpauth:left-0 ecpauth:right-0 ecpauth:bottom-0 ecpauth:flex ecpauth:items-center ecpauth:justify-center ecpauth:bg-white/80 ecpauth:dark:bg-gray-950/80 ecpauth:z-50" },
10
+ react_1.default.createElement("div", { className: "loader" })));
11
+ }
@@ -0,0 +1,3 @@
1
+ export declare function LoggedIn({ children }: {
2
+ children: React.ReactNode;
3
+ }): import("react").ReactNode;
@@ -0,0 +1,9 @@
1
+ "use client";
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.LoggedIn = LoggedIn;
5
+ const auth_provider_1 = require("../contexts/auth-provider");
6
+ function LoggedIn({ children }) {
7
+ const { isAuthenticated } = (0, auth_provider_1.useAuth)();
8
+ return isAuthenticated ? children : null;
9
+ }
@@ -0,0 +1,3 @@
1
+ export declare function LoggedOut({ children }: {
2
+ children: React.ReactNode;
3
+ }): import("react").ReactNode;
@@ -0,0 +1,9 @@
1
+ "use client";
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.LoggedOut = LoggedOut;
5
+ const auth_provider_1 = require("../contexts/auth-provider");
6
+ function LoggedOut({ children }) {
7
+ const { isAuthenticated } = (0, auth_provider_1.useAuth)();
8
+ return !isAuthenticated ? children : null;
9
+ }
@@ -0,0 +1,2 @@
1
+ import React from "react";
2
+ export declare function Login({ className, ...props }: React.ComponentPropsWithoutRef<"div">): React.JSX.Element;
@@ -0,0 +1,102 @@
1
+ "use client";
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.Login = Login;
38
+ const react_1 = __importStar(require("react"));
39
+ const utils_1 = require("../lib/utils");
40
+ const button_1 = require("../components/ui/button");
41
+ const card_1 = require("../components/ui/card");
42
+ const input_1 = require("../components/ui/input");
43
+ const label_1 = require("../components/ui/label");
44
+ const auth_provider_1 = require("../contexts/auth-provider");
45
+ const loader_1 = require("./loader");
46
+ const message_1 = require("./message");
47
+ function Login({ className, ...props }) {
48
+ var _a, _b;
49
+ const { login, error, computedRouteContext, isAuthenticated } = (0, auth_provider_1.useAuth)();
50
+ const [authToken, setAuthToken] = react_1.default.useState(null);
51
+ const { resetPasswordUrl, signupUrl, loginUrl } = computedRouteContext;
52
+ (0, react_1.useEffect)(() => {
53
+ const authToken = new URLSearchParams(window.location.search).get("authToken");
54
+ if (authToken) {
55
+ setAuthToken(authToken);
56
+ }
57
+ }, []);
58
+ (0, react_1.useEffect)(() => {
59
+ if (authToken) {
60
+ login({
61
+ email: "",
62
+ password: "",
63
+ authToken,
64
+ });
65
+ }
66
+ }, [authToken]);
67
+ const [state, handleSubmit, isPending] = (0, react_1.useActionState)(async function (prevState, formData) {
68
+ await login({
69
+ email: formData.get("email"),
70
+ password: formData.get("password"),
71
+ });
72
+ return { email: formData.get("email") };
73
+ }, undefined);
74
+ return (react_1.default.createElement("div", { className: (0, utils_1.cn)("ecpauth:relative ecpauth:flex ecpauth:flex-col ecpauth:gap-6 ecpauth:w-full ecpauth:max-w-sm", className), ...props },
75
+ react_1.default.createElement(card_1.Card, { className: "ecpauth:relative ecpauth:overflow-hidden" },
76
+ isAuthenticated && react_1.default.createElement(loader_1.Loader, null),
77
+ authToken && !error && (react_1.default.createElement("div", { className: "ecpauth:absolute ecpauth:top-0 ecpauth:left-0 ecpauth:right-0 ecpauth:bottom-0 ecpauth:flex ecpauth:flex-col ecpauth:items-center ecpauth:justify-center ecpauth:gap-2 ecpauth:text-black ecpauth:dark:text-white ecpauth:bg-white/90 ecpauth:dark:bg-gray-900/90 ecpauth:z-50 ecpauth:rounded-xl" },
78
+ react_1.default.createElement("p", null, "Please wait..."),
79
+ react_1.default.createElement("a", { href: loginUrl, className: "ecpauth:underline ecpauth:underline-offset-4 ecpauth:!text-blue-500 ecpauth:hover:!text-blue-600" }, "Or go back to login"))),
80
+ react_1.default.createElement(card_1.CardHeader, null,
81
+ react_1.default.createElement(card_1.CardTitle, { className: "ecpauth:text-2xl" }, "Login"),
82
+ react_1.default.createElement(card_1.CardDescription, null, "Enter your email below to login to your account")),
83
+ react_1.default.createElement(card_1.CardContent, null,
84
+ error && (react_1.default.createElement("p", { className: "ecpauth:text-red-500 ecpauth:mb-4" }, error.message)),
85
+ react_1.default.createElement("form", { action: handleSubmit },
86
+ react_1.default.createElement("div", { className: "ecpauth:flex ecpauth:flex-col ecpauth:gap-6" },
87
+ react_1.default.createElement("div", { className: "ecpauth:grid ecpauth:gap-2" },
88
+ react_1.default.createElement(label_1.Label, { htmlFor: "email" }, "Email/Username"),
89
+ react_1.default.createElement(input_1.Input, { id: "email", type: "text", placeholder: "email@example.com", name: "email", defaultValue: state === null || state === void 0 ? void 0 : state.email }),
90
+ react_1.default.createElement(message_1.Message, { message: (_a = error === null || error === void 0 ? void 0 : error.errors) === null || _a === void 0 ? void 0 : _a.email })),
91
+ react_1.default.createElement("div", { className: "ecpauth:grid ecpauth:gap-2" },
92
+ react_1.default.createElement("div", { className: "ecpauth:flex ecpauth:items-center" },
93
+ react_1.default.createElement(label_1.Label, { htmlFor: "password" }, "Password"),
94
+ resetPasswordUrl && (react_1.default.createElement("a", { href: resetPasswordUrl, className: "ecpauth:ml-auto ecpauth:inline-block ecpauth:text-sm ecpauth:underline-offset-4 ecpauth:hover:underline" }, "Forgot your password?"))),
95
+ react_1.default.createElement(input_1.Input, { id: "password", type: "password", name: "password" }),
96
+ react_1.default.createElement(message_1.Message, { message: (_b = error === null || error === void 0 ? void 0 : error.errors) === null || _b === void 0 ? void 0 : _b.password })),
97
+ react_1.default.createElement(button_1.Button, { type: "submit", className: "ecpauth:w-full ecpauth:cursor-pointer", disabled: isPending }, isPending ? "Logging in..." : "Login")),
98
+ signupUrl && (react_1.default.createElement("div", { className: "ecpauth:mt-4 ecpauth:text-center ecpauth:text-sm" },
99
+ "Don't have an account?",
100
+ " ",
101
+ react_1.default.createElement("a", { href: signupUrl, className: "ecpauth:underline ecpauth:underline-offset-4" }, "Sign up"))))))));
102
+ }
@@ -0,0 +1,6 @@
1
+ import React from "react";
2
+ export declare function Message({ message, variant, className, }: {
3
+ message?: string;
4
+ variant?: "error" | "success";
5
+ className?: string;
6
+ }): React.JSX.Element | null;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Message = Message;
7
+ const react_1 = __importDefault(require("react"));
8
+ const utils_1 = require("../lib/utils");
9
+ function Message({ message, variant = "error", className = "ecpauth:-mt-2", }) {
10
+ if (!message)
11
+ return null;
12
+ return (react_1.default.createElement("div", { className: (0, utils_1.cn)("ecpauth:text-sm", variant === "success"
13
+ ? "ecpauth:text-green-500"
14
+ : "ecpauth:text-red-500", className) }, message));
15
+ }
@@ -0,0 +1,4 @@
1
+ import React from "react";
2
+ export declare function MustLogin({ onOpenChange, }: {
3
+ onOpenChange: (open: boolean) => void;
4
+ }): React.JSX.Element;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.MustLogin = MustLogin;
7
+ const react_1 = __importDefault(require("react"));
8
+ const button_1 = require("./ui/button");
9
+ const message_1 = require("./message");
10
+ const dialog_1 = require("./ui/dialog");
11
+ const utils_1 = require("../lib/utils");
12
+ function MustLogin({ onOpenChange, }) {
13
+ return (react_1.default.createElement(react_1.default.Fragment, null,
14
+ react_1.default.createElement(dialog_1.DialogHeader, null,
15
+ react_1.default.createElement(dialog_1.DialogTitle, null, "Authentication Error")),
16
+ react_1.default.createElement("div", { className: "ecpauth:flex ecpauth:items-center ecpauth:justify-center ecpauth:h-40" },
17
+ react_1.default.createElement(message_1.Message, { message: "User not found. Make sure you are logged in.", variant: "error" })),
18
+ react_1.default.createElement("div", { className: "ecpauth:flex ecpauth:justify-end ecpauth:gap-2" },
19
+ react_1.default.createElement(button_1.Button, { type: "button", variant: "outline", onClick: () => {
20
+ onOpenChange(false);
21
+ (0, utils_1.unstuckPointerEvents)();
22
+ } }, "Close"))));
23
+ }
@@ -0,0 +1,3 @@
1
+ import React from "react";
2
+ import { OTPProps } from "../types";
3
+ export declare function OptionalOTPWrapper(props: OTPProps): React.JSX.Element | null;
@@ -0,0 +1,52 @@
1
+ "use client";
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.OptionalOTPWrapper = OptionalOTPWrapper;
38
+ const react_1 = __importStar(require("react"));
39
+ const utils_1 = require("../lib/utils");
40
+ function OptionalOTPWrapper(props) {
41
+ const [Inner, setInner] = (0, react_1.useState)(null);
42
+ (0, react_1.useEffect)(() => {
43
+ if (!props.user || !(0, utils_1.isOtpAvailable)())
44
+ return;
45
+ import("./optional-otp.js").then((mod) => {
46
+ setInner(() => mod.OptionalOTPInner);
47
+ });
48
+ }, [props.user]);
49
+ if (!props.user || !Inner)
50
+ return null;
51
+ return react_1.default.createElement(Inner, { ...props });
52
+ }
@@ -0,0 +1,3 @@
1
+ import React from "react";
2
+ import { OTPProps } from "../types";
3
+ export declare function OptionalOTPInner({ user, onVerified, onCanceled }: OTPProps): React.JSX.Element | null;