@githat/nextjs 0.2.5 → 0.2.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.
package/dist/index.js CHANGED
@@ -22,8 +22,12 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
22
22
  var src_exports = {};
23
23
  __export(src_exports, {
24
24
  ChangePasswordForm: () => ChangePasswordForm,
25
+ CognitoButton: () => CognitoButton,
26
+ CognitoCallback: () => CognitoCallback,
25
27
  ForgotPasswordForm: () => ForgotPasswordForm,
26
28
  GitHatProvider: () => GitHatProvider,
29
+ GitHubButton: () => GitHubButton,
30
+ GitHubCallback: () => GitHubCallback,
27
31
  OrgSwitcher: () => OrgSwitcher,
28
32
  ProtectedRoute: () => ProtectedRoute,
29
33
  ResetPasswordForm: () => ResetPasswordForm,
@@ -36,6 +40,7 @@ __export(src_exports, {
36
40
  VerifyEmailStatus: () => VerifyEmailStatus,
37
41
  useAuth: () => useAuth,
38
42
  useData: () => useData,
43
+ useEmail: () => useEmail,
39
44
  useGitHat: () => useGitHat
40
45
  });
41
46
  module.exports = __toCommonJS(src_exports);
@@ -472,6 +477,73 @@ function useGitHat() {
472
477
  },
473
478
  [client]
474
479
  );
480
+ const getGitHubOAuthUrl = (0, import_react2.useCallback)(
481
+ async (options) => {
482
+ const params = new URLSearchParams();
483
+ if (options?.redirectUri) params.append("redirectUri", options.redirectUri);
484
+ if (options?.state) params.append("state", options.state);
485
+ const queryString = params.toString();
486
+ const path = queryString ? `/auth/oauth/github/url?${queryString}` : "/auth/oauth/github/url";
487
+ return client.fetchApi(path);
488
+ },
489
+ [client]
490
+ );
491
+ const signInWithGitHub = (0, import_react2.useCallback)(
492
+ async (code, options) => {
493
+ const response = await client.fetchApi("/auth/oauth/github", {
494
+ method: "POST",
495
+ body: JSON.stringify({
496
+ code,
497
+ redirectUri: options?.redirectUri
498
+ })
499
+ });
500
+ if (response.accessToken) {
501
+ window.dispatchEvent(new CustomEvent("githat:auth-changed", {
502
+ detail: { user: response.user, org: response.org, signedIn: true }
503
+ }));
504
+ }
505
+ return {
506
+ user: response.user,
507
+ org: response.org,
508
+ isNewUser: response.isNewUser
509
+ };
510
+ },
511
+ [client]
512
+ );
513
+ const getCognitoOAuthUrl = (0, import_react2.useCallback)(
514
+ async (options) => {
515
+ const params = new URLSearchParams();
516
+ if (options?.redirectUri) params.append("redirectUri", options.redirectUri);
517
+ if (options?.state) params.append("state", options.state);
518
+ if (options?.identityProvider) params.append("identityProvider", options.identityProvider);
519
+ const queryString = params.toString();
520
+ const path = queryString ? `/auth/oauth/cognito/url?${queryString}` : "/auth/oauth/cognito/url";
521
+ return client.fetchApi(path);
522
+ },
523
+ [client]
524
+ );
525
+ const signInWithCognito = (0, import_react2.useCallback)(
526
+ async (code, options) => {
527
+ const response = await client.fetchApi("/auth/oauth/cognito", {
528
+ method: "POST",
529
+ body: JSON.stringify({
530
+ code,
531
+ redirectUri: options?.redirectUri
532
+ })
533
+ });
534
+ if (response.accessToken) {
535
+ window.dispatchEvent(new CustomEvent("githat:auth-changed", {
536
+ detail: { user: response.user, org: response.org, signedIn: true }
537
+ }));
538
+ }
539
+ return {
540
+ user: response.user,
541
+ org: response.org,
542
+ isNewUser: response.isNewUser
543
+ };
544
+ },
545
+ [client]
546
+ );
475
547
  return {
476
548
  fetch: client.fetchApi,
477
549
  getUserOrgs: () => client.fetchApi("/user/orgs"),
@@ -485,7 +557,12 @@ function useGitHat() {
485
557
  changePassword,
486
558
  // Email verification
487
559
  verifyEmail,
488
- resendVerificationEmail
560
+ resendVerificationEmail,
561
+ // OAuth (Web2)
562
+ getGitHubOAuthUrl,
563
+ signInWithGitHub,
564
+ getCognitoOAuthUrl,
565
+ signInWithCognito
489
566
  };
490
567
  }
491
568
 
@@ -567,15 +644,40 @@ function useData() {
567
644
  }), [client]);
568
645
  }
569
646
 
570
- // src/components/SignInForm.tsx
647
+ // src/email.ts
571
648
  var import_react4 = require("react");
