@githat/nextjs 0.2.4 → 0.2.6

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.mjs CHANGED
@@ -384,33 +384,23 @@ function useGitHat() {
384
384
  );
385
385
  const forgotPassword = useCallback2(
386
386
  async (email) => {
387
- const response = await fetch(`${ctx.config.apiUrl}/auth/forgot-password`, {
387
+ await client.fetchApi("/auth/forgot-password", {
388
388
  method: "POST",
389
- headers: { "Content-Type": "application/json" },
390
389
  body: JSON.stringify({ email })
391
390
  });
392
- if (!response.ok) {
393
- const error = await response.json().catch(() => ({}));
394
- throw new Error(error.message || "Failed to send reset email");
395
- }
396
391
  return { success: true };
397
392
  },
398
- [ctx.config.apiUrl]
393
+ [client]
399
394
  );
400
395
  const resetPassword = useCallback2(
401
396
  async (token, newPassword) => {
402
- const response = await fetch(`${ctx.config.apiUrl}/auth/reset-password`, {
397
+ await client.fetchApi("/auth/reset-password", {
403
398
  method: "POST",
404
- headers: { "Content-Type": "application/json" },
405
399
  body: JSON.stringify({ token, password: newPassword })
406
400
  });
407
- if (!response.ok) {
408
- const error = await response.json().catch(() => ({}));
409
- throw new Error(error.message || "Failed to reset password");
410
- }
411
401
  return { success: true };
412
402
  },
413
- [ctx.config.apiUrl]
403
+ [client]
414
404
  );
415
405
  const changePassword = useCallback2(
416
406
  async (currentPassword, newPassword) => {
@@ -424,33 +414,90 @@ function useGitHat() {
424
414
  );
425
415
  const verifyEmail = useCallback2(
426
416
  async (token) => {
427
- const response = await fetch(`${ctx.config.apiUrl}/auth/verify-email`, {
417
+ await client.fetchApi("/auth/verify-email", {
428
418
  method: "POST",
429
- headers: { "Content-Type": "application/json" },
430
419
  body: JSON.stringify({ token })
431
420
  });
432
- if (!response.ok) {
433
- const error = await response.json().catch(() => ({}));
434
- throw new Error(error.message || "Failed to verify email");
435
- }
436
421
  return { success: true };
437
422
  },
438
- [ctx.config.apiUrl]
423
+ [client]
439
424
  );
440
425
  const resendVerificationEmail = useCallback2(
441
426
  async (email) => {
442
- const response = await fetch(`${ctx.config.apiUrl}/auth/resend-verification`, {
427
+ await client.fetchApi("/auth/resend-verification", {
443
428
  method: "POST",
444
- headers: { "Content-Type": "application/json" },
445
429
  body: JSON.stringify({ email })
446
430
  });
447
- if (!response.ok) {
448
- const error = await response.json().catch(() => ({}));
449
- throw new Error(error.message || "Failed to resend verification email");
450
- }
451
431
  return { success: true };
452
432
  },
453
- [ctx.config.apiUrl]
433
+ [client]
434
+ );
435
+ const getGitHubOAuthUrl = useCallback2(
436
+ async (options) => {
437
+ const params = new URLSearchParams();
438
+ if (options?.redirectUri) params.append("redirectUri", options.redirectUri);
439
+ if (options?.state) params.append("state", options.state);
440
+ const queryString = params.toString();
441
+ const path = queryString ? `/auth/oauth/github/url?${queryString}` : "/auth/oauth/github/url";
442
+ return client.fetchApi(path);
443
+ },
444
+ [client]
445
+ );
446
+ const signInWithGitHub = useCallback2(
447
+ async (code, options) => {
448
+ const response = await client.fetchApi("/auth/oauth/github", {
449
+ method: "POST",
450
+ body: JSON.stringify({
451
+ code,
452
+ redirectUri: options?.redirectUri
453
+ })
454
+ });
455
+ if (response.accessToken) {
456
+ window.dispatchEvent(new CustomEvent("githat:auth-changed", {
457
+ detail: { user: response.user, org: response.org, signedIn: true }
458
+ }));
459
+ }
460
+ return {
461
+ user: response.user,
462
+ org: response.org,
463
+ isNewUser: response.isNewUser
464
+ };
465
+ },
466
+ [client]
467
+ );
468
+ const getCognitoOAuthUrl = useCallback2(
469
+ async (options) => {
470
+ const params = new URLSearchParams();
471
+ if (options?.redirectUri) params.append("redirectUri", options.redirectUri);
472
+ if (options?.state) params.append("state", options.state);
473
+ if (options?.identityProvider) params.append("identityProvider", options.identityProvider);
474
+ const queryString = params.toString();
475
+ const path = queryString ? `/auth/oauth/cognito/url?${queryString}` : "/auth/oauth/cognito/url";
476
+ return client.fetchApi(path);
477
+ },
478
+ [client]
479
+ );
480
+ const signInWithCognito = useCallback2(
481
+ async (code, options) => {
482
+ const response = await client.fetchApi("/auth/oauth/cognito", {
483
+ method: "POST",
484
+ body: JSON.stringify({
485
+ code,
486
+ redirectUri: options?.redirectUri
487
+ })
488
+ });
489
+ if (response.accessToken) {
490
+ window.dispatchEvent(new CustomEvent("githat:auth-changed", {
491
+ detail: { user: response.user, org: response.org, signedIn: true }
492
+ }));
493
+ }
494
+ return {
495
+ user: response.user,
496
+ org: response.org,
497
+ isNewUser: response.isNewUser
498
+ };
499
+ },
500
+ [client]
454
501
  );
455
502
  return {
456
503
  fetch: client.fetchApi,
@@ -465,7 +512,12 @@ function useGitHat() {
465
512
  changePassword,
466
513
  // Email verification
467
514
  verifyEmail,
468
- resendVerificationEmail
515
+ resendVerificationEmail,
516
+ // OAuth (Web2)
517
+ getGitHubOAuthUrl,
518
+ signInWithGitHub,
519
+ getCognitoOAuthUrl,
520
+ signInWithCognito
469
521
  };
470
522
  }
471
523
 
@@ -574,7 +626,7 @@ function SignInForm({ onSuccess, signUpUrl, forgotPasswordUrl }) {
574
626
  window.location.href = params.get("redirect_url") || config.afterSignInUrl;
575
627
  }
576
628
  } catch (err) {
577
- setError(err.message || "Sign in failed");
629
+ setError(err instanceof Error ? err.message : "Sign in failed");
578
630
  } finally {
579
631
  setLoading(false);
580
632
  }
@@ -672,7 +724,7 @@ function SignUpForm({ onSuccess, signInUrl }) {
672
724
  window.location.href = config.afterSignInUrl;
673
725
  }
674
726
  } catch (err) {
675
- setError(err.message || "Sign up failed");
727
+ setError(err instanceof Error ? err.message : "Sign up failed");
676
728
  } finally {
677
729
  setLoading(false);
678
730
  }
@@ -1297,10 +1349,435 @@ function ChangePasswordForm({
1297
1349
  ] })
1298
1350
  ] });
1299
1351
  }
1352
+
1353
+ // src/components/GitHubButton.tsx
1354
+ import { useState as useState11, useCallback as useCallback3 } from "react";
1355
+ import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
1356
+ var GitHubIcon = () => /* @__PURE__ */ jsx13("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsx13("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" }) });
1357
+ function GitHubButton({
1358
+ children = "Continue with GitHub",
1359
+ redirectUri,
1360
+ onSuccess,
1361
+ onError,
1362
+ className = "",
1363
+ variant = "default",
1364
+ disabled = false
1365
+ }) {
1366
+ const { getGitHubOAuthUrl } = useGitHat();
1367
+ const [isLoading, setIsLoading] = useState11(false);
1368
+ const handleClick = useCallback3(async () => {
1369
+ if (isLoading || disabled) return;
1370
+ setIsLoading(true);
1371
+ try {
1372
+ const state = crypto.randomUUID();
1373
+ sessionStorage.setItem("githat_oauth_state", state);
1374
+ const { url } = await getGitHubOAuthUrl({ redirectUri, state });
1375
+ window.location.href = url;
1376
+ } catch (error) {
1377
+ setIsLoading(false);
1378
+ if (onError) {
1379
+ onError(error instanceof Error ? error : new Error("Failed to start GitHub OAuth"));
1380
+ }
1381
+ }
1382
+ }, [getGitHubOAuthUrl, redirectUri, onError, isLoading, disabled]);
1383
+ const baseStyles = "githat-github-button";
1384
+ const variantStyles = variant === "outline" ? "githat-github-button-outline" : "";
1385
+ const disabledStyles = disabled || isLoading ? "githat-github-button-disabled" : "";
1386
+ return /* @__PURE__ */ jsxs11(
1387
+ "button",
1388
+ {
1389
+ type: "button",
1390
+ onClick: handleClick,
1391
+ disabled: disabled || isLoading,
1392
+ className: `${baseStyles} ${variantStyles} ${disabledStyles} ${className}`.trim(),
1393
+ children: [
1394
+ isLoading ? /* @__PURE__ */ jsx13("span", { className: "githat-github-spinner" }) : /* @__PURE__ */ jsx13(GitHubIcon, {}),
1395
+ /* @__PURE__ */ jsx13("span", { children })
1396
+ ]
1397
+ }
1398
+ );
1399
+ }
1400
+ if (typeof document !== "undefined") {
1401
+ const styleId = "githat-github-button-styles";
1402
+ if (!document.getElementById(styleId)) {
1403
+ const style = document.createElement("style");
1404
+ style.id = styleId;
1405
+ style.textContent = `
1406
+ .githat-github-button {
1407
+ display: inline-flex;
1408
+ align-items: center;
1409
+ justify-content: center;
1410
+ gap: 0.5rem;
1411
+ padding: 0.625rem 1rem;
1412
+ font-size: 0.875rem;
1413
+ font-weight: 500;
1414
+ border-radius: 0.375rem;
1415
+ border: none;
1416
+ cursor: pointer;
1417
+ transition: all 0.15s ease;
1418
+ background-color: #24292f;
1419
+ color: #ffffff;
1420
+ width: 100%;
1421
+ }
1422
+ .githat-github-button:hover:not(:disabled) {
1423
+ background-color: #32383f;
1424
+ }
1425
+ .githat-github-button-outline {
1426
+ background-color: transparent;
1427
+ color: #24292f;
1428
+ border: 1px solid #d0d7de;
1429
+ }
1430
+ .githat-github-button-outline:hover:not(:disabled) {
1431
+ background-color: #f6f8fa;
1432
+ border-color: #24292f;
1433
+ }
1434
+ .githat-github-button-disabled {
1435
+ opacity: 0.5;
1436
+ cursor: not-allowed;
1437
+ }
1438
+ .githat-github-spinner {
1439
+ width: 1rem;
1440
+ height: 1rem;
1441
+ border: 2px solid currentColor;
1442
+ border-top-color: transparent;
1443
+ border-radius: 50%;
1444
+ animation: githat-spin 0.6s linear infinite;
1445
+ }
1446
+ @keyframes githat-spin {
1447
+ to { transform: rotate(360deg); }
1448
+ }
1449
+ `;
1450
+ document.head.appendChild(style);
1451
+ }
1452
+ }
1453
+
1454
+ // src/components/GitHubCallback.tsx
1455
+ import { useEffect as useEffect6, useState as useState12 } from "react";
1456
+ import { Fragment as Fragment3, jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
1457
+ function GitHubCallback({
1458
+ redirectUrl = "/dashboard",
1459
+ newUserRedirectUrl,
1460
+ onSuccess,
1461
+ onError,
1462
+ loadingComponent,
1463
+ errorComponent
1464
+ }) {
1465
+ const { signInWithGitHub } = useGitHat();
1466
+ const { config } = useAuth();
1467
+ const [error, setError] = useState12(null);
1468
+ const [isProcessing, setIsProcessing] = useState12(true);
1469
+ useEffect6(() => {
1470
+ const handleCallback = async () => {
1471
+ const params = new URLSearchParams(window.location.search);
1472
+ const code = params.get("code");
1473
+ const state = params.get("state");
1474
+ const errorParam = params.get("error");
1475
+ const errorDescription = params.get("error_description");
1476
+ if (errorParam) {
1477
+ const errorMsg = errorDescription || errorParam;
1478
+ setError(errorMsg);
1479
+ setIsProcessing(false);
1480
+ if (onError) {
1481
+ onError(new Error(errorMsg));
1482
+ }
1483
+ return;
1484
+ }
1485
+ if (!code) {
1486
+ const errorMsg = "No authorization code received";
1487
+ setError(errorMsg);
1488
+ setIsProcessing(false);
1489
+ if (onError) {
1490
+ onError(new Error(errorMsg));
1491
+ }
1492
+ return;
1493
+ }
1494
+ const savedState = sessionStorage.getItem("githat_oauth_state");
1495
+ if (savedState && state !== savedState) {
1496
+ const errorMsg = "Invalid state parameter";
1497
+ setError(errorMsg);
1498
+ setIsProcessing(false);
1499
+ if (onError) {
1500
+ onError(new Error(errorMsg));
1501
+ }
1502
+ return;
1503
+ }
1504
+ sessionStorage.removeItem("githat_oauth_state");
1505
+ try {
1506
+ const result = await signInWithGitHub(code);
1507
+ if (onSuccess) {
1508
+ onSuccess(result);
1509
+ }
1510
+ const targetUrl = result.isNewUser && newUserRedirectUrl ? newUserRedirectUrl : redirectUrl || config.afterSignInUrl || "/dashboard";
1511
+ window.location.href = targetUrl;
1512
+ } catch (err) {
1513
+ const errorMsg = err instanceof Error ? err.message : "Authentication failed";
1514
+ setError(errorMsg);
1515
+ setIsProcessing(false);
1516
+ if (onError) {
1517
+ onError(err instanceof Error ? err : new Error(errorMsg));
1518
+ }
1519
+ }
1520
+ };
1521
+ handleCallback();
1522
+ }, [signInWithGitHub, redirectUrl, newUserRedirectUrl, config.afterSignInUrl, onSuccess, onError]);
1523
+ if (error) {
1524
+ if (errorComponent) {
1525
+ return /* @__PURE__ */ jsx14(Fragment3, { children: errorComponent(error) });
1526
+ }
1527
+ return /* @__PURE__ */ jsxs12("div", { className: "githat-callback-error", children: [
1528
+ /* @__PURE__ */ jsx14("h2", { children: "Authentication Failed" }),
1529
+ /* @__PURE__ */ jsx14("p", { children: error }),
1530
+ /* @__PURE__ */ jsx14("a", { href: "/sign-in", children: "Back to Sign In" })
1531
+ ] });
1532
+ }
1533
+ if (loadingComponent) {
1534
+ return /* @__PURE__ */ jsx14(Fragment3, { children: loadingComponent });
1535
+ }
1536
+ return /* @__PURE__ */ jsxs12("div", { className: "githat-callback-loading", children: [
1537
+ /* @__PURE__ */ jsx14("div", { className: "githat-callback-spinner" }),
1538
+ /* @__PURE__ */ jsx14("p", { children: "Completing sign in with GitHub..." })
1539
+ ] });
1540
+ }
1541
+ if (typeof document !== "undefined") {
1542
+ const styleId = "githat-callback-styles";
1543
+ if (!document.getElementById(styleId)) {
1544
+ const style = document.createElement("style");
1545
+ style.id = styleId;
1546
+ style.textContent = `
1547
+ .githat-callback-loading,
1548
+ .githat-callback-error {
1549
+ display: flex;
1550
+ flex-direction: column;
1551
+ align-items: center;
1552
+ justify-content: center;
1553
+ min-height: 200px;
1554
+ padding: 2rem;
1555
+ text-align: center;
1556
+ }
1557
+ .githat-callback-spinner {
1558
+ width: 2rem;
1559
+ height: 2rem;
1560
+ border: 3px solid #e5e7eb;
1561
+ border-top-color: #3b82f6;
1562
+ border-radius: 50%;
1563
+ animation: githat-spin 0.8s linear infinite;
1564
+ margin-bottom: 1rem;
1565
+ }
1566
+ .githat-callback-error h2 {
1567
+ color: #dc2626;
1568
+ margin-bottom: 0.5rem;
1569
+ }
1570
+ .githat-callback-error p {
1571
+ color: #6b7280;
1572
+ margin-bottom: 1rem;
1573
+ }
1574
+ .githat-callback-error a {
1575
+ color: #3b82f6;
1576
+ text-decoration: underline;
1577
+ }
1578
+ @keyframes githat-spin {
1579
+ to { transform: rotate(360deg); }
1580
+ }
1581
+ `;
1582
+ document.head.appendChild(style);
1583
+ }
1584
+ }
1585
+
1586
+ // src/components/CognitoButton.tsx
1587
+ import { useState as useState13, useCallback as useCallback4 } from "react";
1588
+ import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
1589
+ var AWSIcon = () => /* @__PURE__ */ jsx15("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsx15("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" }) });
1590
+ function CognitoButton({
1591
+ children = "Continue with AWS",
1592
+ redirectUri,
1593
+ identityProvider,
1594
+ onError,
1595
+ className = "",
1596
+ variant = "default",
1597
+ disabled = false
1598
+ }) {
1599
+ const { getCognitoOAuthUrl } = useGitHat();
1600
+ const [isLoading, setIsLoading] = useState13(false);
1601
+ const handleClick = useCallback4(async () => {
1602
+ if (isLoading || disabled) return;
1603
+ setIsLoading(true);
1604
+ try {
1605
+ const state = crypto.randomUUID();
1606
+ sessionStorage.setItem("githat_cognito_oauth_state", state);
1607
+ const { url } = await getCognitoOAuthUrl({ redirectUri, state, identityProvider });
1608
+ window.location.href = url;
1609
+ } catch (error) {
1610
+ setIsLoading(false);
1611
+ if (onError) {
1612
+ onError(error instanceof Error ? error : new Error("Failed to start Cognito OAuth"));
1613
+ }
1614
+ }
1615
+ }, [getCognitoOAuthUrl, redirectUri, identityProvider, onError, isLoading, disabled]);
1616
+ const baseStyles = "githat-cognito-button";
1617
+ const variantStyles = variant === "outline" ? "githat-cognito-button-outline" : "";
1618
+ const disabledStyles = disabled || isLoading ? "githat-cognito-button-disabled" : "";
1619
+ return /* @__PURE__ */ jsxs13(
1620
+ "button",
1621
+ {
1622
+ type: "button",
1623
+ onClick: handleClick,
1624
+ disabled: disabled || isLoading,
1625
+ className: `${baseStyles} ${variantStyles} ${disabledStyles} ${className}`.trim(),
1626
+ children: [
1627
+ isLoading ? /* @__PURE__ */ jsx15("span", { className: "githat-cognito-spinner" }) : /* @__PURE__ */ jsx15(AWSIcon, {}),
1628
+ /* @__PURE__ */ jsx15("span", { children })
1629
+ ]
1630
+ }
1631
+ );
1632
+ }
1633
+ if (typeof document !== "undefined") {
1634
+ const styleId = "githat-cognito-button-styles";
1635
+ if (!document.getElementById(styleId)) {
1636
+ const style = document.createElement("style");
1637
+ style.id = styleId;
1638
+ style.textContent = `
1639
+ .githat-cognito-button {
1640
+ display: inline-flex;
1641
+ align-items: center;
1642
+ justify-content: center;
1643
+ gap: 0.5rem;
1644
+ padding: 0.625rem 1rem;
1645
+ font-size: 0.875rem;
1646
+ font-weight: 500;
1647
+ border-radius: 0.375rem;
1648
+ border: none;
1649
+ cursor: pointer;
1650
+ transition: all 0.15s ease;
1651
+ background-color: #ff9900;
1652
+ color: #232f3e;
1653
+ width: 100%;
1654
+ }
1655
+ .githat-cognito-button:hover:not(:disabled) {
1656
+ background-color: #ec7211;
1657
+ }
1658
+ .githat-cognito-button-outline {
1659
+ background-color: transparent;
1660
+ color: #ff9900;
1661
+ border: 1px solid #ff9900;
1662
+ }
1663
+ .githat-cognito-button-outline:hover:not(:disabled) {
1664
+ background-color: rgba(255, 153, 0, 0.1);
1665
+ }
1666
+ .githat-cognito-button-disabled {
1667
+ opacity: 0.5;
1668
+ cursor: not-allowed;
1669
+ }
1670
+ .githat-cognito-spinner {
1671
+ width: 1rem;
1672
+ height: 1rem;
1673
+ border: 2px solid currentColor;
1674
+ border-top-color: transparent;
1675
+ border-radius: 50%;
1676
+ animation: githat-cognito-spin 0.6s linear infinite;
1677
+ }
1678
+ @keyframes githat-cognito-spin {
1679
+ to { transform: rotate(360deg); }
1680
+ }
1681
+ `;
1682
+ document.head.appendChild(style);
1683
+ }
1684
+ }
1685
+
1686
+ // src/components/CognitoCallback.tsx
1687
+ import { useEffect as useEffect7, useState as useState14 } from "react";
1688
+ import { Fragment as Fragment4, jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
1689
+ function CognitoCallback({
1690
+ redirectUrl = "/dashboard",
1691
+ newUserRedirectUrl,
1692
+ onSuccess,
1693
+ onError,
1694
+ loadingComponent,
1695
+ errorComponent
1696
+ }) {
1697
+ const { signInWithCognito } = useGitHat();
1698
+ const { config } = useAuth();
1699
+ const [error, setError] = useState14(null);
1700
+ const [isProcessing, setIsProcessing] = useState14(true);
1701
+ useEffect7(() => {
1702
+ const handleCallback = async () => {
1703
+ const params = new URLSearchParams(window.location.search);
1704
+ const code = params.get("code");
1705
+ const state = params.get("state");
1706
+ const errorParam = params.get("error");
1707
+ const errorDescription = params.get("error_description");
1708
+ if (errorParam) {
1709
+ const errorMsg = errorDescription || errorParam;
1710
+ setError(errorMsg);
1711
+ setIsProcessing(false);
1712
+ if (onError) {
1713
+ onError(new Error(errorMsg));
1714
+ }
1715
+ return;
1716
+ }
1717
+ if (!code) {
1718
+ const errorMsg = "No authorization code received";
1719
+ setError(errorMsg);
1720
+ setIsProcessing(false);
1721
+ if (onError) {
1722
+ onError(new Error(errorMsg));
1723
+ }
1724
+ return;
1725
+ }
1726
+ const savedState = sessionStorage.getItem("githat_cognito_oauth_state");
1727
+ if (savedState && state !== savedState) {
1728
+ const errorMsg = "Invalid state parameter";
1729
+ setError(errorMsg);
1730
+ setIsProcessing(false);
1731
+ if (onError) {
1732
+ onError(new Error(errorMsg));
1733
+ }
1734
+ return;
1735
+ }
1736
+ sessionStorage.removeItem("githat_cognito_oauth_state");
1737
+ try {
1738
+ const result = await signInWithCognito(code);
1739
+ if (onSuccess) {
1740
+ onSuccess(result);
1741
+ }
1742
+ const targetUrl = result.isNewUser && newUserRedirectUrl ? newUserRedirectUrl : redirectUrl || config.afterSignInUrl || "/dashboard";
1743
+ window.location.href = targetUrl;
1744
+ } catch (err) {
1745
+ const errorMsg = err instanceof Error ? err.message : "Authentication failed";
1746
+ setError(errorMsg);
1747
+ setIsProcessing(false);
1748
+ if (onError) {
1749
+ onError(err instanceof Error ? err : new Error(errorMsg));
1750
+ }
1751
+ }
1752
+ };
1753
+ handleCallback();
1754
+ }, [signInWithCognito, redirectUrl, newUserRedirectUrl, config.afterSignInUrl, onSuccess, onError]);
1755
+ if (error) {
1756
+ if (errorComponent) {
1757
+ return /* @__PURE__ */ jsx16(Fragment4, { children: errorComponent(error) });
1758
+ }
1759
+ return /* @__PURE__ */ jsxs14("div", { className: "githat-callback-error", children: [
1760
+ /* @__PURE__ */ jsx16("h2", { children: "Authentication Failed" }),
1761
+ /* @__PURE__ */ jsx16("p", { children: error }),
1762
+ /* @__PURE__ */ jsx16("a", { href: "/sign-in", children: "Back to Sign In" })
1763
+ ] });
1764
+ }
1765
+ if (loadingComponent) {
1766
+ return /* @__PURE__ */ jsx16(Fragment4, { children: loadingComponent });
1767
+ }
1768
+ return /* @__PURE__ */ jsxs14("div", { className: "githat-callback-loading", children: [
1769
+ /* @__PURE__ */ jsx16("div", { className: "githat-callback-spinner" }),
1770
+ /* @__PURE__ */ jsx16("p", { children: "Completing sign in with AWS Cognito..." })
1771
+ ] });
1772
+ }
1300
1773
  export {
1301
1774
  ChangePasswordForm,
1775
+ CognitoButton,
1776
+ CognitoCallback,
1302
1777
  ForgotPasswordForm,
1303
1778
  GitHatProvider,
1779
+ GitHubButton,
1780
+ GitHubCallback,
1304
1781
  OrgSwitcher,
1305
1782
  ProtectedRoute,
1306
1783
  ResetPasswordForm,