Skip to content

Conversation

@subhankarmaiti
Copy link
Contributor

Implements Native to Web SSO functionality enabling seamless authentication between native contexts and WebViews. Applications can obtain session transfer credentials from native SDKs to establish authenticated web sessions without re-authentication.

Usage

const { getSSOCredentials } = useAuth0();

const credentials = await getSSOCredentials();
// { sessionTransferToken, tokenType, expiresIn, idToken?, refreshToken? }

// With parameters
await getSSOCredentials(
  { audience: 'https://api.example.com' },
  { 'X-Custom-Header': 'value' }
);

@subhankarmaiti subhankarmaiti requested a review from a team as a code owner November 21, 2025 06:24
@subhankarmaiti subhankarmaiti changed the title feat: add getSSOCredentials method for Native to Web SSO support feat: add support for Native to Web SSO support Nov 21, 2025
@subhankarmaiti subhankarmaiti changed the title feat: add support for Native to Web SSO support feat: add support for Native to Web SSO Nov 21, 2025
@pmathew92
Copy link
Contributor

@claude

@github-actions
Copy link

github-actions bot commented Nov 21, 2025

Claude finished @pmathew92's task —— View job


Code Review Complete

  • Read PR diff and understand changes
  • Read AGENTS.md for project context (not found, proceeding with review)
  • Perform code quality review
  • Perform security review
  • Perform performance review
  • Provide inline feedback on specific issues
  • Post overall assessment

Overall Assessment

❌ This pull request requires fixes before it can be merged. A critical compilation error was identified in the Android implementation that will prevent the code from building, along with several type safety issues that could cause runtime failures.

Critical Issues:

  • Compilation Error: The Android implementation calls a non-existent method handleCredentialsManagerError (line 415)
  • Type Safety: Unsafe type casting in the Android implementation that will fail with ClassCastException if non-String values are passed in parameters or headers

Additional Issues:

  • Type definitions use overly permissive any types that bypass TypeScript's type safety
  • Test code contains empty catch blocks without explanatory comments
  • Unnecessary default value assignments that change function semantics
  • Minor code quality issues with unused parameters

The TypeScript/React implementation, iOS native implementation, and test coverage are well-structured. Once the critical Android issues are resolved, this will be a solid addition to the library.


val headerMap = headers?.toHashMap() ?: emptyMap()

secureCredentialsManager.getSSOCredentials(
params as Map<String, String>,

Choose a reason for hiding this comment

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

Type Safety Issue: Unsafe type casting without validation. The cast as Map<String, String> will fail at runtime if the HashMap contains non-String values.

The parameters and headers may contain non-String values (numbers, booleans, nested objects) that would cause a ClassCastException.

Suggested change
params as Map<String, String>,
val params = parameters?.toHashMap()?.mapValues { it.value?.toString() ?: "" } ?: emptyMap()
val headerMap = headers?.toHashMap()?.mapValues { it.value?.toString() ?: "" } ?: emptyMap()
secureCredentialsManager.getSSOCredentials(
params,
headerMap,

}

override fun onFailure(error: CredentialsManagerException) {
handleCredentialsManagerError(error, promise)

Choose a reason for hiding this comment

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

Error Handling Issue: The method handleCredentialsManagerError is called but doesn't exist in the codebase. This will cause a compilation error.

Looking at line 252, the correct method name is deduceErrorCode, which should be used along with manual error rejection:

Suggested change
handleCredentialsManagerError(error, promise)
override fun onFailure(error: CredentialsManagerException) {
val errorCode = deduceErrorCode(error)
promise.reject(errorCode, error.message, error)
}

}

async getSSOCredentials(
_parameters?: Record<string, any>,

Choose a reason for hiding this comment

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

Unused Parameters: The parameters are prefixed with underscore indicating they're intentionally unused, but they're still defined in the function signature. Consider using rest parameters or omitting the names entirely for cleaner code:

Suggested change
_parameters?: Record<string, any>,
async getSSOCredentials(): Promise<SessionTransferCredentials> {

* that can be used to authenticate in web contexts without requiring the user
* to log in again. The session transfer token can be passed as a cookie or
* query parameter to the `/authorize` endpoint to establish a web session.
*

Choose a reason for hiding this comment

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

Type Safety Issue: The parameters parameter allows Record<string, any> which is overly permissive and bypasses type safety. Consider defining a more specific type for parameters to prevent runtime errors:

parameters?: Record<string, string | number | boolean>

const handleGetSSOCredentials = async () => {
try {
const credentials = await getSSOCredentials();
setSSOCredentials(credentials);

Choose a reason for hiding this comment

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

Test Implementation Issue: Empty catch block silently swallows errors. The test should explicitly handle or verify error behavior:

Suggested change
setSSOCredentials(credentials);
try {
const credentials = await getSSOCredentials();
setSSOCredentials(credentials);
} catch (error) {
// Error will be dispatched to state, no action needed
}

if (error) {
return <Text testID="error">Error: {error.message}</Text>;
}

Choose a reason for hiding this comment

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

Test Implementation Issue: Empty catch block silently swallows errors. This pattern appears multiple times in the test file and should include at least a comment explaining why the error is ignored:

Suggested change
getSSOCredentials(parameters).catch(() => {
// Error will be dispatched to state
});

async getSSOCredentials(
parameters?: Record<string, any>,
headers?: Record<string, string>
): Promise<SessionTransferCredentials> {

Choose a reason for hiding this comment

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

Unnecessary Default Assignment: The nullish coalescing operator creates new empty objects when undefined is passed, which changes the function's semantics. The native modules should handle undefined parameters:

Suggested change
): Promise<SessionTransferCredentials> {
async getSSOCredentials(
parameters?: Record<string, any>,
headers?: Record<string, string>
): Promise<SessionTransferCredentials> {
return this.a0_call(
Auth0NativeModule.getSSOCredentials.bind(Auth0NativeModule),
parameters,
headers
);
}

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.

3 participants