Skip to content

Conversation

@yash-rajpal
Copy link
Member

@yash-rajpal yash-rajpal commented Oct 24, 2025

Proposed changes (including videos or screenshots)

Issue(s)

Steps to test or reproduce

Further comments

Backports #37021

Summary by CodeRabbit

  • Bug Fixes
    • Iframe-based authentication now automatically activates when the feature is enabled, streamlining the login experience
    • Enhanced token login callback handling with improved error propagation and detection
    • Improved authentication response validation and error checking during token login flow
    • Refined authentication request handling for better reliability and error recovery

@dionisio-bot
Copy link
Contributor

dionisio-bot bot commented Oct 24, 2025

Looks like this PR is not ready to merge, because of the following issues:

  • This PR is missing the required milestone or project

Please fix the issues and try again

If you have any trouble, please check the PR guidelines

@changeset-bot
Copy link

changeset-bot bot commented Oct 24, 2025

⚠️ No Changeset found

Latest commit: 45a3309

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 24, 2025

Walkthrough

The iframe authentication hook is refactored from useCallback to useEffectEvent pattern, with explicit network fetch logic, callback propagation, and error handling. The LoginPage component is updated to automatically invoke the iframe login flow on mount when enabled.

Changes

Cohort / File(s) Summary
useIframe Hook Refactoring
apps/meteor/client/hooks/iframe/useIframe.ts
Changed import from useEffect to useEffectEvent; rewrote tryLogin implementation to useEffectEvent-based async flow with fetch, error handling, and callback propagation; updated tokenLogin invocation to accept and forward callback parameter; relocated Electron URL augmentation to post-normalization phase.
LoginPage Integration
apps/meteor/client/views/root/MainLayout/LoginPage.tsx
Added useEffect hook to auto-invoke iframe-based login on mount/update; destructured tryLogin and enabled from useIframe hook; maintained existing iframeLoginUrl rendering logic.

Sequence Diagram

sequenceDiagram
    participant LP as LoginPage
    participant UE as useIframe<br/>(useEffectEvent)
    participant API as Rocket.Chat<br/>API
    participant CB as Callback

    LP->>LP: useEffect (on mount/enabled change)
    LP->>UE: tryLogin(callback)
    activate UE
    
    rect rgb(240, 248, 255)
      note right of UE: Build URL with proper<br/>separator & Electron flag
      UE->>UE: Construct API URL
    end
    
    UE->>API: fetch(apiUrl, {method, credentials})
    activate API
    API-->>UE: response
    deactivate API
    
    alt Success (result.ok)
      rect rgb(220, 240, 220)
        UE->>UE: Parse response.json()
        UE->>UE: loginWithToken(body, callback)
        UE->>CB: callback(null, result)
      end
    else Error
      rect rgb(255, 220, 220)
        UE->>UE: setIframeLoginUrl(url)
        UE->>CB: callback(error, null)
      end
    end
    
    deactivate UE
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

The changes involve heterogeneous modifications across two files: a complex hook rewrite with async logic and callback propagation in useIframe, paired with straightforward integration changes in LoginPage. The logic density is moderate in the hook implementation with error handling paths and URL construction, while the LoginPage changes are minimal and repetitive.

Possibly related PRs

Suggested labels

stat: ready to merge, stat: QA assured

Suggested reviewers

  • MartinSchoeler
  • tassoevan

Poem

🐰 Hops through the iframe with glee,
useEffectEvent flows so free,
Callbacks cascade, errors caught tight,
Auto-login springs forth at first light,
The frame doth dance in React's delight!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "fix: iframe auth api request loop" is directly related to the main changes in the pull request. The modifications restructure iframe authentication logic by switching from useEffect to useEffectEvent and reorganizing how the authentication flow is invoked, which aligns with fixing a looping issue in API requests. The title is concise, specific enough for team members to understand the primary focus (iframe authentication loop fix), and accurately captures the intent of the changeset without being vague or misleading.
✨ 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 backport-7.10.3-37021

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.

