@sylergydigital/issue-pin-sdk 0.6.5 → 0.6.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/CHANGELOG.md CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
3
  All notable changes to `@sylergydigital/issue-pin-sdk` are documented here.
4
4
 
5
+ ## [0.6.6] - 2026-04-15
6
+
7
+ ### Fixed
8
+ - **SSO handoff for federated pin click-through** — clicking a pin on a 3rd-party app now auto-logs the user into the IssuePin dashboard via `external-sso-launch` magic link, instead of landing on the login page. Falls back to direct link when not in a federated context.
9
+
5
10
  ## [0.6.5] - 2026-04-15
6
11
 
7
12
  ### Added
package/dist/index.cjs CHANGED
@@ -487,6 +487,34 @@ function FeedbackProvider({
487
487
  const onModeChangeUnified = config.onModeChange ?? (config.onFeedbackActiveChange ? ((m) => config.onFeedbackActiveChange(m === "annotate")) : void 0);
488
488
  const controlledModeFromProps = config.mode !== void 0 ? config.mode : config.feedbackActive !== void 0 ? config.feedbackActive ? "annotate" : "view" : void 0;
489
489
  const initialModeUncontrolled = config.mode ?? (config.feedbackActive !== void 0 ? config.feedbackActive ? "annotate" : "view" : "view");
490
+ const openThreadInDashboard = (0, import_react2.useCallback)((threadId) => {
491
+ const threadPath = `/threads/${threadId}`;
492
+ const baseUrl = resolved.siteUrl?.replace(/\/+$/, "") || window.location.origin;
493
+ if (config.apiKey && autoIdentity.accessToken) {
494
+ const functionsBaseUrl = getFunctionsBaseUrl(resolved.supabaseUrl);
495
+ fetch(`${functionsBaseUrl}/external-sso-launch`, {
496
+ method: "POST",
497
+ headers: {
498
+ "Content-Type": "application/json",
499
+ Authorization: `Bearer ${autoIdentity.accessToken}`
500
+ },
501
+ body: JSON.stringify({
502
+ apiKey: config.apiKey,
503
+ nextPath: threadPath
504
+ })
505
+ }).then((res) => res.ok ? res.json() : null).then((data) => {
506
+ if (data?.redirect_url) {
507
+ window.open(data.redirect_url, "_blank", "noopener,noreferrer");
508
+ } else {
509
+ window.open(`${baseUrl}${threadPath}`, "_blank", "noopener,noreferrer");
510
+ }
511
+ }).catch(() => {
512
+ window.open(`${baseUrl}${threadPath}`, "_blank", "noopener,noreferrer");
513
+ });
514
+ return;
515
+ }
516
+ window.open(`${baseUrl}${threadPath}`, "_blank", "noopener,noreferrer");
517
+ }, [resolved.supabaseUrl, resolved.siteUrl, config.apiKey, autoIdentity.accessToken]);
490
518
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
491
519
  FeedbackProviderInner,
492
520
  {
@@ -513,6 +541,7 @@ function FeedbackProvider({
513
541
  userId: effectiveUserId,
514
542
  userEmail: effectiveEmail,
515
543
  userDisplayName: effectiveDisplayName,
544
+ openThreadInDashboard,
516
545
  children
517
546
  }
518
547
  );
@@ -541,7 +570,8 @@ function FeedbackProviderInner({
541
570
  debug,
542
571
  userId,
543
572
  userEmail,
544
- userDisplayName
573
+ userDisplayName,
574
+ openThreadInDashboard
545
575
  }) {
546
576
  const debugLog = (0, import_react2.useCallback)((message, extra) => {
547
577
  if (!debug) return;
@@ -652,6 +682,7 @@ function FeedbackProviderInner({
652
682
  const target = event.target;
653
683
  if (!(target instanceof Element)) return;
654
684
  if (!target.closest('[data-ew-feedback-interactive="true"]')) return;
685
+ if (target.closest("[data-ew-launcher]")) return;
655
686
  event.stopPropagation();
656
687
  };
657
688
  window.addEventListener("pointerdown", handleSdkPointerDownCapture, true);
@@ -932,7 +963,8 @@ function FeedbackProviderInner({
932
963
  setPendingScreenshotPin,
933
964
  submitThread,
934
965
  submitScreenshotThread,
935
- refreshThreads: fetchThreads
966
+ refreshThreads: fetchThreads,
967
+ openThreadInDashboard
936
968
  },
937
969
  children: [
938
970
  children,
@@ -1292,7 +1324,7 @@ function ThreadPins() {
1292
1324
  const signedUrlCache = (0, import_react5.useRef)({});
1293
1325
  const threads = ctx?.threads ?? EMPTY_THREADS;
1294
1326
  const client = ctx?.client;
1295
- const threadBaseUrl = ctx?.siteUrl?.replace(/\/+$/, "") || window.location.origin;
1327
+ const openThreadInDashboard = ctx?.openThreadInDashboard;
1296
1328
  const scrollContainer = ctx?.scrollContainer;
1297
1329
  const container = scrollContainer?.ref.current ?? null;
1298
1330
  const getSignedUrl = (0, import_react5.useCallback)(async (path) => {
@@ -1416,8 +1448,8 @@ function ThreadPins() {
1416
1448
  });
1417
1449
  return;
1418
1450
  }
1419
- window.open(`${threadBaseUrl}/threads/${pin.threadId}`, "_blank", "noopener,noreferrer");
1420
- }, [getSignedUrl, threadBaseUrl]);
1451
+ openThreadInDashboard?.(pin.threadId);
1452
+ }, [getSignedUrl, openThreadInDashboard]);
1421
1453
  const containerLayer = (0, import_react5.useMemo)(() => {
1422
1454
  if (!container || containerPositions.length === 0) return null;
1423
1455
  const { width, height } = getContainerContentSize(container);
@@ -1544,7 +1576,7 @@ function ReviewSurfaceOverlay() {
1544
1576
  const mode = ctx?.mode ?? "view";
1545
1577
  const reviewUrl = ctx?.reviewUrl ?? null;
1546
1578
  const threads = ctx?.threads ?? EMPTY_THREADS2;
1547
- const threadBaseUrl = ctx?.siteUrl?.replace(/\/+$/, "") || window.location.origin;
1579
+ const openThreadInDashboard = ctx?.openThreadInDashboard;
1548
1580
  const updateMetrics = (0, import_react6.useCallback)(() => {
1549
1581
  const iframe = iframeRef.current;
1550
1582
  if (!iframe) return;
@@ -1722,7 +1754,7 @@ function ReviewSurfaceOverlay() {
1722
1754
  index: index + 1,
1723
1755
  left,
1724
1756
  top,
1725
- onClick: () => window.open(`${threadBaseUrl}/threads/${thread.id}`, "_blank", "noopener,noreferrer")
1757
+ onClick: () => openThreadInDashboard?.(thread.id)
1726
1758
  },
1727
1759
  thread.id
1728
1760
  );
@@ -2379,6 +2411,7 @@ function FeedbackButton({ position = "bottom-right" }) {
2379
2411
  {
2380
2412
  ref: menuRef,
2381
2413
  "data-ew-feedback-interactive": "true",
2414
+ "data-ew-launcher": true,
2382
2415
  style: { ...wrapperStyle, touchAction: "none" },
2383
2416
  onPointerDown: handlePointerDown,
2384
2417
  onPointerMove: handlePointerMove,