Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fix-auth-button-cross-contamination.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@knocklabs/react-core": patch
---

Fix auth button cross-contamination when SlackKit and TeamsKit are rendered simultaneously. The shared `useAuthPostMessageListener` hook now checks whether its own popup is open before processing `authComplete` messages, preventing one integration's OAuth completion from incorrectly updating the other's connection state.
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ export function useAuthPostMessageListener(
return;
}

// Ignore messages when this integration hasn't opened a popup
if (!popupWindowRef.current || popupWindowRef.current.closed) {
return;
Comment thread
meryldakin marked this conversation as resolved.
}
Comment thread
cursor[bot] marked this conversation as resolved.

const messageType = getMessageType(event.data);

if (messageType === "authComplete") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,50 @@ describe("useAuthPostMessageListener", () => {
expect(popupWindowRef.current).toBeNull();
});

it("should ignore messages when popupWindowRef is null", () => {
popupWindowRef.current = null;

renderHook(() =>
useAuthPostMessageListener({
knockHost,
popupWindowRef,
setConnectionStatus,
onAuthenticationComplete,
}),
);

const event = new MessageEvent("message", {
data: "authComplete",
origin: knockHost,
});
window.dispatchEvent(event);

expect(setConnectionStatus).not.toHaveBeenCalled();
expect(onAuthenticationComplete).not.toHaveBeenCalled();
});

it("should ignore messages when popup is closed", () => {
mockPopup.closed = true;

renderHook(() =>
useAuthPostMessageListener({
knockHost,
popupWindowRef,
setConnectionStatus,
onAuthenticationComplete,
}),
);

const event = new MessageEvent("message", {
data: "authComplete",
origin: knockHost,
});
window.dispatchEvent(event);

expect(setConnectionStatus).not.toHaveBeenCalled();
expect(onAuthenticationComplete).not.toHaveBeenCalled();
});

it("should ignore messages from different origins", () => {
renderHook(() =>
useAuthPostMessageListener({
Expand Down
Loading