@githat/nextjs 0.4.0 → 0.4.2

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/index.js CHANGED
@@ -21,15 +21,19 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  // src/index.ts
22
22
  var src_exports = {};
23
23
  __export(src_exports, {
24
+ ChangePasswordForm: () => ChangePasswordForm,
25
+ ForgotPasswordForm: () => ForgotPasswordForm,
24
26
  GitHatProvider: () => GitHatProvider,
25
27
  OrgSwitcher: () => OrgSwitcher,
26
28
  ProtectedRoute: () => ProtectedRoute,
29
+ ResetPasswordForm: () => ResetPasswordForm,
27
30
  SignInButton: () => SignInButton,
28
31
  SignInForm: () => SignInForm,
29
32
  SignUpButton: () => SignUpButton,
30
33
  SignUpForm: () => SignUpForm,
31
34
  UserButton: () => UserButton,
32
35
  VerifiedBadge: () => VerifiedBadge,
36
+ VerifyEmailStatus: () => VerifyEmailStatus,
33
37
  useAuth: () => useAuth,
34
38
  useData: () => useData,
35
39
  useGitHat: () => useGitHat
@@ -122,14 +126,21 @@ function createClient(apiUrl, appKey, options = {}) {
122
126
  });
123
127
  } catch (networkError) {
124
128
  if (networkError instanceof TypeError) {
125
- const isMissingKey = !appKey || !appKey.startsWith("pk_live_");
129
+ const isMissingKey = !appKey || !appKey.startsWith("pk_live_") && !appKey.startsWith("pk_test_");
126
130
  const isLocalhost = typeof window !== "undefined" && (window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1");
127
131
  if (isMissingKey && !isLocalhost) {
128
132
  throw new Error(
129
- "Missing GitHat API key. Add NEXT_PUBLIC_GITHAT_PUBLISHABLE_KEY to .env.local"
133
+ "GitHat: Missing or invalid publishable key. Add NEXT_PUBLIC_GITHAT_PUBLISHABLE_KEY to your environment variables. Get your key at https://githat.io/dashboard/apps"
130
134
  );
131
135
  }
132
- throw new Error("Unable to connect to GitHat API. Check your network connection.");
136
+ if (isLocalhost) {
137
+ throw new Error(
138
+ "GitHat: Cannot reach api.githat.io. Check your internet connection."
139
+ );
140
+ }
141
+ throw new Error(
142
+ "GitHat: API request failed. Verify your publishable key and app domain at https://githat.io/dashboard/apps"
143
+ );
133
144
  }
134
145
  throw networkError;
135
146
  }
@@ -167,10 +178,59 @@ function createClient(apiUrl, appKey, options = {}) {
167
178
  // src/provider.tsx
168
179
  var import_jsx_runtime = require("react/jsx-runtime");
169
180
  var GitHatContext = (0, import_react.createContext)(null);
181
+ function isDevMode(key) {
182
+ return !key || !key.startsWith("pk_live_") && !key.startsWith("pk_test_");
183
+ }
184
+ function DevModeBanner() {
185
+ const [dismissed, setDismissed] = (0, import_react.useState)(() => {
186
+ if (typeof window === "undefined") return true;
187
+ return localStorage.getItem("githat_dev_banner_dismissed") === "1";
188
+ });
189
+ if (dismissed || typeof window === "undefined") return null;
190
+ const hostname = window.location.hostname;
191
+ if (hostname !== "localhost" && hostname !== "127.0.0.1") return null;
192
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "githat-dev-banner", role: "status", children: [
193
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [
194
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: "GitHat Dev Mode" }),
195
+ " \u2014 No publishable key. Auth works on localhost.",
196
+ " ",
197
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { href: "https://githat.io/dashboard/apps", target: "_blank", rel: "noopener noreferrer", children: "Get your key" })
198
+ ] }),
199
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
200
+ "button",
201
+ {
202
+ onClick: () => {
203
+ setDismissed(true);
204
+ localStorage.setItem("githat_dev_banner_dismissed", "1");
205
+ },
206
+ "aria-label": "Dismiss",
207
+ children: "\xD7"
208
+ }
209
+ )
210
+ ] });
211
+ }
170
212
  function GitHatProvider({ config: rawConfig, children }) {
171
213
  const config = (0, import_react.useMemo)(() => resolveConfig(rawConfig), [rawConfig]);
172
214
  const useCookies = config.tokenStorage === "cookie";
215
+ const devMode = isDevMode(config.publishableKey);
173
216
  const clientRef = (0, import_react.useRef)(createClient(config.apiUrl, config.publishableKey, { useCookies }));
217
+ (0, import_react.useEffect)(() => {
218
+ if (!devMode || typeof window === "undefined") return;
219
+ const hostname = window.location.hostname;
220
+ if (hostname === "localhost" || hostname === "127.0.0.1") {
221
+ console.warn(
222
+ "%c GitHat Dev Mode %c No publishable key configured. Auth works on localhost but will fail in production. Get your key at https://githat.io/dashboard/apps",
223
+ "background: #f59e0b; color: #000; font-weight: bold; padding: 2px 6px; border-radius: 3px;",
224
+ "color: #f59e0b;"
225
+ );
226
+ } else {
227
+ console.error(
228
+ "%c GitHat %c Missing publishable key. Auth requests will fail. Add NEXT_PUBLIC_GITHAT_PUBLISHABLE_KEY to your environment. Get your key at https://githat.io/dashboard/apps",
229
+ "background: #ef4444; color: #fff; font-weight: bold; padding: 2px 6px; border-radius: 3px;",
230
+ "color: #ef4444;"
231
+ );
232
+ }
233
+ }, []);
174
234
  const [user, setUser] = (0, import_react.useState)(null);
175
235
  const [org, setOrg] = (0, import_react.useState)(null);
176
236
  const [isSignedIn, setIsSignedIn] = (0, import_react.useState)(false);
@@ -318,7 +378,10 @@ function GitHatProvider({ config: rawConfig, children }) {
318
378
  signOut,
319
379
  switchOrg
320
380
  }), [user, org, isSignedIn, isLoading, authError, config, signIn, signUp, signOut, switchOrg]);
321
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GitHatContext.Provider, { value, children });
381
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(GitHatContext.Provider, { value, children: [
382
+ devMode && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DevModeBanner, {}),
383
+ children
384
+ ] });
322
385
  }
323
386
 
324
387
  // src/hooks.ts
@@ -359,13 +422,90 @@ function useGitHat() {
359
422
  },
360
423
  [client, ctx.org?.id]
361
424
  );
425
+ const forgotPassword = (0, import_react2.useCallback)(
426
+ async (email) => {
427
+ const response = await fetch(`${ctx.config.apiUrl}/auth/forgot-password`, {
428
+ method: "POST",
429
+ headers: { "Content-Type": "application/json" },
430
+ body: JSON.stringify({ email })
431
+ });
432
+ if (!response.ok) {
433
+ const error = await response.json().catch(() => ({}));
434
+ throw new Error(error.message || "Failed to send reset email");
435
+ }
436
+ return { success: true };
437
+ },
438
+ [ctx.config.apiUrl]
439
+ );
440
+ const resetPassword = (0, import_react2.useCallback)(
441
+ async (token, newPassword) => {
442
+ const response = await fetch(`${ctx.config.apiUrl}/auth/reset-password`, {
443
+ method: "POST",
444
+ headers: { "Content-Type": "application/json" },
445
+ body: JSON.stringify({ token, password: newPassword })
446
+ });
447
+ if (!response.ok) {
448
+ const error = await response.json().catch(() => ({}));
449
+ throw new Error(error.message || "Failed to reset password");
450
+ }
451
+ return { success: true };
452
+ },
453
+ [ctx.config.apiUrl]
454
+ );
455
+ const changePassword = (0, import_react2.useCallback)(
456
+ async (currentPassword, newPassword) => {
457
+ await client.fetchApi("/auth/change-password", {
458
+ method: "POST",
459
+ body: JSON.stringify({ currentPassword, newPassword })
460
+ });
461
+ return { success: true };
462
+ },
463
+ [client]
464
+ );
465
+ const verifyEmail = (0, import_react2.useCallback)(
466
+ async (token) => {
467
+ const response = await fetch(`${ctx.config.apiUrl}/auth/verify-email`, {
468
+ method: "POST",
469
+ headers: { "Content-Type": "application/json" },
470
+ body: JSON.stringify({ token })
471
+ });
472
+ if (!response.ok) {
473
+ const error = await response.json().catch(() => ({}));
474
+ throw new Error(error.message || "Failed to verify email");
475
+ }
476
+ return { success: true };
477
+ },
478
+ [ctx.config.apiUrl]
479
+ );
480
+ const resendVerificationEmail = (0, import_react2.useCallback)(
481
+ async (email) => {
482
+ const response = await fetch(`${ctx.config.apiUrl}/auth/resend-verification`, {
483
+ method: "POST",
484
+ headers: { "Content-Type": "application/json" },
485
+ body: JSON.stringify({ email })
486
+ });
487
+ if (!response.ok) {
488
+ const error = await response.json().catch(() => ({}));
489
+ throw new Error(error.message || "Failed to resend verification email");
490
+ }
491
+ return { success: true };
492
+ },
493
+ [ctx.config.apiUrl]
494
+ );
362
495
  return {
363
496
  fetch: client.fetchApi,
364
497
  getUserOrgs: () => client.fetchApi("/user/orgs"),
365
498
  verifyMCP: (domain) => client.fetchApi(`/verify/mcp/${domain}`),
366
499
  verifyAgent: (wallet) => client.fetchApi(`/verify/agent/${wallet}`),
367
500
  getOrgMetadata,
368
- updateOrgMetadata
501
+ updateOrgMetadata,
502
+ // Password management
503
+ forgotPassword,
504
+ resetPassword,
505
+ changePassword,
506
+ // Email verification
507
+ verifyEmail,
508
+ resendVerificationEmail
369
509
  };