649
+ function useEmail() {
650
+ const ctx = useAuth();
651
+ const client = (0, import_react4.useMemo)(
652
+ () => createClient(ctx.config.apiUrl, ctx.config.publishableKey),
653
+ [ctx.config.apiUrl, ctx.config.publishableKey]
654
+ );
655
+ return (0, import_react4.useMemo)(() => ({
656
+ /**
657
+ * Send a transactional email.
658
+ * @param options - Email options (to, subject, html/text, replyTo)
659
+ */
660
+ send: async (options) => {
661
+ if (!options.to) throw new Error('Recipient "to" is required');
662
+ if (!options.subject) throw new Error("Subject is required");
663
+ if (!options.html && !options.text) throw new Error('At least one of "html" or "text" is required');
664
+ return client.fetchApi("/email/send", {
665
+ method: "POST",
666
+ body: JSON.stringify(options)
667
+ });
668
+ }
669
+ }), [client]);
670
+ }
671
+
672
+ // src/components/SignInForm.tsx
673
+ var import_react5 = require("react");
572
674
  var import_jsx_runtime2 = require("react/jsx-runtime");
573
675
  function SignInForm({ onSuccess, signUpUrl, forgotPasswordUrl }) {
574
676
  const { signIn, config } = useAuth();
575
- const [email, setEmail] = (0, import_react4.useState)("");
576
- const [password, setPassword] = (0, import_react4.useState)("");
577
- const [error, setError] = (0, import_react4.useState)("");
578
- const [loading, setLoading] = (0, import_react4.useState)(false);
677
+ const [email, setEmail] = (0, import_react5.useState)("");
678
+ const [password, setPassword] = (0, import_react5.useState)("");
679
+ const [error, setError] = (0, import_react5.useState)("");
680
+ const [loading, setLoading] = (0, import_react5.useState)(false);
579
681
  const emailValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
580
682
  const handleSubmit = async (e) => {
581
683
  e.preventDefault();
@@ -661,15 +763,15 @@ function SignInForm({ onSuccess, signUpUrl, forgotPasswordUrl }) {
661
763
  }
662
764
 
663
765
  // src/components/SignUpForm.tsx
664
- var import_react5 = require("react");
766
+ var import_react6 = require("react");
665
767
  var import_jsx_runtime3 = require("react/jsx-runtime");
666
768
  function SignUpForm({ onSuccess, signInUrl }) {
667
769
  const { signUp, config } = useAuth();
668
- const [name, setName] = (0, import_react5.useState)("");
669
- const [email, setEmail] = (0, import_react5.useState)("");
670
- const [password, setPassword] = (0, import_react5.useState)("");
671
- const [error, setError] = (0, import_react5.useState)("");
672
- const [loading, setLoading] = (0, import_react5.useState)(false);
770
+ const [name, setName] = (0, import_react6.useState)("");
771
+ const [email, setEmail] = (0, import_react6.useState)("");
772
+ const [password, setPassword] = (0, import_react6.useState)("");
773
+ const [error, setError] = (0, import_react6.useState)("");
774
+ const [loading, setLoading] = (0, import_react6.useState)(false);
673
775
  const emailValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
674
776
  const passwordValid = password.length >= 8 && /[A-Z]/.test(password) && /[a-z]/.test(password) && /\d/.test(password);
675
777
  const handleSubmit = async (e) => {
@@ -775,31 +877,31 @@ function SignUpForm({ onSuccess, signInUrl }) {
775
877
  }
776
878
 
777
879
  // src/components/SignInButton.tsx
778
- var import_react6 = require("react");
880
+ var import_react7 = require("react");
779
881
  var import_jsx_runtime4 = require("react/jsx-runtime");
780
882
  function SignInButton({ className, children, href }) {
781
- const ctx = (0, import_react6.useContext)(GitHatContext);
883
+ const ctx = (0, import_react7.useContext)(GitHatContext);
782
884
  const url = href || ctx?.config.signInUrl || "/sign-in";
783
885
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("a", { href: url, className: className || "githat-button githat-button-primary", "aria-label": "Sign in", children: children || "Sign in" });
784
886
  }
785
887
 
786
888
  // src/components/SignUpButton.tsx
787
- var import_react7 = require("react");
889
+ var import_react8 = require("react");
788
890
  var import_jsx_runtime5 = require("react/jsx-runtime");
789
891
  function SignUpButton({ className, children, href }) {
790
- const ctx = (0, import_react7.useContext)(GitHatContext);
892
+ const ctx = (0, import_react8.useContext)(GitHatContext);
791
893
  const url = href || ctx?.config.signUpUrl || "/sign-up";
792
894
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("a", { href: url, className: className || "githat-button githat-button-outline", "aria-label": "Sign up", children: children || "Sign up" });
793
895
  }
794
896
 
795
897
  // src/components/UserButton.tsx
796
- var import_react8 = require("react");
898
+ var import_react9 = require("react");
797
899
  var import_jsx_runtime6 = require("react/jsx-runtime");
798
900
  function UserButton() {
799
901
  const { user, org, isSignedIn, signOut } = useAuth();
800
- const [open, setOpen] = (0, import_react8.useState)(false);
801
- const ref = (0, import_react8.useRef)(null);
802
- (0, import_react8.useEffect)(() => {
902
+ const [open, setOpen] = (0, import_react9.useState)(false);
903
+ const ref = (0, import_react9.useRef)(null);
904
+ (0, import_react9.useEffect)(() => {
803
905
  const handleClickOutside = (e) => {
804
906
  if (ref.current && !ref.current.contains(e.target)) setOpen(false);
805
907
  };
@@ -826,23 +928,23 @@ function UserButton() {
826
928
  }
827
929
 
828
930
  // src/components/OrgSwitcher.tsx
829
- var import_react9 = require("react");
931
+ var import_react10 = require("react");
830
932
  var import_jsx_runtime7 = require("react/jsx-runtime");
831
933
  function OrgSwitcher() {
832
934
  const { org, isSignedIn, switchOrg } = useAuth();
833
935
  const githat = useGitHat();
834
- const [orgs, setOrgs] = (0, import_react9.useState)([]);
835
- const [orgsLoading, setOrgsLoading] = (0, import_react9.useState)(false);
836
- const [open, setOpen] = (0, import_react9.useState)(false);
837
- const ref = (0, import_react9.useRef)(null);
838
- (0, import_react9.useEffect)(() => {
936
+ const [orgs, setOrgs] = (0, import_react10.useState)([]);
937
+ const [orgsLoading, setOrgsLoading] = (0, import_react10.useState)(false);
938
+ const [open, setOpen] = (0, import_react10.useState)(false);
939
+ const ref = (0, import_react10.useRef)(null);
940
+ (0, import_react10.useEffect)(() => {
839
941
  if (isSignedIn) {
840
942
  setOrgsLoading(true);
841
943
  githat.getUserOrgs().then((data) => setOrgs(data.orgs || [])).catch(() => {
842
944
  }).finally(() => setOrgsLoading(false));
843
945
  }
844
946
  }, [isSignedIn]);
845
- (0, import_react9.useEffect)(() => {
947
+ (0, import_react10.useEffect)(() => {
846
948
  const handleClickOutside = (e) => {
847
949
  if (ref.current && !ref.current.contains(e.target)) setOpen(false);
848
950
  };
@@ -876,15 +978,15 @@ function OrgSwitcher() {
876
978
  }
877
979
 
878
980
  // src/components/VerifiedBadge.tsx
879
- var import_react10 = require("react");
981
+ var import_react11 = require("react");
880
982
  var import_jsx_runtime8 = require("react/jsx-runtime");
881
983
  var CACHE_TTL = 5 * 60 * 1e3;
882
984
  var cache = /* @__PURE__ */ new Map();
883
985
  function VerifiedBadge({ type, identifier, label }) {
884
986
  const githat = useGitHat();
885
- const [verified, setVerified] = (0, import_react10.useState)(null);
886
- const mounted = (0, import_react10.useRef)(true);
887
- (0, import_react10.useEffect)(() => {
987
+ const [verified, setVerified] = (0, import_react11.useState)(null);
988
+ const mounted = (0, import_react11.useRef)(true);
989
+ (0, import_react11.useEffect)(() => {
888
990
  mounted.current = true;
889
991
  const key = `${type}:${identifier}`;
890
992
  const cached = cache.get(key);
@@ -930,7 +1032,7 @@ function ProtectedRoute({ children, fallback }) {
930
1032
  }
931
1033
 
932
1034
  // src/components/ForgotPasswordForm.tsx
933
- var import_react11 = require("react");
1035
+ var import_react12 = require("react");
934
1036
  var import_jsx_runtime10 = require("react/jsx-runtime");
935
1037
  function ForgotPasswordForm({
936
1038
  onSuccess,
@@ -938,10 +1040,10 @@ function ForgotPasswordForm({
938
1040
  signInUrl = "/sign-in"
939
1041
  }) {
940
1042
  const { forgotPassword } = useGitHat();
941
- const [email, setEmail] = (0, import_react11.useState)("");
942
- const [isLoading, setIsLoading] = (0, import_react11.useState)(false);
943
- const [sent, setSent] = (0, import_react11.useState)(false);
944
- const [error, setError] = (0, import_react11.useState)("");
1043
+ const [email, setEmail] = (0, import_react12.useState)("");
1044
+ const [isLoading, setIsLoading] = (0, import_react12.useState)(false);
1045
+ const [sent, setSent] = (0, import_react12.useState)(false);
1046
+ const [error, setError] = (0, import_react12.useState)("");
945
1047
  const emailValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
946
1048
  const handleSubmit = async (e) => {
947
1049
  e.preventDefault();
@@ -1025,7 +1127,7 @@ function ForgotPasswordForm({
1025
1127
  }
1026
1128
 
1027
1129
  // src/components/ResetPasswordForm.tsx
1028
- var import_react12 = require("react");
1130
+ var import_react13 = require("react");
1029
1131
  var import_jsx_runtime11 = require("react/jsx-runtime");
1030
1132
  function ResetPasswordForm({
1031
1133
  token,
@@ -1035,11 +1137,11 @@ function ResetPasswordForm({
1035
1137
  minPasswordLength = 8
1036
1138
  }) {
1037
1139
  const { resetPassword } = useGitHat();
1038
- const [password, setPassword] = (0, import_react12.useState)("");
1039
- const [confirm, setConfirm] = (0, import_react12.useState)("");
1040
- const [isLoading, setIsLoading] = (0, import_react12.useState)(false);
1041
- const [success, setSuccess] = (0, import_react12.useState)(false);
1042
- const [error, setError] = (0, import_react12.useState)("");
1140
+ const [password, setPassword] = (0, import_react13.useState)("");
1141
+ const [confirm, setConfirm] = (0, import_react13.useState)("");
1142
+ const [isLoading, setIsLoading] = (0, import_react13.useState)(false);
1143
+ const [success, setSuccess] = (0, import_react13.useState)(false);
1144
+ const [error, setError] = (0, import_react13.useState)("");
1043
1145
  const handleSubmit = async (e) => {
1044
1146
  e.preventDefault();
1045
1147
  if (password !== confirm) {
@@ -1137,7 +1239,7 @@ function ResetPasswordForm({
1137
1239
  }
1138
1240
 
1139
1241
  // src/components/VerifyEmailStatus.tsx
1140
- var import_react13 = require("react");
1242
+ var import_react14 = require("react");
1141
1243
  var import_jsx_runtime12 = require("react/jsx-runtime");
1142
1244
  function VerifyEmailStatus({
1143
1245
  token,
@@ -1147,9 +1249,9 @@ function VerifyEmailStatus({
1147
1249
  redirectDelay = 3e3
1148
1250
  }) {
1149
1251
  const { verifyEmail } = useGitHat();
1150
- const [status, setStatus] = (0, import_react13.useState)("loading");
1151
- const [error, setError] = (0, import_react13.useState)("");
1152
- (0, import_react13.useEffect)(() => {
1252
+ const [status, setStatus] = (0, import_react14.useState)("loading");
1253
+ const [error, setError] = (0, import_react14.useState)("");
1254
+ (0, import_react14.useEffect)(() => {
1153
1255
  if (!token) {
1154
1256
  setStatus("error");
1155
1257
  setError("Missing verification token");
@@ -1200,7 +1302,7 @@ function VerifyEmailStatus({
1200
1302
  }
1201
1303
 
1202
1304
  // src/components/ChangePasswordForm.tsx
1203
- var import_react14 = require("react");
1305
+ var import_react15 = require("react");
1204
1306
  var import_jsx_runtime13 = require("react/jsx-runtime");
1205
1307
  function ChangePasswordForm({
1206
1308
  onSuccess,
@@ -1208,12 +1310,12 @@ function ChangePasswordForm({
1208
1310
  minPasswordLength = 8
1209
1311
  }) {
1210
1312
  const { changePassword } = useGitHat();
1211
- const [current, setCurrent] = (0, import_react14.useState)("");
1212
- const [newPass, setNewPass] = (0, import_react14.useState)("");
1213
- const [confirm, setConfirm] = (0, import_react14.useState)("");
1214
- const [isLoading, setIsLoading] = (0, import_react14.useState)(false);
1215
- const [error, setError] = (0, import_react14.useState)("");
1216
- const [success, setSuccess] = (0, import_react14.useState)(false);
1313
+ const [current, setCurrent] = (0, import_react15.useState)("");
1314
+ const [newPass, setNewPass] = (0, import_react15.useState)("");
1315
+ const [confirm, setConfirm] = (0, import_react15.useState)("");
1316
+ const [isLoading, setIsLoading] = (0, import_react15.useState)(false);
1317
+ const [error, setError] = (0, import_react15.useState)("");
1318
+ const [success, setSuccess] = (0, import_react15.useState)(false);
1217
1319
  const handleSubmit = async (e) => {
1218
1320
  e.preventDefault();
1219
1321
  if (newPass !== confirm) {
@@ -1317,11 +1419,436 @@ function ChangePasswordForm({
1317
1419
  ] })
1318
1420
  ] });
1319
1421
  }
1422
+
1423
+ // src/components/GitHubButton.tsx
1424
+ var import_react16 = require("react");
1425
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1426
+ var GitHubIcon = () => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "M12 0C5.374 0 0 5.373 0 12c0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23A11.509 11.509 0 0112 5.803c1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576C20.566 21.797 24 17.3 24 12c0-6.627-5.373-12-12-12z" }) });
1427
+ function GitHubButton({
1428
+ children = "Continue with GitHub",
1429
+ redirectUri,
1430
+ onSuccess,
1431
+ onError,
1432
+ className = "",
1433
+ variant = "default",
1434
+ disabled = false
1435
+ }) {
1436
+ const { getGitHubOAuthUrl } = useGitHat();
1437
+ const [isLoading, setIsLoading] = (0, import_react16.useState)(false);
1438
+ const handleClick = (0, import_react16.useCallback)(async () => {
1439
+ if (isLoading || disabled) return;
1440
+ setIsLoading(true);
1441
+ try {
1442
+ const state = crypto.randomUUID();
1443
+ sessionStorage.setItem("githat_oauth_state", state);
1444
+ const { url } = await getGitHubOAuthUrl({ redirectUri, state });
1445
+ window.location.href = url;
1446
+ } catch (error) {
1447
+ setIsLoading(false);
1448
+ if (onError) {
1449
+ onError(error instanceof Error ? error : new Error("Failed to start GitHub OAuth"));
1450
+ }
1451
+ }
1452
+ }, [getGitHubOAuthUrl, redirectUri, onError, isLoading, disabled]);
1453
+ const baseStyles = "githat-github-button";
1454
+ const variantStyles = variant === "outline" ? "githat-github-button-outline" : "";
1455
+ const disabledStyles = disabled || isLoading ? "githat-github-button-disabled" : "";
1456
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
1457
+ "button",
1458
+ {
1459
+ type: "button",
1460
+ onClick: handleClick,
1461
+ disabled: disabled || isLoading,
1462
+ className: `${baseStyles} ${variantStyles} ${disabledStyles} ${className}`.trim(),
1463
+ children: [
1464
+ isLoading ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "githat-github-spinner" }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(GitHubIcon, {}),
1465
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children })
1466
+ ]
1467
+ }
1468
+ );
1469
+ }
1470
+ if (typeof document !== "undefined") {
1471
+ const styleId = "githat-github-button-styles";
1472
+ if (!document.getElementById(styleId)) {
1473
+ const style = document.createElement("style");
1474
+ style.id = styleId;
1475
+ style.textContent = `
1476
+ .githat-github-button {
1477
+ display: inline-flex;
1478
+ align-items: center;
1479
+ justify-content: center;
1480
+ gap: 0.5rem;
1481
+ padding: 0.625rem 1rem;
1482
+ font-size: 0.875rem;
1483
+ font-weight: 500;
1484
+ border-radius: 0.375rem;
1485
+ border: none;
1486
+ cursor: pointer;
1487
+ transition: all 0.15s ease;
1488
+ background-color: #24292f;
1489
+ color: #ffffff;
1490
+ width: 100%;
1491
+ }
1492
+ .githat-github-button:hover:not(:disabled) {
1493
+ background-color: #32383f;
1494
+ }
1495
+ .githat-github-button-outline {
1496
+ background-color: transparent;
1497
+ color: #24292f;
1498
+ border: 1px solid #d0d7de;
1499
+ }
1500
+ .githat-github-button-outline:hover:not(:disabled) {
1501
+ background-color: #f6f8fa;
1502
+ border-color: #24292f;
1503
+ }
1504
+ .githat-github-button-disabled {
1505
+ opacity: 0.5;
1506
+ cursor: not-allowed;
1507
+ }
1508
+ .githat-github-spinner {
1509
+ width: 1rem;
1510
+ height: 1rem;
1511
+ border: 2px solid currentColor;
1512
+ border-top-color: transparent;
1513
+ border-radius: 50%;
1514
+ animation: githat-spin 0.6s linear infinite;
1515
+ }
1516
+ @keyframes githat-spin {
1517
+ to { transform: rotate(360deg); }
1518
+ }
1519
+ `;
1520
+ document.head.appendChild(style);
1521
+ }
1522
+ }
1523
+
1524
+ // src/components/GitHubCallback.tsx
1525
+ var import_react17 = require("react");
1526
+ var import_jsx_runtime15 = require("react/jsx-runtime");
1527
+ function GitHubCallback({
1528
+ redirectUrl = "/dashboard",
1529
+ newUserRedirectUrl,
1530
+ onSuccess,
1531
+ onError,
1532
+ loadingComponent,
1533
+ errorComponent
1534
+ }) {
1535
+ const { signInWithGitHub } = useGitHat();
1536
+ const { config } = useAuth();
1537
+ const [error, setError] = (0, import_react17.useState)(null);
1538
+ const [isProcessing, setIsProcessing] = (0, import_react17.useState)(true);
1539
+ (0, import_react17.useEffect)(() => {
1540
+ const handleCallback = async () => {
1541
+ const params = new URLSearchParams(window.location.search);
1542
+ const code = params.get("code");
1543
+ const state = params.get("state");
1544
+ const errorParam = params.get("error");
1545
+ const errorDescription = params.get("error_description");
1546
+ if (errorParam) {
1547
+ const errorMsg = errorDescription || errorParam;
1548
+ setError(errorMsg);
1549
+ setIsProcessing(false);
1550
+ if (onError) {
1551
+ onError(new Error(errorMsg));
1552
+ }
1553
+ return;
1554
+ }
1555
+ if (!code) {
1556
+ const errorMsg = "No authorization code received";
1557
+ setError(errorMsg);
1558
+ setIsProcessing(false);
1559
+ if (onError) {
1560
+ onError(new Error(errorMsg));
1561
+ }
1562
+ return;
1563
+ }
1564
+ const savedState = sessionStorage.getItem("githat_oauth_state");
1565
+ if (savedState && state !== savedState) {
1566
+ const errorMsg = "Invalid state parameter";
1567
+ setError(errorMsg);
1568
+ setIsProcessing(false);
1569
+ if (onError) {
1570
+ onError(new Error(errorMsg));
1571
+ }
1572
+ return;
1573
+ }
1574
+ sessionStorage.removeItem("githat_oauth_state");
1575
+ try {
1576
+ const result = await signInWithGitHub(code);
1577
+ if (onSuccess) {
1578
+ onSuccess(result);
1579
+ }
1580
+ const targetUrl = result.isNewUser && newUserRedirectUrl ? newUserRedirectUrl : redirectUrl || config.afterSignInUrl || "/dashboard";
1581
+ window.location.href = targetUrl;
1582
+ } catch (err) {
1583
+ const errorMsg = err instanceof Error ? err.message : "Authentication failed";
1584
+ setError(errorMsg);
1585
+ setIsProcessing(false);
1586
+ if (onError) {
1587
+ onError(err instanceof Error ? err : new Error(errorMsg));
1588
+ }
1589
+ }
1590
+ };
1591
+ handleCallback();
1592
+ }, [signInWithGitHub, redirectUrl, newUserRedirectUrl, config.afterSignInUrl, onSuccess, onError]);
1593
+ if (error) {
1594
+ if (errorComponent) {
1595
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_jsx_runtime15.Fragment, { children: errorComponent(error) });
1596
+ }
1597
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "githat-callback-error", children: [
1598
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("h2", { children: "Authentication Failed" }),
1599
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { children: error }),
1600
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("a", { href: "/sign-in", children: "Back to Sign In" })
1601
+ ] });
1602
+ }
1603
+ if (loadingComponent) {
1604
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_jsx_runtime15.Fragment, { children: loadingComponent });
1605
+ }
1606
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "githat-callback-loading", children: [
1607
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "githat-callback-spinner" }),
1608
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { children: "Completing sign in with GitHub..." })
1609
+ ] });
1610
+ }
1611
+ if (typeof document !== "undefined") {
1612
+ const styleId = "githat-callback-styles";
1613
+ if (!document.getElementById(styleId)) {
1614
+ const style = document.createElement("style");
1615
+ style.id = styleId;
1616
+ style.textContent = `
1617
+ .githat-callback-loading,
1618
+ .githat-callback-error {
1619
+ display: flex;
1620
+ flex-direction: column;
1621
+ align-items: center;
1622
+ justify-content: center;
1623
+ min-height: 200px;
1624
+ padding: 2rem;
1625
+ text-align: center;
1626
+ }
1627
+ .githat-callback-spinner {
1628
+ width: 2rem;
1629
+ height: 2rem;
1630
+ border: 3px solid #e5e7eb;
1631
+ border-top-color: #3b82f6;
1632
+ border-radius: 50%;
1633
+ animation: githat-spin 0.8s linear infinite;
1634
+ margin-bottom: 1rem;
1635
+ }
1636
+ .githat-callback-error h2 {
1637
+ color: #dc2626;
1638
+ margin-bottom: 0.5rem;
1639
+ }
1640
+ .githat-callback-error p {
1641
+ color: #6b7280;
1642
+ margin-bottom: 1rem;
1643
+ }
1644
+ .githat-callback-error a {
1645
+ color: #3b82f6;
1646
+ text-decoration: underline;
1647
+ }
1648
+ @keyframes githat-spin {
1649
+ to { transform: rotate(360deg); }
1650
+ }
1651
+ `;
1652
+ document.head.appendChild(style);
1653
+ }
1654
+ }
1655
+
1656
+ // src/components/CognitoButton.tsx
1657
+ var import_react18 = require("react");
1658
+ var import_jsx_runtime16 = require("react/jsx-runtime");
1659
+ var AWSIcon = () => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { d: "M6.763 10.036c0 .296.032.535.088.71.064.176.144.368.256.576.04.063.056.127.056.183 0 .08-.048.16-.152.24l-.503.335a.383.383 0 0 1-.208.072c-.08 0-.16-.04-.239-.112a2.47 2.47 0 0 1-.287-.375 6.18 6.18 0 0 1-.248-.471c-.622.734-1.405 1.101-2.347 1.101-.67 0-1.205-.191-1.596-.574-.391-.384-.59-.894-.59-1.533 0-.678.239-1.23.726-1.644.487-.415 1.133-.623 1.955-.623.272 0 .551.024.846.064.296.04.6.104.918.176v-.583c0-.607-.127-1.03-.375-1.277-.255-.248-.686-.367-1.3-.367-.28 0-.568.031-.863.103-.295.072-.583.16-.862.272a2.287 2.287 0 0 1-.28.104.488.488 0 0 1-.127.023c-.112 0-.168-.08-.168-.247v-.391c0-.128.016-.224.056-.28a.597.597 0 0 1 .224-.167c.279-.144.614-.264 1.005-.36a4.84 4.84 0 0 1 1.246-.151c.95 0 1.644.216 2.091.647.439.43.662 1.085.662 1.963v2.586zm-3.24 1.214c.263 0 .534-.048.822-.144.287-.096.543-.271.758-.51.128-.152.224-.32.272-.512.047-.191.08-.423.08-.694v-.335a6.66 6.66 0 0 0-.735-.136 6.02 6.02 0 0 0-.75-.048c-.535 0-.926.104-1.19.32-.263.215-.39.518-.39.917 0 .375.095.655.295.846.191.2.47.296.838.296zm6.41.862c-.144 0-.24-.024-.304-.08-.064-.048-.12-.16-.168-.311L7.586 5.55a1.398 1.398 0 0 1-.072-.32c0-.128.064-.2.191-.2h.783c.151 0 .255.025.31.08.065.048.113.16.16.312l1.342 5.284 1.245-5.284c.04-.16.088-.264.151-.312a.549.549 0 0 1 .32-.08h.638c.152 0 .256.025.32.08.063.048.12.16.151.312l1.261 5.348 1.381-5.348c.048-.16.104-.264.16-.312a.52.52 0 0 1 .311-.08h.743c.127 0 .2.065.2.2 0 .04-.009.08-.017.128a1.137 1.137 0 0 1-.056.2l-1.923 6.17c-.048.16-.104.264-.168.312a.51.51 0 0 1-.303.08h-.687c-.151 0-.255-.024-.32-.08-.063-.056-.119-.16-.15-.32l-1.238-5.148-1.23 5.14c-.04.16-.087.264-.15.32-.065.056-.177.08-.32.08zm10.256.215c-.415 0-.83-.048-1.229-.143-.399-.096-.71-.2-.918-.32-.128-.071-.215-.151-.247-.223a.563.563 0 0 1-.048-.224v-.407c0-.167.064-.247.183-.247.048 0 .096.008.144.024.048.016.12.048.2.08.271.12.566.215.878.279.319.064.63.096.95.096.502 0 .894-.088 1.165-.264a.86.86 0 0 0 .415-.758.777.777 0 0 0-.215-.559c-.144-.151-.415-.287-.806-.415l-1.157-.36c-.583-.183-1.014-.454-1.277-.813a1.902 1.902 0 0 1-.4-1.158c0-.335.073-.63.216-.886.144-.255.336-.479.575-.654.24-.184.51-.32.83-.415.32-.096.655-.136 1.006-.136.176 0 .359.008.535.032.183.024.35.056.518.088.16.04.312.08.455.127.144.048.256.096.336.144a.69.69 0 0 1 .24.2.43.43 0 0 1 .071.263v.375c0 .168-.064.256-.184.256a.83.83 0 0 1-.303-.096 3.652 3.652 0 0 0-1.532-.311c-.455 0-.815.071-1.062.223-.248.152-.375.383-.375.71 0 .224.08.416.24.567.159.152.454.304.877.44l1.134.358c.574.184.99.44 1.237.767.247.327.367.702.367 1.117 0 .343-.072.655-.207.926-.144.272-.336.511-.583.703-.248.2-.543.343-.886.447-.36.111-.734.167-1.142.167z" }) });
1660
+ function CognitoButton({
1661
+ children = "Continue with AWS",
1662
+ redirectUri,
1663
+ identityProvider,
1664
+ onError,
1665
+ className = "",
1666
+ variant = "default",
1667
+ disabled = false
1668
+ }) {
1669
+ const { getCognitoOAuthUrl } = useGitHat();
1670
+ const [isLoading, setIsLoading] = (0, import_react18.useState)(false);
1671
+ const handleClick = (0, import_react18.useCallback)(async () => {
1672
+ if (isLoading || disabled) return;
1673
+ setIsLoading(true);
1674
+ try {
1675
+ const state = crypto.randomUUID();
1676
+ sessionStorage.setItem("githat_cognito_oauth_state", state);
1677
+ const { url } = await getCognitoOAuthUrl({ redirectUri, state, identityProvider });
1678
+ window.location.href = url;
1679
+ } catch (error) {
1680
+ setIsLoading(false);
1681
+ if (onError) {
1682
+ onError(error instanceof Error ? error : new Error("Failed to start Cognito OAuth"));
1683
+ }
1684
+ }
1685
+ }, [getCognitoOAuthUrl, redirectUri, identityProvider, onError, isLoading, disabled]);
1686
+ const baseStyles = "githat-cognito-button";
1687
+ const variantStyles = variant === "outline" ? "githat-cognito-button-outline" : "";
1688
+ const disabledStyles = disabled || isLoading ? "githat-cognito-button-disabled" : "";
1689
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
1690
+ "button",
1691
+ {
1692
+ type: "button",
1693
+ onClick: handleClick,
1694
+ disabled: disabled || isLoading,
1695
+ className: `${baseStyles} ${variantStyles} ${disabledStyles} ${className}`.trim(),
1696
+ children: [
1697
+ isLoading ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "githat-cognito-spinner" }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(AWSIcon, {}),
1698
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { children })
1699
+ ]
1700
+ }
1701
+ );
1702
+ }
1703
+ if (typeof document !== "undefined") {
1704
+ const styleId = "githat-cognito-button-styles";
1705
+ if (!document.getElementById(styleId)) {
1706
+ const style = document.createElement("style");
1707
+ style.id = styleId;
1708
+ style.textContent = `
1709
+ .githat-cognito-button {
1710
+ display: inline-flex;
1711
+ align-items: center;
1712
+ justify-content: center;
1713
+ gap: 0.5rem;
1714
+ padding: 0.625rem 1rem;
1715
+ font-size: 0.875rem;
1716
+ font-weight: 500;
1717
+ border-radius: 0.375rem;
1718
+ border: none;
1719
+ cursor: pointer;
1720
+ transition: all 0.15s ease;
1721
+ background-color: #ff9900;
1722
+ color: #232f3e;
1723
+ width: 100%;
1724
+ }
1725
+ .githat-cognito-button:hover:not(:disabled) {
1726
+ background-color: #ec7211;
1727
+ }
1728
+ .githat-cognito-button-outline {
1729
+ background-color: transparent;
1730
+ color: #ff9900;
1731
+ border: 1px solid #ff9900;
1732
+ }
1733
+ .githat-cognito-button-outline:hover:not(:disabled) {
1734
+ background-color: rgba(255, 153, 0, 0.1);
1735
+ }
1736
+ .githat-cognito-button-disabled {
1737
+ opacity: 0.5;
1738
+ cursor: not-allowed;
1739
+ }
1740
+ .githat-cognito-spinner {
1741
+ width: 1rem;
1742
+ height: 1rem;
1743
+ border: 2px solid currentColor;
1744
+ border-top-color: transparent;
1745
+ border-radius: 50%;
1746
+ animation: githat-cognito-spin 0.6s linear infinite;
1747
+ }
1748
+ @keyframes githat-cognito-spin {
1749
+ to { transform: rotate(360deg); }
1750
+ }
1751
+ `;
1752
+ document.head.appendChild(style);
1753
+ }
1754
+ }
1755
+
1756
+ // src/components/CognitoCallback.tsx
1757
+ var import_react19 = require("react");
1758
+ var import_jsx_runtime17 = require("react/jsx-runtime");
1759
+ function CognitoCallback({
1760
+ redirectUrl = "/dashboard",
1761
+ newUserRedirectUrl,
1762
+ onSuccess,
1763
+ onError,
1764
+ loadingComponent,
1765
+ errorComponent
1766
+ }) {
1767
+ const { signInWithCognito } = useGitHat();
1768
+ const { config } = useAuth();
1769
+ const [error, setError] = (0, import_react19.useState)(null);
1770
+ const [isProcessing, setIsProcessing] = (0, import_react19.useState)(true);
1771
+ (0, import_react19.useEffect)(() => {
1772
+ const handleCallback = async () => {
1773
+ const params = new URLSearchParams(window.location.search);
1774
+ const code = params.get("code");
1775
+ const state = params.get("state");
1776
+ const errorParam = params.get("error");
1777
+ const errorDescription = params.get("error_description");
1778
+ if (errorParam) {
1779
+ const errorMsg = errorDescription || errorParam;
1780
+ setError(errorMsg);
1781
+ setIsProcessing(false);
1782
+ if (onError) {
1783
+ onError(new Error(errorMsg));
1784
+ }
1785
+ return;
1786
+ }
1787
+ if (!code) {
1788
+ const errorMsg = "No authorization code received";
1789
+ setError(errorMsg);
1790
+ setIsProcessing(false);
1791
+ if (onError) {
1792
+ onError(new Error(errorMsg));
1793
+ }
1794
+ return;
1795
+ }
1796
+ const savedState = sessionStorage.getItem("githat_cognito_oauth_state");
1797
+ if (savedState && state !== savedState) {
1798
+ const errorMsg = "Invalid state parameter";
1799
+ setError(errorMsg);
1800
+ setIsProcessing(false);
1801
+ if (onError) {
1802
+ onError(new Error(errorMsg));
1803
+ }
1804
+ return;
1805
+ }
1806
+ sessionStorage.removeItem("githat_cognito_oauth_state");
1807
+ try {
1808
+ const result = await signInWithCognito(code);
1809
+ if (onSuccess) {
1810
+ onSuccess(result);
1811
+ }
1812
+ const targetUrl = result.isNewUser && newUserRedirectUrl ? newUserRedirectUrl : redirectUrl || config.afterSignInUrl || "/dashboard";
1813
+ window.location.href = targetUrl;
1814
+ } catch (err) {
1815
+ const errorMsg = err instanceof Error ? err.message : "Authentication failed";
1816
+ setError(errorMsg);
1817
+ setIsProcessing(false);
1818
+ if (onError) {
1819
+ onError(err instanceof Error ? err : new Error(errorMsg));
1820
+ }
1821
+ }
1822
+ };
1823
+ handleCallback();
1824
+ }, [signInWithCognito, redirectUrl, newUserRedirectUrl, config.afterSignInUrl, onSuccess, onError]);
1825
+ if (error) {
1826
+ if (errorComponent) {
1827
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_jsx_runtime17.Fragment, { children: errorComponent(error) });
1828
+ }
1829
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "githat-callback-error", children: [
1830
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("h2", { children: "Authentication Failed" }),
1831
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { children: error }),
1832
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("a", { href: "/sign-in", children: "Back to Sign In" })
1833
+ ] });
1834
+ }
1835
+ if (loadingComponent) {
1836
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_jsx_runtime17.Fragment, { children: loadingComponent });
1837
+ }
1838
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "githat-callback-loading", children: [
1839
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "githat-callback-spinner" }),
1840
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { children: "Completing sign in with AWS Cognito..." })
1841
+ ] });
1842
+ }
1320
1843
  // Annotate the CommonJS export names for ESM import in node:
1321
1844
  0 && (module.exports = {
1322
1845
  ChangePasswordForm,
1846
+ CognitoButton,
1847
+ CognitoCallback,
1323
1848
  ForgotPasswordForm,
1324
1849
  GitHatProvider,
1850
+ GitHubButton,
1851
+ GitHubCallback,
1325
1852
  OrgSwitcher,
1326
1853
  ProtectedRoute,
1327
1854
  ResetPasswordForm,
@@ -1334,6 +1861,7 @@ function ChangePasswordForm({
1334
1861
  VerifyEmailStatus,
1335
1862
  useAuth,
1336
1863
  useData,
1864
+ useEmail,
1337
1865
  useGitHat
1338
1866
  });
1339
1867
  //# sourceMappingURL=index.js.map