Skip to content

refactor(saml): convert ServiceProvider deflate flow to async/await#38742

Open
ATHARVA279 wants to merge 2 commits intoRocketChat:developfrom
ATHARVA279:refactor/saml-serviceprovider-async-await
Open

refactor(saml): convert ServiceProvider deflate flow to async/await#38742
ATHARVA279 wants to merge 2 commits intoRocketChat:developfrom
ATHARVA279:refactor/saml-serviceprovider-async-await

Conversation

@ATHARVA279
Copy link

@ATHARVA279 ATHARVA279 commented Feb 17, 2026

Proposed changes (including videos or screenshots)

Issue(s)

Steps to test or reproduce

Further comments

fix #38741

Summary by CodeRabbit

  • Refactor
    • Improved SAML logout flow with asynchronous handling and more robust URL construction and error propagation, resulting in more reliable logout redirects.

@dionisio-bot
Copy link
Contributor

dionisio-bot bot commented Feb 17, 2026

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

  • This PR is missing the 'stat: QA assured' label
  • 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 Feb 17, 2026

⚠️ No Changeset found

Latest commit: fae8cab

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

@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 17, 2026

Walkthrough

The SAML ServiceProvider refactors internal callback-based async flows to async/await. A module-scoped deflateRawAsync helper and a new private buildLogoutResponseUrl(response: string): Promise<string> consolidate deflate, encoding, signing, and query assembly used by logout and request URL builders.

Changes

Cohort / File(s) Summary
SAML Async Refactor
apps/meteor/app/meteor-accounts-saml/server/lib/ServiceProvider.ts
Added deflateRawAsync helper; replaced inline callback-based zlib.deflateRaw usage with Promise/async-await; introduced private buildLogoutResponseUrl(response: string): Promise<string> to perform deflate, base64 encoding, relay-state, signing, and query assembly; updated logoutResponseToUrl and requestToUrl call sites to use the new helper and async flow.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐇 I hopped through tangled callback trails,

Swapped nests of callbacks for async sails,
A single helper hums a tidy tune,
Logout URLs now sparkle like the moon,
—happy rabbit, coding under the rune

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: converting callback-based async deflate flow to async/await patterns in the SAML ServiceProvider module.
Linked Issues check ✅ Passed The PR implements all key coding objectives: converts callback-based async operations to async/await, improves error handling, preserves external behavior, and maintains existing test compatibility.
Out of Scope Changes check ✅ Passed All changes are directly aligned with the refactoring objective of converting the deflate flow to async/await in the target ServiceProvider.ts file; no unrelated modifications detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 1 file

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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/meteor/app/meteor-accounts-saml/server/lib/ServiceProvider.ts (1)

110-154: ⚠️ Potential issue | 🟡 Minor

deflateRawAsync is now outside the try/catch — intentional?

The deflateRawAsync call on Line 111 is outside the try block (Lines 112–153). If deflation fails, the raw error propagates instead of going through the error instanceof Error ? error : String(error) normalization on Line 152. This is benign since deflateRawAsync will only throw Error instances, but it's a subtle behavioral change from the original code worth being aware of.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/app/meteor-accounts-saml/server/lib/ServiceProvider.ts` around
lines 110 - 154, The call to deflateRawAsync in requestToUrl is currently
outside the try/catch so its errors bypass the existing normalization; move the
await deflateRawAsync(request) inside the existing try block (or wrap it in a
small try/catch that rethrows using the same normalization: throw error
instanceof Error ? error : String(error)) so all exceptions from deflation are
handled consistently by the requestToUrl error path.
🧹 Nitpick comments (2)
apps/meteor/app/meteor-accounts-saml/server/lib/ServiceProvider.ts (2)

167-168: Remove code comment from implementation.

Line 167 introduces a code comment in new code. As per coding guidelines, "Avoid code comments in the implementation".

Proposed fix
-		// TBD. We should really include a proper RelayState here
 		const relayState = Meteor.absoluteUrl();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/app/meteor-accounts-saml/server/lib/ServiceProvider.ts` around
lines 167 - 168, Remove the inline implementation comment preceding relayState
and keep only the code; delete the comment "// TBD. We should really include a
proper RelayState here" so the function uses const relayState =
Meteor.absoluteUrl() without implementation comments, leaving any design notes
to PR description or separate documentation; locate the declaration of
relayState in ServiceProvider.ts to remove that comment.

96-105: The async IIFE bridge is correct but consider making the method itself async.

The void (async () => { ... })() pattern properly bridges async logic into the callback-based signature. If the public contract permits it, converting logoutResponseToUrl to return a Promise<string> (like requestToUrl already does) and deprecating the callback overload would complete the modernization goal from issue #38741. That said, if callers still rely on the callback shape, this intermediate step is fine.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/app/meteor-accounts-saml/server/lib/ServiceProvider.ts` around
lines 96 - 105, The method logoutResponseToUrl currently wraps an async IIFE to
call buildLogoutResponseUrl and invoke a callback; change logoutResponseToUrl
into an async function that returns Promise<string> (remove the callback
parameter), simply await this.buildLogoutResponseUrl(response) and return the
target, and mark the old callback-based usage as deprecated (update or remove
any callback callers to use the returned Promise). Ensure references to
logoutResponseToUrl and buildLogoutResponseUrl are updated accordingly so
callers now await logoutResponseToUrl(response).
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 508b4a1 and 83eb250.

📒 Files selected for processing (1)
  • apps/meteor/app/meteor-accounts-saml/server/lib/ServiceProvider.ts
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

**/*.{ts,tsx,js}: Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests
Avoid code comments in the implementation

Files:

  • apps/meteor/app/meteor-accounts-saml/server/lib/ServiceProvider.ts
🧬 Code graph analysis (1)
apps/meteor/app/meteor-accounts-saml/server/lib/ServiceProvider.ts (1)
apps/meteor/app/meteor-accounts-saml/server/lib/Utils.ts (3)
  • error (142-146)
  • relayState (45-47)
  • relayState (49-51)
🔇 Additional comments (2)
apps/meteor/app/meteor-accounts-saml/server/lib/ServiceProvider.ts (2)

28-29: LGTM — module-scoped promisified helper.

Clean extraction avoids repeated util.promisify calls across methods.


156-178: Clean extraction of the logout response URL building logic.

The method correctly mirrors the pattern from requestToUrl for logout responses.

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@apps/meteor/app/meteor-accounts-saml/server/lib/ServiceProvider.ts`:
- Around line 110-154: The call to deflateRawAsync in requestToUrl is currently
outside the try/catch so its errors bypass the existing normalization; move the
await deflateRawAsync(request) inside the existing try block (or wrap it in a
small try/catch that rethrows using the same normalization: throw error
instanceof Error ? error : String(error)) so all exceptions from deflation are
handled consistently by the requestToUrl error path.

---

Nitpick comments:
In `@apps/meteor/app/meteor-accounts-saml/server/lib/ServiceProvider.ts`:
- Around line 167-168: Remove the inline implementation comment preceding
relayState and keep only the code; delete the comment "// TBD. We should really
include a proper RelayState here" so the function uses const relayState =
Meteor.absoluteUrl() without implementation comments, leaving any design notes
to PR description or separate documentation; locate the declaration of
relayState in ServiceProvider.ts to remove that comment.
- Around line 96-105: The method logoutResponseToUrl currently wraps an async
IIFE to call buildLogoutResponseUrl and invoke a callback; change
logoutResponseToUrl into an async function that returns Promise<string> (remove
the callback parameter), simply await this.buildLogoutResponseUrl(response) and
return the target, and mark the old callback-based usage as deprecated (update
or remove any callback callers to use the returned Promise). Ensure references
to logoutResponseToUrl and buildLogoutResponseUrl are updated accordingly so
callers now await logoutResponseToUrl(response).

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.

🧹 Nitpick comments (1)
apps/meteor/app/meteor-accounts-saml/server/lib/ServiceProvider.ts (1)

156-177: Consider extracting shared URL-building logic to reduce duplication.

buildLogoutResponseUrl and requestToUrl share nearly identical steps: deflate → base64 → target URL selection → separator → relay state → sign → stringify. Extracting a common private helper (e.g., buildRedirectUrl(payload, target, relayState)) would reduce duplication and make future changes less error-prone.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/app/meteor-accounts-saml/server/lib/ServiceProvider.ts` around
lines 156 - 177, Both buildLogoutResponseUrl and requestToUrl duplicate the same
URL-building steps (deflate → base64 → choose target → append separator → set
RelayState → maybeSignRequest → querystring.stringify); extract that into a
private helper (e.g., buildRedirectUrl or buildSignedRedirect) and have
buildLogoutResponseUrl and requestToUrl call it. The helper should accept the
payload (SAMLResponse or SAMLRequest), target URL (use
serviceProviderOptions.idpSLORedirectURL or caller-provided target), and
relayState (default to Meteor.absoluteUrl()), perform deflateRawAsync + base64,
call maybeSignRequest, and return target + querystring.stringify(signedPayload)
so both methods keep minimal logic and no duplicated steps.
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 83eb250 and fae8cab.

📒 Files selected for processing (1)
  • apps/meteor/app/meteor-accounts-saml/server/lib/ServiceProvider.ts
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

**/*.{ts,tsx,js}: Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests
Avoid code comments in the implementation

Files:

  • apps/meteor/app/meteor-accounts-saml/server/lib/ServiceProvider.ts
🔇 Additional comments (4)
apps/meteor/app/meteor-accounts-saml/server/lib/ServiceProvider.ts (4)

28-29: Clean extraction of deflateRawAsync.

Good use of util.promisify at module scope to avoid repeated promisification.


96-105: LGTM — async IIFE with void is a clean bridge from callback to async.

The void operator correctly suppresses the floating-promise lint, and the try/catch properly funnels errors back into the callback.


112-112: Clean swap to deflateRawAsync.


156-177: No action needed. The idpSLORedirectURL property is a required string field in the IServiceProviderOptions interface, not optional. The code at line 159 correctly assigns this property to target without a guard, and calling .indexOf('?') is safe. The pattern in requestToUrl that checks if (this.serviceProviderOptions.idpSLORedirectURL) before using it is defensive coding despite the property being required by the type.

Likely an incorrect or invalid review comment.

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@apps/meteor/app/meteor-accounts-saml/server/lib/ServiceProvider.ts`:
- Around line 156-177: Both buildLogoutResponseUrl and requestToUrl duplicate
the same URL-building steps (deflate → base64 → choose target → append separator
→ set RelayState → maybeSignRequest → querystring.stringify); extract that into
a private helper (e.g., buildRedirectUrl or buildSignedRedirect) and have
buildLogoutResponseUrl and requestToUrl call it. The helper should accept the
payload (SAMLResponse or SAMLRequest), target URL (use
serviceProviderOptions.idpSLORedirectURL or caller-provided target), and
relayState (default to Meteor.absoluteUrl()), perform deflateRawAsync + base64,
call maybeSignRequest, and return target + querystring.stringify(signedPayload)
so both methods keep minimal logic and no duplicated steps.

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.

fix: refactor callback-based async flow to async/await in SAML ServiceProvider

2 participants