370
510
  }
371
511
 
@@ -808,17 +948,410 @@ function ProtectedRoute({ children, fallback }) {
808
948
  }
809
949
  return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_jsx_runtime9.Fragment, { children });
810
950
  }
951
+
952
+ // src/components/ForgotPasswordForm.tsx
953
+ var import_react11 = require("react");
954
+ var import_jsx_runtime10 = require("react/jsx-runtime");
955
+ function ForgotPasswordForm({
956
+ onSuccess,
957
+ onError,
958
+ signInUrl = "/sign-in"
959
+ }) {
960
+ const { forgotPassword } = useGitHat();
961
+ const [email, setEmail] = (0, import_react11.useState)("");
962
+ const [isLoading, setIsLoading] = (0, import_react11.useState)(false);
963
+ const [sent, setSent] = (0, import_react11.useState)(false);
964
+ const [error, setError] = (0, import_react11.useState)("");
965
+ const emailValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
966
+ const handleSubmit = async (e) => {
967
+ e.preventDefault();
968
+ if (!emailValid) {
969
+ setError("Please enter a valid email address");
970
+ return;
971
+ }
972
+ setIsLoading(true);
973
+ setError("");
974
+ try {
975
+ await forgotPassword(email);
976
+ setSent(true);
977
+ onSuccess?.(email);
978
+ } catch (err) {
979
+ const message = err instanceof Error ? err.message : "Failed to send reset email";
980
+ setError(message);
981
+ onError?.(err instanceof Error ? err : new Error(message));
982
+ } finally {
983
+ setIsLoading(false);
984
+ }
985
+ };
986
+ if (sent) {
987
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "githat-form-container", children: [
988
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "githat-form-header", children: [
989
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h2", { className: "githat-form-title", children: "Check your email" }),
990
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("p", { className: "githat-form-subtitle", children: [
991
+ "We sent a password reset link to ",
992
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("strong", { children: email })
993
+ ] })
994
+ ] }),
995
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("a", { href: signInUrl, className: "githat-link", children: "Back to sign in" }),
996
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("p", { className: "githat-powered-by", children: [
997
+ "Secured by ",
998
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("strong", { children: "GitHat" })
999
+ ] })
1000
+ ] });
1001
+ }
1002
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "githat-form-container", children: [
1003
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "githat-form-header", children: [
1004
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h2", { className: "githat-form-title", children: "Forgot password" }),
1005
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "githat-form-subtitle", children: "Enter your email and we'll send you a reset link" })
1006
+ ] }),
1007
+ error && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "githat-alert githat-alert-error", role: "alert", "aria-live": "polite", children: error }),
1008
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("form", { onSubmit: handleSubmit, className: "githat-form", "aria-label": "Forgot password form", children: [
1009
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "githat-field", children: [
1010
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { className: "githat-label", htmlFor: "githat-forgot-email", children: "Email" }),
1011
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1012
+ "input",
1013
+ {
1014
+ id: "githat-forgot-email",
1015
+ className: "githat-input",
1016
+ type: "email",
1017
+ value: email,
1018
+ onChange: (e) => setEmail(e.target.value),
1019
+ placeholder: "you@example.com",
1020
+ autoComplete: "email",
1021
+ disabled: isLoading,
1022
+ required: true
1023
+ }
1024
+ )
1025
+ ] }),
1026
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1027
+ "button",
1028
+ {
1029
+ type: "submit",
1030
+ className: "githat-button githat-button-primary",
1031
+ disabled: isLoading || !email || email.length > 0 && !emailValid,
1032
+ children: isLoading ? "Sending..." : "Send reset link"
1033
+ }
1034
+ )
1035
+ ] }),
1036
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("p", { className: "githat-form-footer", children: [
1037
+ "Remember your password? ",
1038
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("a", { href: signInUrl, className: "githat-link", children: "Sign in" })
1039
+ ] }),
1040
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("p", { className: "githat-powered-by", children: [
1041
+ "Secured by ",
1042
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("strong", { children: "GitHat" })
1043
+ ] })
1044
+ ] });
1045
+ }
1046
+
1047
+ // src/components/ResetPasswordForm.tsx
1048
+ var import_react12 = require("react");
1049
+ var import_jsx_runtime11 = require("react/jsx-runtime");
1050
+ function ResetPasswordForm({
1051
+ token,
1052
+ onSuccess,
1053
+ onError,
1054
+ signInUrl = "/sign-in",
1055
+ minPasswordLength = 8
1056
+ }) {
1057
+ const { resetPassword } = useGitHat();
1058
+ const [password, setPassword] = (0, import_react12.useState)("");
1059
+ const [confirm, setConfirm] = (0, import_react12.useState)("");
1060
+ const [isLoading, setIsLoading] = (0, import_react12.useState)(false);
1061
+ const [success, setSuccess] = (0, import_react12.useState)(false);
1062
+ const [error, setError] = (0, import_react12.useState)("");
1063
+ const handleSubmit = async (e) => {
1064
+ e.preventDefault();
1065
+ if (password !== confirm) {
1066
+ setError("Passwords do not match");
1067
+ return;
1068
+ }
1069
+ if (password.length < minPasswordLength) {
1070
+ setError(`Password must be at least ${minPasswordLength} characters`);
1071
+ return;
1072
+ }
1073
+ setIsLoading(true);
1074
+ setError("");
1075
+ try {
1076
+ await resetPassword(token, password);
1077
+ setSuccess(true);
1078
+ onSuccess?.();
1079
+ } catch (err) {
1080
+ const message = err instanceof Error ? err.message : "Failed to reset password";
1081
+ setError(message);
1082
+ onError?.(err instanceof Error ? err : new Error(message));
1083
+ } finally {
1084
+ setIsLoading(false);
1085
+ }
1086
+ };
1087
+ if (success) {
1088
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "githat-form-container", children: [
1089
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "githat-form-header", children: [
1090
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h2", { className: "githat-form-title", children: "Password reset!" }),
1091
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "githat-form-subtitle", children: "Your password has been successfully reset." })
1092
+ ] }),
1093
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("a", { href: signInUrl, className: "githat-button githat-button-primary", style: { display: "block", textAlign: "center", textDecoration: "none" }, children: "Sign in" }),
1094
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("p", { className: "githat-powered-by", children: [
1095
+ "Secured by ",
1096
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("strong", { children: "GitHat" })
1097
+ ] })
1098
+ ] });
1099
+ }
1100
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "githat-form-container", children: [
1101
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "githat-form-header", children: [
1102
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h2", { className: "githat-form-title", children: "Reset password" }),
1103
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "githat-form-subtitle", children: "Enter your new password" })
1104
+ ] }),
1105
+ error && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "githat-alert githat-alert-error", role: "alert", "aria-live": "polite", children: error }),
1106
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("form", { onSubmit: handleSubmit, className: "githat-form", "aria-label": "Reset password form", children: [
1107
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "githat-field", children: [
1108
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("label", { className: "githat-label", htmlFor: "githat-reset-password", children: "New password" }),
1109
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1110
+ "input",
1111
+ {
1112
+ id: "githat-reset-password",
1113
+ className: "githat-input",
1114
+ type: "password",
1115
+ value: password,
1116
+ onChange: (e) => setPassword(e.target.value),
1117
+ placeholder: "Enter new password",
1118
+ autoComplete: "new-password",
1119
+ disabled: isLoading,
1120
+ required: true,
1121
+ minLength: minPasswordLength
1122
+ }
1123
+ )
1124
+ ] }),
1125
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "githat-field", children: [
1126
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("label", { className: "githat-label", htmlFor: "githat-reset-confirm", children: "Confirm password" }),
1127
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1128
+ "input",
1129
+ {
1130
+ id: "githat-reset-confirm",
1131
+ className: "githat-input",
1132
+ type: "password",
1133
+ value: confirm,
1134
+ onChange: (e) => setConfirm(e.target.value),
1135
+ placeholder: "Confirm new password",
1136
+ autoComplete: "new-password",
1137
+ disabled: isLoading,
1138
+ required: true
1139
+ }
1140
+ )
1141
+ ] }),
1142
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1143
+ "button",
1144
+ {
1145
+ type: "submit",
1146
+ className: "githat-button githat-button-primary",
1147
+ disabled: isLoading || !password || !confirm,
1148
+ children: isLoading ? "Resetting..." : "Reset password"
1149
+ }
1150
+ )
1151
+ ] }),
1152
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("p", { className: "githat-powered-by", children: [
1153
+ "Secured by ",
1154
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("strong", { children: "GitHat" })
1155
+ ] })
1156
+ ] });
1157
+ }
1158
+
1159
+ // src/components/VerifyEmailStatus.tsx
1160
+ var import_react13 = require("react");
1161
+ var import_jsx_runtime12 = require("react/jsx-runtime");
1162
+ function VerifyEmailStatus({
1163
+ token,
1164
+ onSuccess,
1165
+ onError,
1166
+ signInUrl = "/sign-in",
1167
+ redirectDelay = 3e3
1168
+ }) {
1169
+ const { verifyEmail } = useGitHat();
1170
+ const [status, setStatus] = (0, import_react13.useState)("loading");
1171
+ const [error, setError] = (0, import_react13.useState)("");
1172
+ (0, import_react13.useEffect)(() => {
1173
+ if (!token) {
1174
+ setStatus("error");
1175
+ setError("Missing verification token");
1176
+ return;
1177
+ }
1178
+ verifyEmail(token).then(() => {
1179
+ setStatus("success");
1180
+ onSuccess?.();
1181
+ if (signInUrl && redirectDelay > 0) {
1182
+ setTimeout(() => {
1183
+ window.location.href = signInUrl;
1184
+ }, redirectDelay);
1185
+ }
1186
+ }).catch((err) => {
1187
+ setStatus("error");
1188
+ const message = err instanceof Error ? err.message : "Verification failed";
1189
+ setError(message);
1190
+ onError?.(err instanceof Error ? err : new Error(message));
1191
+ });
1192
+ }, [token, verifyEmail, onSuccess, onError, signInUrl, redirectDelay]);
1193
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "githat-form-container", children: [
1194
+ status === "loading" && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "githat-form-header", children: [
1195
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h2", { className: "githat-form-title", children: "Verifying email..." }),
1196
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "githat-form-subtitle", children: "Please wait while we verify your email address." })
1197
+ ] }),
1198
+ status === "success" && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
1199
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "githat-form-header", children: [
1200
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h2", { className: "githat-form-title", children: "Email verified!" }),
1201
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "githat-form-subtitle", children: "Your email has been successfully verified. Redirecting to sign in..." })
1202
+ ] }),
1203
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("a", { href: signInUrl, className: "githat-button githat-button-primary", style: { display: "block", textAlign: "center", textDecoration: "none" }, children: "Sign in now" })
1204
+ ] }),
1205
+ status === "error" && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
1206
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "githat-form-header", children: [
1207
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h2", { className: "githat-form-title", children: "Verification failed" }),
1208
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "githat-form-subtitle", children: error })
1209
+ ] }),
1210
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("p", { className: "githat-form-footer", children: [
1211
+ "The link may have expired. ",
1212
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("a", { href: "/sign-up", className: "githat-link", children: "Try signing up again" })
1213
+ ] })
1214
+ ] }),
1215
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("p", { className: "githat-powered-by", children: [
1216
+ "Secured by ",
1217
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("strong", { children: "GitHat" })
1218
+ ] })
1219
+ ] });
1220
+ }
1221
+
1222
+ // src/components/ChangePasswordForm.tsx
1223
+ var import_react14 = require("react");
1224
+ var import_jsx_runtime13 = require("react/jsx-runtime");
1225
+ function ChangePasswordForm({
1226
+ onSuccess,
1227
+ onError,
1228
+ minPasswordLength = 8
1229
+ }) {
1230
+ const { changePassword } = useGitHat();
1231
+ const [current, setCurrent] = (0, import_react14.useState)("");
1232
+ const [newPass, setNewPass] = (0, import_react14.useState)("");
1233
+ const [confirm, setConfirm] = (0, import_react14.useState)("");
1234
+ const [isLoading, setIsLoading] = (0, import_react14.useState)(false);
1235
+ const [error, setError] = (0, import_react14.useState)("");
1236
+ const [success, setSuccess] = (0, import_react14.useState)(false);
1237
+ const handleSubmit = async (e) => {
1238
+ e.preventDefault();
1239
+ if (newPass !== confirm) {
1240
+ setError("Passwords do not match");
1241
+ return;
1242
+ }
1243
+ if (newPass.length < minPasswordLength) {
1244
+ setError(`Password must be at least ${minPasswordLength} characters`);
1245
+ return;
1246
+ }
1247
+ setIsLoading(true);
1248
+ setError("");
1249
+ try {
1250
+ await changePassword(current, newPass);
1251
+ setSuccess(true);
1252
+ setCurrent("");
1253
+ setNewPass("");
1254
+ setConfirm("");
1255
+ onSuccess?.();
1256
+ } catch (err) {
1257
+ const message = err instanceof Error ? err.message : "Failed to change password";
1258
+ setError(message);
1259
+ onError?.(err instanceof Error ? err : new Error(message));
1260
+ } finally {
1261
+ setIsLoading(false);
1262
+ }
1263
+ };
1264
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "githat-form-container", children: [
1265
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "githat-form-header", children: [
1266
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("h2", { className: "githat-form-title", children: "Change password" }),
1267
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "githat-form-subtitle", children: "Update your account password" })
1268
+ ] }),
1269
+ success && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "githat-alert githat-alert-success", role: "status", "aria-live": "polite", children: "Password changed successfully!" }),
1270
+ error && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "githat-alert githat-alert-error", role: "alert", "aria-live": "polite", children: error }),
1271
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("form", { onSubmit: handleSubmit, className: "githat-form", "aria-label": "Change password form", children: [
1272
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "githat-field", children: [
1273
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { className: "githat-label", htmlFor: "githat-change-current", children: "Current password" }),
1274
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1275
+ "input",
1276
+ {
1277
+ id: "githat-change-current",
1278
+ className: "githat-input",
1279
+ type: "password",
1280
+ value: current,
1281
+ onChange: (e) => setCurrent(e.target.value),
1282
+ placeholder: "Enter current password",
1283
+ autoComplete: "current-password",
1284
+ disabled: isLoading,
1285
+ required: true
1286
+ }
1287
+ )
1288
+ ] }),
1289
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "githat-field", children: [
1290
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { className: "githat-label", htmlFor: "githat-change-new", children: "New password" }),
1291
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1292
+ "input",
1293
+ {
1294
+ id: "githat-change-new",
1295
+ className: "githat-input",
1296
+ type: "password",
1297
+ value: newPass,
1298
+ onChange: (e) => setNewPass(e.target.value),
1299
+ placeholder: "Enter new password",
1300
+ autoComplete: "new-password",
1301
+ disabled: isLoading,
1302
+ required: true,
1303
+ minLength: minPasswordLength
1304
+ }
1305
+ )
1306
+ ] }),
1307
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "githat-field", children: [
1308
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { className: "githat-label", htmlFor: "githat-change-confirm", children: "Confirm new password" }),
1309
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1310
+ "input",
1311
+ {
1312
+ id: "githat-change-confirm",
1313
+ className: "githat-input",
1314
+ type: "password",
1315
+ value: confirm,
1316
+ onChange: (e) => setConfirm(e.target.value),
1317
+ placeholder: "Confirm new password",
1318
+ autoComplete: "new-password",
1319
+ disabled: isLoading,
1320
+ required: true
1321
+ }
1322
+ )
1323
+ ] }),
1324
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1325
+ "button",
1326
+ {
1327
+ type: "submit",
1328
+ className: "githat-button githat-button-primary",
1329
+ disabled: isLoading || !current || !newPass || !confirm,
1330
+ children: isLoading ? "Changing..." : "Change password"
1331
+ }
1332
+ )
1333
+ ] }),
1334
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("p", { className: "githat-powered-by", children: [
1335
+ "Secured by ",
1336
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("strong", { children: "GitHat" })
1337
+ ] })
1338
+ ] });
1339
+ }
811
1340
  // Annotate the CommonJS export names for ESM import in node:
812
1341
  0 && (module.exports = {
1342
+ ChangePasswordForm,
1343
+ ForgotPasswordForm,
813
1344
  GitHatProvider,
814
1345
  OrgSwitcher,
815
1346
  ProtectedRoute,
1347
+ ResetPasswordForm,
816
1348
  SignInButton,
817
1349
  SignInForm,
818
1350
  SignUpButton,
819
1351
  SignUpForm,
820
1352
  UserButton,
821
1353
  VerifiedBadge,
1354
+ VerifyEmailStatus,
822
1355
  useAuth,
823
1356
  useData,
824
1357
  useGitHat