Skip to content

feat: TokenStorage#24

Open
jaredperreault-okta wants to merge 20 commits into
jp-react-native-sdkfrom
jp-rn-tokenstorage
Open

feat: TokenStorage#24
jaredperreault-okta wants to merge 20 commits into
jp-react-native-sdkfrom
jp-rn-tokenstorage

Conversation

@jaredperreault-okta
Copy link
Copy Markdown
Contributor

@jaredperreault-okta jaredperreault-okta commented Mar 27, 2026

This includes changes from #23

The relevant commit(s) to this PR is

@jaredperreault-okta jaredperreault-okta force-pushed the jp-rn-tokenstorage branch 3 times, most recently from fb18b8d to 69b8d28 Compare April 30, 2026 15:05
@jaredperreault-okta jaredperreault-okta marked this pull request as ready for review April 30, 2026 15:06

import android.content.Context
import android.content.SharedPreferences
import androidx.security.crypto.EncryptedSharedPreferences
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

EncryptedSharedPreferences module is not supported anymore. It is using Google's tink library which has issues on various devices. We'll need to write our own by using the default encryption from the device to avoid all the bugs.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Does it make sense to use SharedPreferences or SQLlite as the backing store for this?

Comment on lines +149 to +151
// Request hardware-backed keystore if available
// Falls back to software keystore on devices without secure hardware
setIsStrongBoxBacked(false)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

this should be set to true. based on the comments. Also in keyGenerator.generateKey() you should wrap it in a try/catch. If it fails to generate a key try again with setIsStrongBoxBacked(false). Android does not have a way to check if the device has a TPM. so fallback has to be handled with a try/catch

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

What's this file used for?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I was having trouble getting things to compile when trying to export 2 bridges in the same library. This has been fixed in the follow up PR #31

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Same here

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I was having trouble getting things to compile when trying to export 2 bridges in the same library. This has been fixed in the follow up PR #31


@interface RCT_EXTERN_MODULE(BrowserSessionBridge, NSObject)

RCT_EXTERN_METHOD(launchBrowserSession:(NSString *)url
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

We may need to supply an argument indicating whether or not the user wants ephemeral sessions

Comment on lines +49 to +51
let webViewController = UIViewController()
let webView = WKWebView(frame: webViewController.view.bounds)
webView.load(URLRequest(url: urlObj))
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

We shouldn't use WKWebView. Instead, we need to use Apple's ASWebAuthenticationSession to perform the sign-in. The use of webviews for sign-in is considered an insecure practice.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This has been address in the follow-up #31

Comment on lines +53 to +58
try KeychainHelper.save(
service: Self.SERVICE_TOKENS,
key: id,
value: tokenData,
accessibility: kSecAttrAccessibleWhenUnlockedThisDeviceOnly
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

We should consider factoring the okta-mobile-swift Keychain utilities into a separate github package, and reusing them here. Something to consider for the future ...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We briefly discussed this a few months ago and we seemed to come to the conclusion the juice wasn't worth the squeeze. It can definitely be re-visited though

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This is good for a first pass, but we'll need a way for the developer to supply custom keychain access rules and biometric requirements. Apple provides a richer set of controls for when keychain items are accessible (e.g. when the device is locked, after first unlock, etc), as well as "access groups" (different apps / extensions can share keychain items), biometric options, etc.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ultimately this is a first pass at Storage for a beta release. There's definitely room for iteration and feature expansion

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