@codecov
Copy link

codecov bot commented Oct 24, 2025

Codecov Report

❌ Patch coverage is 74.07407% with 7 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (release-7.10.3@4464136). Learn more about missing BASE report.

Additional details and impacted files

Impacted file tree graph

@@                Coverage Diff                @@
##             release-7.10.3   #37295   +/-   ##
=================================================
  Coverage                  ?   66.22%           
=================================================
  Files                     ?     3289           
  Lines                     ?   110364           
  Branches                  ?    20910           
=================================================
  Hits                      ?    73087           
  Misses                    ?    34592           
  Partials                  ?     2685           
Flag Coverage Δ
e2e 57.46% <74.07%> (?)
unit 71.53% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@yash-rajpal yash-rajpal marked this pull request as ready for review October 24, 2025 17:34
@yash-rajpal yash-rajpal requested a review from a team as a code owner October 24, 2025 17:34
Copy link
Contributor

@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: 1

🧹 Nitpick comments (7)
apps/meteor/client/hooks/iframe/useIframe.ts (6)

40-49: Use URL/URLSearchParams instead of manual separator logic.

Safer and clearer than string concatenation; also future‑proof if more params are added.

Apply:

-		let url = accountIframeUrl;
-		let separator = '?';
-		if (url.indexOf('?') > -1) {
-			separator = '&';
-		}
-
-		if (navigator.userAgent.indexOf('Electron') > -1) {
-			url += `${separator}client=electron`;
-		}
+		const urlObj = new URL(accountIframeUrl, window.location.origin);
+		if (navigator.userAgent.includes('Electron')) {
+			urlObj.searchParams.set('client', 'electron');
+		}
+		const url = urlObj.toString();

18-33: Avoid double dispatch when both loginToken and token exist.

Current logic can invoke both tokenLogin and iframeLogin. Prefer an exclusive branch and early return.

  const loginWithToken = useCallback(
-		(tokenData: string | { loginToken: string } | { token: string }, callback?: (error: Error | null | undefined) => void) => {
+		(tokenData: string | { loginToken: string } | { token: string }, callback?: (error: Error | null | undefined) => void) => {
 			if (typeof tokenData === 'string') {
 				tokenData = {
 					token: tokenData,
 				};
 			}
-			if ('loginToken' in tokenData) {
-				tokenLogin(tokenData.loginToken, callback);
-			}
-			if ('token' in tokenData) {
-				iframeLogin(tokenData.token, callback);
-			}
+			if ('loginToken' in tokenData) {
+				return tokenLogin(tokenData.loginToken, callback);
+			}
+			if ('token' in tokenData) {
+				return iframeLogin(tokenData.token, callback);
+			}
+			callback?.(new Error('Missing token data'));
 		},
 		[iframeLogin, tokenLogin],
 	);

51-55: Harden network call: normalize method, set Accept header, consider abort/timeout.

  • Normalize to an allowlist of methods (GET/POST).
  • Add Accept: application/json.
  • Consider AbortController to prevent state updates after unmount and to avoid hanging requests.
-			const result = await fetch(apiUrl, {
-				method: apiMethod,
-				headers: undefined,
-				credentials: 'include',
-			});
+			const method = apiMethod?.toUpperCase() === 'POST' ? 'POST' : 'GET';
+			const response = await fetch(apiUrl, {
+				method,
+				credentials: 'include',
+				headers: { Accept: 'application/json' },
+			});

57-61: Improve error reporting and rename result to response for clarity.

  • Use !response.ok only; include status details in the error.
  • Avoid confusing naming (result is also a param name in the callback type).
-			if (!result.ok || result.status !== 200) {
-				setIframeLoginUrl(url);
-				callback?.(new Error(), null);
-				return;
-			}
-
-			const body = await result.json();
+			if (!response.ok) {
+				setIframeLoginUrl(url);
+				callback?.(new Error(`Iframe auth API failed: ${response.status} ${response.statusText}`), null);
+				return;
+			}
+
+			const body = await response.json();

Also applies to: 63-64


72-75: Normalize thrown values to Error.

Ensure the callback always receives an Error with a message for diagnostics.

-		} catch (error) {
-			setIframeLoginUrl(url);
-			callback?.(error instanceof Error ? error : undefined, null);
+		} catch (error) {
+			setIframeLoginUrl(url);
+			const err = error instanceof Error ? error : new Error(String(error));
+			callback?.(err, null);
 		}

