Skip to content

Conversation

@DanielRivers
Copy link
Member

Explain your changes

Add support for invitations

Checklist

🛟 If you need help, consider asking for advice over in the Kinde community.

@DanielRivers DanielRivers requested review from a team as code owners December 2, 2025 13:03
@coderabbitai
Copy link

coderabbitai bot commented Dec 2, 2025

Walkthrough

Modified KindeProvider.tsx to add synchronous invitation-code handling from URL parameters. The change introduces ref-based state management to coordinate invitation-based login redirects, with conditional child rendering and early-exit initialization guards to isolate the invitation flow from normal authentication.

Changes

Cohort / File(s) Summary
Invitation-code redirect flow
src/state/KindeProvider.tsx
Adds ref-based invitation_code parsing and storage; introduces isRedirectingRef, redirectInitiatedRef, and loginRef to manage redirect coordination; implements useEffect to trigger login with prompt=create when invitation_code exists; conditionally prevents child rendering during active redirect; updates initialization logic with early-return guard when redirect is in progress.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Ref management correctness: Verify initialization, lifecycle, and proper updates of isRedirectingRef, redirectInitiatedRef, invitationCodeRef, and loginRef
  • useEffect logic and dependencies: Ensure correct trigger conditions, dependency array completeness, and error handling for the invitation redirect flow
  • Render conditionals: Confirm child rendering prevention is properly guarded and that forceChildrenRender override works as intended
  • Init flow interaction: Validate that early-return logic during redirect doesn't break normal authentication initialization or create state inconsistencies

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: add support for invitationCode' directly matches the main changeset focus of adding invitation code handling functionality.
Description check ✅ Passed The description 'Add support for invitations' relates to the changeset which implements invitation code functionality in the KindeProvider.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/invitation_code

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (4)
src/state/KindeProvider.tsx (4)

228-234: URL parsing runs on every render.

new URLSearchParams(window.location.search) executes on every render, even though the refs only initialize once. Consider memoizing this or using a lazy initialization pattern:

-  // Check for invitation_code synchronously before any hooks/rendering
-  const params = new URLSearchParams(window.location.search);
-  const hasInvitationCode = params.has("invitation_code");
-  const invitationCodeRef = useRef<string | null>(
-    hasInvitationCode ? params.get("invitation_code") : null,
-  );
-  const isRedirectingRef = useRef(hasInvitationCode);
+  // Check for invitation_code synchronously before any hooks/rendering
+  const invitationCodeRef = useRef<string | null>(null);
+  const isRedirectingRef = useRef(false);
+  
+  // Initialize refs only once
+  if (invitationCodeRef.current === null && isRedirectingRef.current === false) {
+    const params = new URLSearchParams(window.location.search);
+    if (params.has("invitation_code")) {
+      invitationCodeRef.current = params.get("invitation_code");
+      isRedirectingRef.current = true;
+    }
+  }

Alternatively, use a dedicated initialization ref to track whether parsing has been done.


375-376: loginRef is assigned but never read.

loginRef is assigned at line 436 but never used elsewhere. The useEffect at line 439 directly uses the login callback from the dependency array instead of loginRef.current. Either remove the unused ref or use it for the intended immediate access pattern.

If the ref is no longer needed:

   const initRef = useRef(false);
-  const loginRef = useRef<typeof login | null>(null);
   const redirectInitiatedRef = useRef(false);

And remove the assignment at lines 435-436.


439-456: Consider invoking onError callback on invitation redirect failure.

The catch block logs the error but doesn't notify the application via the onError callback. This could leave users on a blank screen (since children aren't rendered during redirect) without understanding what went wrong.

       }).catch((error) => {
         console.error("Error processing invitation code:", error);
+        mergedCallbacks.onError?.(
+          {
+            error: "ERR_INVITATION_REDIRECT",
+            errorDescription: String(error),
+          },
+          {},
+          {} as KindeContextProps,
+        );
         isRedirectingRef.current = false;
         redirectInitiatedRef.current = false;
       });

Also note: the login && check on line 443 is always true since login is a stable useCallback reference.


788-793: Unused variable declaration before early return.

The params variable declared at line 788 is unused when isRedirectingRef.current is true (the early return at line 792). Additionally, it shadows the params variable from line 229. Consider removing this redundant parsing or moving it after the guard clause:

   const init = useCallback(async () => {
     if (initRef.current) return;
     try {
-      const params = new URLSearchParams(window.location.search);
-
       // Skip initialization if redirecting for invitation (handled in useEffect above)
       if (isRedirectingRef.current) {
         return;
       }

+      const params = new URLSearchParams(window.location.search);
+
       try {
         initRef.current = true;
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 256ae19 and a22deb3.

⛔ Files ignored due to path filters (1)
  • package.json is excluded by !**/*.json
📒 Files selected for processing (1)
  • src/state/KindeProvider.tsx (6 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-09-05T12:17:11.365Z
Learnt from: DanielRivers
Repo: kinde-oss/kinde-auth-react PR: 173
File: src/state/KindeProvider.tsx:584-585
Timestamp: 2025-09-05T12:17:11.365Z
Learning: In Kinde auth React applications, the callback URL (redirectUri) is always absolute because it's required for hosted auth to work properly.

Applied to files:

  • src/state/KindeProvider.tsx
🔇 Additional comments (1)
src/state/KindeProvider.tsx (1)

890-893: LGTM!

The conditional render suppression correctly prevents rendering children during the invitation redirect flow while respecting the forceChildrenRender escape hatch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants