Skip to content

feat: open browser login providers in a system auth session for WebAuthn support#7419

Open
diegolmello wants to merge 5 commits into
developfrom
custom-oauth-webauthn-login
Open

feat: open browser login providers in a system auth session for WebAuthn support#7419
diegolmello wants to merge 5 commits into
developfrom
custom-oauth-webauthn-login

Conversation

@diegolmello

@diegolmello diegolmello commented Jun 19, 2026

Copy link
Copy Markdown
Member

Proposed changes

Browser-based login currently opens inside an in-app WebView. WebViews cannot run the browser WebAuthn/FIDO2 API, so providers that require passkeys (Custom OAuth with Keycloak, Authentik, AWS Cognito, etc.) cannot complete login on mobile.

This switches every browser-based login to a real system auth session via WebBrowser.openAuthSessionAsync (ASWebAuthenticationSession on iOS, Chrome Custom Tabs on Android), both of which support WebAuthn. It follows the path Custom OAuth and Google login already used: the provider opens in the auth session, and the app completes login when the browser redirects back.

Changes:

  • serviceLogin.ts — Facebook, Github, Gitlab, Google, Linkedin, Meteor, Twitter and Wordpress request the server's redirect login style and open in the auth session. The server redirects to rocketchat://auth?…&type=oauth&credentialToken=…&credentialSecret=…, and login completes through the existing deep-link pipeline (parseDeepLinkingdeepLinkingOpenhandleOAuth). SAML and CAS open in the auth session and complete by parsing the redirect result directly with parseSamlOrCasRedirect. The now-unused WebView navigation helper is removed.
  • parseDeepLinking.ts (new) — the deep-link parser is extracted from app/index.tsx into a shared helper so both the OS deep-link listener and the new auth-session handler can use it. Behavior is unchanged.
  • deepLinking.jshandleOAuth is guarded against re-using a single-use credentialToken. On Android the redirect is delivered on two channels (the auth-session result and the OS deep-link listener, since the rocketchat scheme is registered BROWSABLE), which would otherwise consume the token twice and fail the login.

The in-app WebView is retained for iframe authentication.

Issue(s)

How to test or reproduce

OAuth (incl. WebAuthn/passkey):

  1. Configure a Custom OAuth provider that enforces WebAuthn/passkey authentication (e.g. Keycloak with a passkey policy).
  2. On the login screen, tap the provider button. A system auth session opens (not a WebView). Complete the passkey challenge.
  3. The browser redirects back to the app and login completes. Before this change, the WebView could not invoke the WebAuthn API, so this failed.
  4. Verify Google, Facebook, Github, Gitlab, Linkedin, Meteor, Twitter and Wordpress still log in normally through the auth session.

SAML and CAS (dedicated QA step — please test explicitly):

  1. Configure a SAML provider and log in by tapping the SAML button. The auth session opens, you complete the IdP login, and the app logs you in.
  2. Configure a CAS provider and log in by tapping the CAS button. The auth session opens, you complete the CAS login, and the app logs you in.

These two now complete by parsing the auth-session redirect result rather than inspecting WebView navigation, so they need explicit verification on both iOS and Android.

Screenshots

Types of changes

  • Bugfix (non-breaking change which fixes an issue)
  • Improvement (non-breaking change which improves a current function)
  • New feature (non-breaking change which adds functionality)
  • Documentation update (if none of the other choices apply)

Checklist

  • I have read the CONTRIBUTING doc
  • I have signed the CLA
  • Lint and unit tests pass locally with my changes
  • I have added tests that prove my fix is effective or that my feature works (if applicable)
  • I have added necessary documentation (if applicable)
  • Any dependent changes have been merged and published in downstream modules

Further comments

The server has supported redirect-style OAuth for all providers since 3.15.0, so no server change is required. A single deep-link parser is shared between the OS listener and the auth-session handler.

Summary by CodeRabbit

  • New Features
    • Improved OAuth sign-in flow by using an external browser auth session with redirect/deep-link handling, including SAML/CAS.
  • Bug Fixes
    • Prevented duplicate OAuth logins by ignoring repeated credential tokens during deep-link processing.
  • Tests
    • Added Jest coverage for deep-link URL parsing and OAuth dedup behavior in the deep-link saga.
  • Refactor
    • Centralized deep-link parsing into a shared helper and updated routing/handlers to use it across auth providers.

@diegolmello diegolmello requested a deployment to approve_e2e_testing June 19, 2026 17:55 — with GitHub Actions Waiting
@coderabbitai

coderabbitai Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Extracts an inline parseDeepLinking function from app/index.tsx into a shared helper module with tests. Replaces the custom OAuth in-app WebView flow with WebBrowser.openAuthSessionAsync (system browser), parsing the redirect URL and dispatching the deep-link action. Adds OAuth token deduplication in the deep-linking saga to prevent reprocessing the same credential.

Changes

OAuth System Browser Flow

Layer / File(s) Summary
parseDeepLinking shared helper
app/lib/methods/helpers/parseDeepLinking.ts, app/lib/methods/helpers/__tests__/parseDeepLinking.test.ts, app/index.tsx
New parseDeepLinking default export handles prefix normalization, category matching, and query parsing. Tests cover OAuth, room, invite, shareextension, and invalid inputs. Inline definition removed from app/index.tsx and replaced with an import.
openOAuthSession and openSSOSession via system browser
app/containers/LoginServices/serviceLogin.ts
Imports expo-web-browser, store, deepLinkingOpen, and parseDeepLinking. Adds OAUTH_REDIRECT_URL constant. New openOAuthSession calls WebBrowser.openAuthSessionAsync with the rocketchat://auth redirect scheme, parses the returned URL via parseDeepLinking, dispatches deepLinkingOpen, and logs errors. New openSSOSession handles SAML/CAS flows with parseSamlOrCasRedirect.
OAuth provider handlers updated
app/containers/LoginServices/serviceLogin.ts
All provider handlers (onPressFacebook, onPressGithub, onPressGitlab, onPressGoogle, onPressLinkedin, onPressMeteor, onPressTwitter, onPressWordpress, onPressCustomOAuth) switched to use getOAuthState('redirect'), include response_type=code, encode redirect parameters, and route through openOAuthSession. SSO handlers (onPressSaml, onPressCas) now call openSSOSession instead of the removed WebView pattern.
deepLinking saga deduplication
app/sagas/deepLinking.js, app/sagas/__tests__/deepLinking.test.ts
Module-scoped consumedOAuthToken added. handleOAuth now skips login if credentialToken is absent or already consumed, recording the token before invoking loginOAuthOrSso. Test suite verifies that duplicate credentialToken values are skipped and different tokens trigger new login attempts.

Sequence Diagram(s)

sequenceDiagram
  actor User
  participant providerHandler as Provider Handler
  participant openOAuthSession
  participant WebBrowser
  participant parseDeepLinking
  participant handleOAuth

  User->>providerHandler: tap OAuth provider button
  providerHandler->>openOAuthSession: authorization URL (response_type=code, encoded params)
  openOAuthSession->>WebBrowser: openAuthSessionAsync(url, "rocketchat://auth")
  WebBrowser-->>User: opens system browser for OAuth provider
  User-->>WebBrowser: completes authentication
  WebBrowser-->>openOAuthSession: result {type: "success", url: "rocketchat://auth?credentialToken=..."}
  openOAuthSession->>parseDeepLinking: result.url
  parseDeepLinking-->>openOAuthSession: parsed {type, credentialToken, credentialSecret}
  openOAuthSession->>handleOAuth: dispatch(deepLinkingOpen(parsed))
  handleOAuth->>handleOAuth: check consumedOAuthToken, deduplicate or call loginOAuthOrSso
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • RocketChat/Rocket.Chat.ReactNative#7343: Both PRs address SAML/CAS redirect deduplication—this PR moves SSO to system browser via openSSOSession and dedupes at the saga level, while the related PR gates WebView redirect handling.

Suggested reviewers

  • OtavioStasiak
🚥 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 PR title accurately describes the main change: switching OAuth login providers to use system auth session (via WebBrowser.openAuthSessionAsync) to enable WebAuthn support.
Linked Issues check ✅ Passed The PR fully addresses issue #5681 by implementing WebAuthn support through browser-based auth sessions, enabling OAuth login with passkey authentication.
Out of Scope Changes check ✅ Passed All changes are directly aligned with enabling WebAuthn support: OAuth/SSO provider refactoring, deep-link parsing extraction, deduplication logic, and comprehensive test coverage.
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.

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • NATIVE-1312: Request failed with status code 401

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.

Comment thread app/sagas/deepLinking.js

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
app/containers/LoginServices/serviceLogin.ts (1)

101-101: ⚡ Quick win

Add explicit return types to the new TS functions.

The new function declarations rely on inferred return types. Please annotate them explicitly (: void / : Promise<void>) to keep the login flow contract strict and readable.

♻️ Suggested change
-export const onPressCustomOAuth = ({ loginService, server }: { loginService: IItemService; server: string }) => {
+export const onPressCustomOAuth = ({ loginService, server }: { loginService: IItemService; server: string }): void => {
@@
-const openOAuthSession = async (url: string) => {
+const openOAuthSession = async (url: string): Promise<void> => {

As per coding guidelines, **/*.{ts,tsx}: Use TypeScript for type safety; add explicit type annotations to function parameters and return types.

Also applies to: 149-149

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/containers/LoginServices/serviceLogin.ts` at line 101, The functions
onPressCustomOAuth (at line 101) and the other function referenced at line 149
are missing explicit return type annotations. Add explicit return types to both
function declarations by specifying either `: void` or `: Promise<void>`
depending on whether each function is asynchronous or not. This ensures the
login flow contract is strict, readable, and follows the coding guidelines for
TypeScript type safety.

Source: Coding guidelines

app/lib/methods/helpers/parseDeepLinking.ts (1)

3-23: ⚡ Quick win

Define an explicit parser return contract (and nullable URL input).

The helper currently relies on inferred return typing, which weakens the deep-link payload contract across callers. Add an explicit return type and accept nullable input to match deep-link sources.

♻️ Suggested change
-const parseDeepLinking = (url: string) => {
+const parseDeepLinking = (url: string | null | undefined): Record<string, string | undefined> | null => {

As per coding guidelines, **/*.{ts,tsx}: Use TypeScript for type safety; add explicit type annotations to function parameters and return types.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/lib/methods/helpers/parseDeepLinking.ts` around lines 3 - 23, The
parseDeepLinking function lacks explicit type annotations for both its parameter
and return type, which weakens type safety. Add an explicit return type
annotation to the parseDeepLinking function to define the deep-link payload
contract, and make the url parameter accept nullable input (string | null or
string | undefined) to properly handle cases where deep-link sources may provide
null or undefined values.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/containers/LoginServices/serviceLogin.ts`:
- Around line 112-113: The URL composition logic in the serviceLogin function
uses includes(domain) to check if absolutePath is absolute, which is unreliable
and can generate invalid URLs. Replace the includes(domain) check with a proper
absolute-URL detection method (such as checking if absolutePath starts with a
protocol like http:// or https://, or using a URL parsing utility) to correctly
determine whether to prefix absolutePath with the domain before passing it to
openOAuthSession(url).

In `@app/sagas/deepLinking.js`:
- Around line 134-139: The variable consumedOAuthToken is being assigned the
credentialToken value before the loginOAuthOrSso function call completes. This
means if the login fails, the token is permanently marked as consumed for the
session. Move the assignment of consumedOAuthToken = credentialToken to after
the yield loginOAuthOrSso call succeeds, either by placing it after the yield
statement in the try block or in a success callback, so that only successfully
authenticated tokens are marked as consumed.

---

Nitpick comments:
In `@app/containers/LoginServices/serviceLogin.ts`:
- Line 101: The functions onPressCustomOAuth (at line 101) and the other
function referenced at line 149 are missing explicit return type annotations.
Add explicit return types to both function declarations by specifying either `:
void` or `: Promise<void>` depending on whether each function is asynchronous or
not. This ensures the login flow contract is strict, readable, and follows the
coding guidelines for TypeScript type safety.

In `@app/lib/methods/helpers/parseDeepLinking.ts`:
- Around line 3-23: The parseDeepLinking function lacks explicit type
annotations for both its parameter and return type, which weakens type safety.
Add an explicit return type annotation to the parseDeepLinking function to
define the deep-link payload contract, and make the url parameter accept
nullable input (string | null or string | undefined) to properly handle cases
where deep-link sources may provide null or undefined values.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 20acd6e4-de2d-448c-89ab-3b1a28ad79cc

📥 Commits

Reviewing files that changed from the base of the PR and between bf1dbdb and 9f1606c.

📒 Files selected for processing (5)
  • app/containers/LoginServices/serviceLogin.ts
  • app/index.tsx
  • app/lib/methods/helpers/__tests__/parseDeepLinking.test.ts
  • app/lib/methods/helpers/parseDeepLinking.ts
  • app/sagas/deepLinking.js
📜 Review details
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,jsx,tsx}: Use descriptive names for functions, variables, and classes that clearly convey their purpose
Write comments that explain the 'why' behind code decisions, not the 'what'
Keep functions small and focused on a single responsibility
Use const by default, let when reassignment is needed, and avoid var
Prefer async/await over .then() chains for handling asynchronous operations
Use explicit error handling with try/catch blocks for async operations
Avoid deeply nested code; refactor complex logic into helper functions

Files:

  • app/lib/methods/helpers/__tests__/parseDeepLinking.test.ts
  • app/sagas/deepLinking.js
  • app/lib/methods/helpers/parseDeepLinking.ts
  • app/index.tsx
  • app/containers/LoginServices/serviceLogin.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use TypeScript for type safety; add explicit type annotations to function parameters and return types
Prefer interfaces over type aliases for defining object shapes in TypeScript
Use enums for sets of related constants rather than magic strings or numbers

Use TypeScript with strict mode enabled

Files:

  • app/lib/methods/helpers/__tests__/parseDeepLinking.test.ts
  • app/lib/methods/helpers/parseDeepLinking.ts
  • app/index.tsx
  • app/containers/LoginServices/serviceLogin.ts
**/*.{js,jsx,ts,tsx,json}

📄 CodeRabbit inference engine (CLAUDE.md)

Use Prettier formatting with tabs, single quotes, 130 character line width, no trailing commas, and avoid arrow function parentheses

Files:

  • app/lib/methods/helpers/__tests__/parseDeepLinking.test.ts
  • app/sagas/deepLinking.js
  • app/lib/methods/helpers/parseDeepLinking.ts
  • app/index.tsx
  • app/containers/LoginServices/serviceLogin.ts
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Enforce ESLint rules from @rocket.chat/eslint-config with React, React Native, TypeScript, and Jest plugins

Files:

  • app/lib/methods/helpers/__tests__/parseDeepLinking.test.ts
  • app/sagas/deepLinking.js
  • app/lib/methods/helpers/parseDeepLinking.ts
  • app/index.tsx
  • app/containers/LoginServices/serviceLogin.ts
app/containers/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Place reusable UI components in 'app/containers/' directory

Files:

  • app/containers/LoginServices/serviceLogin.ts
🧠 Learnings (2)
📚 Learning: 2026-04-30T17:07:51.020Z
Learnt from: diegolmello
Repo: RocketChat/Rocket.Chat.ReactNative PR: 7274
File: app/lib/services/voip/MediaCallEvents.ts:0-0
Timestamp: 2026-04-30T17:07:51.020Z
Learning: In this Rocket.Chat React Native codebase, the ESLint rule `no-void: error` is enforced. When you see a promise returned from an async call that is not awaited (a “floating promise”), do not silence it with the `void somePromise()` pattern. Instead, handle the promise explicitly by attaching `.catch(...)` (or otherwise awaiting/handling the error) so unhandled-rejection risks are addressed in a way that satisfies the existing ESLint configuration.

Applied to files:

  • app/lib/methods/helpers/__tests__/parseDeepLinking.test.ts
  • app/lib/methods/helpers/parseDeepLinking.ts
  • app/index.tsx
  • app/containers/LoginServices/serviceLogin.ts
📚 Learning: 2026-05-07T13:19:52.152Z
Learnt from: diegolmello
Repo: RocketChat/Rocket.Chat.ReactNative PR: 7304
File: app/sagas/deepLinking.js:237-243
Timestamp: 2026-05-07T13:19:52.152Z
Learning: In this codebase’s Redux-Saga usage, remember that `yield put(action)` dispatches through the Redux store synchronously, and any saga(s) that synchronously react via action listeners (and synchronous `put` chains) will run to completion before the calling saga resumes at its next `yield`. As a result, within a single saga there is no scheduler interleaving between a `yield select(...)` and a subsequent `yield take(...)` at the next `yield` point, so a check-then-take pattern like `const state = yield select(...); if (state !== TARGET) { yield take(a => a.type === TARGET); }` is safe from TOCTOU races under the synchronous `put`/take model described above.

Applied to files:

  • app/sagas/deepLinking.js
🔇 Additional comments (2)
app/lib/methods/helpers/__tests__/parseDeepLinking.test.ts (1)

3-38: LGTM!

app/index.tsx (1)

25-25: LGTM!

Comment thread app/containers/LoginServices/serviceLogin.ts
Comment thread app/sagas/deepLinking.js Outdated
The guard that stops Android's double-delivered OAuth redirect from consuming
the single-use credentialToken twice had no coverage. Add cases asserting a
fresh token logs in once, a repeat of the same token is a no-op, and a distinct
token still logs in.

Claude-Session: https://claude.ai/code/session_01GrrvSigJqJYa9CK4W1FiSy
handleOAuth marks a credentialToken consumed before logging in; without a
secret the login can only fail, needlessly burning the token. Bail out early
when the secret is absent, alongside the empty-token and already-consumed checks.

Claude-Session: https://claude.ai/code/session_01GrrvSigJqJYa9CK4W1FiSy
@github-actions

Copy link
Copy Markdown

iOS Build Available

Rocket.Chat 4.74.0.109165

@github-actions

Copy link
Copy Markdown

WebViews cannot run the browser WebAuthn/FIDO2 API, so providers that
require passkeys could not complete login on mobile. Following the path
already used by Custom OAuth and Google, every browser-based login now
opens in a system auth session (ASWebAuthenticationSession on iOS,
Chrome Custom Tabs on Android), which supports WebAuthn.

- Facebook, Github, Gitlab, Google, Linkedin, Meteor, Twitter and
  Wordpress request the server's redirect login style and open in the
  auth session, completing through the deep-link pipeline.
- SAML and CAS open in the auth session and complete by parsing the
  redirect result directly.

The in-app WebView is retained for iframe authentication.

Claude-Session: https://claude.ai/code/session_01GrrvSigJqJYa9CK4W1FiSy
@diegolmello diegolmello temporarily deployed to approve_e2e_testing June 19, 2026 20:41 — with GitHub Actions Inactive
@diegolmello diegolmello changed the title feat: support WebAuthn/passkey login for Custom OAuth providers feat: open browser login providers in a system auth session for WebAuthn support Jun 19, 2026
@diegolmello diegolmello deployed to android_build June 19, 2026 20:44 — with GitHub Actions Active

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/containers/LoginServices/serviceLogin.ts`:
- Around line 124-129: In the onPressCas function, the `service` parameter is
constructed with an unencoded server URL value, which can cause parsing issues
on certain CAS servers. To fix this, apply URL encoding to the `server` variable
when building the URL string by wrapping it with encodeURIComponent() before
inserting it into the query string, so the full callback URL is properly escaped
as a query parameter value.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ddbd5ede-5af7-4c28-b053-6122f0d322d8

📥 Commits

Reviewing files that changed from the base of the PR and between 7bddf5e and 0e24828.

📒 Files selected for processing (1)
  • app/containers/LoginServices/serviceLogin.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
  • GitHub Check: ESLint and Test / run-eslint-and-test
  • GitHub Check: format
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,jsx,tsx}: Use descriptive names for functions, variables, and classes that clearly convey their purpose
Write comments that explain the 'why' behind code decisions, not the 'what'
Keep functions small and focused on a single responsibility
Use const by default, let when reassignment is needed, and avoid var
Prefer async/await over .then() chains for handling asynchronous operations
Use explicit error handling with try/catch blocks for async operations
Avoid deeply nested code; refactor complex logic into helper functions

Files:

  • app/containers/LoginServices/serviceLogin.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use TypeScript for type safety; add explicit type annotations to function parameters and return types
Prefer interfaces over type aliases for defining object shapes in TypeScript
Use enums for sets of related constants rather than magic strings or numbers

Use TypeScript with strict mode enabled

Files:

  • app/containers/LoginServices/serviceLogin.ts
**/*.{js,jsx,ts,tsx,json}

📄 CodeRabbit inference engine (CLAUDE.md)

Use Prettier formatting with tabs, single quotes, 130 character line width, no trailing commas, and avoid arrow function parentheses

Files:

  • app/containers/LoginServices/serviceLogin.ts
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Enforce ESLint rules from @rocket.chat/eslint-config with React, React Native, TypeScript, and Jest plugins

Files:

  • app/containers/LoginServices/serviceLogin.ts
app/containers/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Place reusable UI components in 'app/containers/' directory

Files:

  • app/containers/LoginServices/serviceLogin.ts
🧠 Learnings (1)
📚 Learning: 2026-04-30T17:07:51.020Z
Learnt from: diegolmello
Repo: RocketChat/Rocket.Chat.ReactNative PR: 7274
File: app/lib/services/voip/MediaCallEvents.ts:0-0
Timestamp: 2026-04-30T17:07:51.020Z
Learning: In this Rocket.Chat React Native codebase, the ESLint rule `no-void: error` is enforced. When you see a promise returned from an async call that is not awaited (a “floating promise”), do not silence it with the `void somePromise()` pattern. Instead, handle the promise explicitly by attaching `.catch(...)` (or otherwise awaiting/handling the error) so unhandled-rejection risks are addressed in a way that satisfies the existing ESLint configuration.

Applied to files:

  • app/containers/LoginServices/serviceLogin.ts
🔇 Additional comments (6)
app/containers/LoginServices/serviceLogin.ts (6)

5-12: LGTM!


16-70: LGTM!


72-98: LGTM!


115-122: LGTM!


162-177: LGTM!


179-191: LGTM!

Comment on lines 124 to 129
export const onPressCas = ({ casLoginUrl, server }: { casLoginUrl: string; server: string }) => {
logEvent(events.ENTER_WITH_CAS);
const ssoToken = random(17);
const url = `${casLoginUrl}?service=${server}/_cas/${ssoToken}`;
openOAuth({ url, ssoToken, authType: 'cas' });
openSSOSession(url, 'cas', ssoToken);
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

URL-encode the service parameter value.

The service parameter contains a full callback URL with protocol and slashes (e.g., https://server/_cas/token). Without encoding, certain CAS servers may misparse the query string. This could cause authentication failures.

🐛 Suggested fix
 export const onPressCas = ({ casLoginUrl, server }: { casLoginUrl: string; server: string }) => {
 	logEvent(events.ENTER_WITH_CAS);
 	const ssoToken = random(17);
-	const url = `${casLoginUrl}?service=${server}/_cas/${ssoToken}`;
+	const url = `${casLoginUrl}?service=${encodeURIComponent(`${server}/_cas/${ssoToken}`)}`;
 	openSSOSession(url, 'cas', ssoToken);
 };
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/containers/LoginServices/serviceLogin.ts` around lines 124 - 129, In the
onPressCas function, the `service` parameter is constructed with an unencoded
server URL value, which can cause parsing issues on certain CAS servers. To fix
this, apply URL encoding to the `server` variable when building the URL string
by wrapping it with encodeURIComponent() before inserting it into the query
string, so the full callback URL is properly escaped as a query parameter value.

@github-actions

Copy link
Copy Markdown

@github-actions

Copy link
Copy Markdown

iOS Build Available

Rocket.Chat 4.74.0.109173

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OAuth login with Webauthn not working in Webview

1 participant