51-55: Optional: add an AbortController with timeout.

Prevents hanging fetch and state updates after unmount. Keep minimal if you prefer, but recommended.

Example (outside the selected lines to illustrate structure):

const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), 10000);
try {
  const response = await fetch(apiUrl, { method, credentials: 'include', headers: { Accept: 'application/json' }, signal: controller.signal });
  // ...
} finally {
  clearTimeout(timer);
}
apps/meteor/client/views/root/MainLayout/LoginPage.tsx (1)

16-23: Optional: guard against double‑invoke in React 18 StrictMode (dev‑only).

In dev, effects run twice on mount. A simple ref prevents duplicate API calls.

+import { useEffect, useRef } from 'react';
...
-	useEffect(() => {
-		if (!iframeEnabled) {
-			return;
-		}
-		tryLogin();
-	}, [tryLogin, iframeEnabled]);
+	const attemptedRef = useRef(false);
+	useEffect(() => {
+		if (!iframeEnabled || attemptedRef.current) {
+			return;
+		}
+		attemptedRef.current = true;
+		tryLogin();
+	}, [tryLogin, iframeEnabled]);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between cd4a08a and 0e6a81d.

📒 Files selected for processing (2)
  • apps/meteor/client/hooks/iframe/useIframe.ts (3 hunks)
  • apps/meteor/client/views/root/MainLayout/LoginPage.tsx (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
apps/meteor/client/views/root/MainLayout/LoginPage.tsx (1)
apps/meteor/client/hooks/iframe/useIframe.ts (1)
  • useIframe (5-84)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: 📦 Meteor Build - coverage
🔇 Additional comments (5)
apps/meteor/client/hooks/iframe/useIframe.ts (3)

35-38: Good guard to prevent unnecessary work when disabled.

Short-circuiting on !enabled is correct and helps avoid accidental loops or spurious requests.


1-1: Nice move to useEffectEvent to stop identity churn and request loops.

This should stabilize tryLogin and prevent re‑triggering effects due to changing callback references.

Also applies to: 35-35


18-33: No issues found with callback compatibility.

All three external usages of loginWithToken (ResetPasswordPage.tsx:76, useLoginViaQuery.ts:17, ComposerAnonymous.tsx:26) call it with a single token parameter and no callback—which is correct since the callback parameter is optional. The internal use within useIframe.ts (line 26) provides the callback, also valid. The optional callback signature accommodates both patterns without type or behavior drift.

apps/meteor/client/views/root/MainLayout/LoginPage.tsx (2)

16-23: Effect correctly initiates login without creating loops.

Dependencies are minimal and useEffectEvent keeps tryLogin stable. Looks good.


14-15: Destructuring enabled as iframeEnabled is clear and consistent.

Nice clarity improvement at the call site.

@yash-rajpal yash-rajpal added stat: QA assured Means it has been tested and approved by a company insider stat: ready to merge PR tested and approved waiting for merge labels Oct 24, 2025
@kodiakhq kodiakhq bot merged commit 7dc89a9 into release-7.10.3 Oct 24, 2025
22 checks passed
@kodiakhq kodiakhq bot deleted the backport-7.10.3-37021 branch October 24, 2025 18:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stat: QA assured Means it has been tested and approved by a company insider stat: ready to merge PR tested and approved waiting for merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants