Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
e6d588d
feat: react-native TokenStorage
jaredperreault-okta Mar 27, 2026
27027c4
linter fix
jaredperreault-okta Apr 30, 2026
4e7b7bd
DataStore backed Android TokenStorage
jaredperreault-okta May 4, 2026
bf47206
updates unit tests
jaredperreault-okta May 4, 2026
c6965bf
fixes unit tests in CI
jaredperreault-okta May 4, 2026
b3f9db5
CI fix
jaredperreault-okta May 4, 2026
4d26c87
ci fix
jaredperreault-okta May 4, 2026
7f64f7d
fixes tests
jaredperreault-okta May 4, 2026
f7bc9d4
test fix
jaredperreault-okta May 4, 2026
aeb029f
ci fix
jaredperreault-okta May 4, 2026
991af56
ci test fix
jaredperreault-okta May 4, 2026
1990106
ci fix
jaredperreault-okta May 4, 2026
1ebec2b
ci fix
jaredperreault-okta May 4, 2026
4193daf
ci fix
jaredperreault-okta May 4, 2026
bd632e5
ci fix
jaredperreault-okta May 4, 2026
a682a40
ci fix
jaredperreault-okta May 4, 2026
af05449
fixes tests finally
jaredperreault-okta May 4, 2026
d77e419
fix
jaredperreault-okta May 4, 2026
fa10b68
Android: uses TPM when available
jaredperreault-okta May 6, 2026
397053a
adds 3p notice files
jaredperreault-okta May 6, 2026
751256b
progress
jaredperreault-okta May 13, 2026
d24bdff
progress
jaredperreault-okta May 19, 2026
5d039e7
android e2e working
jaredperreault-okta May 20, 2026
e7c9870
ci fix
jaredperreault-okta May 20, 2026
ec8545b
ci fix
jaredperreault-okta May 20, 2026
68f3202
ci fix
jaredperreault-okta May 20, 2026
0016381
ci fix
jaredperreault-okta May 20, 2026
fd869b9
ci fix android
jaredperreault-okta May 20, 2026
d38e6c1
ci fix
jaredperreault-okta May 20, 2026
dd2405e
ci fix
jaredperreault-okta May 20, 2026
fcaa58f
ci fix
jaredperreault-okta May 20, 2026
ee59484
ci fix
jaredperreault-okta May 20, 2026
4db26c4
ci fix
jaredperreault-okta May 20, 2026
56349db
ci fix
jaredperreault-okta May 20, 2026
a64646e
ci fix
jaredperreault-okta May 20, 2026
76a6009
ci fix
jaredperreault-okta May 21, 2026
4add277
ci fix
jaredperreault-okta May 21, 2026
496db35
ci fix
jaredperreault-okta May 21, 2026
b99916b
ci fix
jaredperreault-okta May 21, 2026
171596d
ci fix
jaredperreault-okta May 21, 2026
ce2ad4e
ci fix
jaredperreault-okta May 21, 2026
1692baf
ci fix
jaredperreault-okta May 21, 2026
cbc98a2
ci fix
jaredperreault-okta May 21, 2026
1165ffd
ci fix
jaredperreault-okta May 21, 2026
781357e
ci fix
jaredperreault-okta May 21, 2026
cc55dc2
should actually fix ci
jaredperreault-okta May 21, 2026
cb6f233
fixes webcrypto ci
jaredperreault-okta May 21, 2026
a4168c9
fixes ci AND builds
jaredperreault-okta May 21, 2026
9767d42
working on ios and android
jaredperreault-okta May 22, 2026
61b7977
linter fix
jaredperreault-okta May 27, 2026
ee00495
linter fix
jaredperreault-okta May 27, 2026
0191a9e
add android instrumented tests for E2E app
FeiChen-okta Jun 4, 2026
5dd79d5
fixes cci
jaredperreault-okta Jun 4, 2026
ead65c7
working android build
jaredperreault-okta Jun 5, 2026
74a3d45
fixes cci
jaredperreault-okta Jun 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 82 additions & 8 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ executors:

macos:
macos:
xcode: "16.3"
xcode: 26.4.1
resource_class: m4pro.medium

jobs:
test-android:
test-rn-webcrypto-android:
executor:
name: android/android_machine
resource_class: large
Expand All @@ -34,10 +34,16 @@ jobs:
- gradle-

- run:
name: Run Android Unit and Integration Tests
name: Setup Node and install dependencies
command: |
cd packages/react-native-webcrypto-bridge/android
./gradlew testDebugUnitTest --info
npm i -g yarn@1.22.22
yarn install --frozen-lockfile

- run:
name: Run React Native Platform Android Tests
command: |
cd packages/react-native-platform/android
./gradlew testDebugUnitTest -PnewArchEnabled=true --info

- save_cache:
key: gradle-{{ checksum "packages/react-native-webcrypto-bridge/android/build.gradle" }}
Expand All @@ -52,7 +58,7 @@ jobs:
path: packages/react-native-webcrypto-bridge/android/build/reports
destination: android-test-reports

test-ios:
test-rn-webcrypto-ios:
executor: macos
steps:
- checkout
Expand Down Expand Up @@ -80,9 +86,77 @@ jobs:
path: packages/react-native-webcrypto-bridge/ios/.build
destination: ios-build-artifacts

test-rn-platform-android:
executor:
name: android/android_machine
resource_class: large
tag: default
steps:
- checkout

- restore_cache:
keys:
- gradle-rn-platform-{{ checksum "packages/react-native-platform/android/build.gradle" }}
- gradle-rn-platform-

- run:
name: Setup Node and install dependencies
command: |
npm i -g yarn@1.22.22
yarn install --frozen-lockfile

- run:
name: Run React Native Platform Android Tests
command: |
cd packages/react-native-platform/android
./gradlew testDebugUnitTest -PnewArchEnabled=true --info

- save_cache:
key: gradle-rn-platform-{{ checksum "packages/react-native-platform/android/build.gradle" }}
paths:
- ~/.gradle
- .gradle

- store_test_results:
path: packages/react-native-platform/android/build/test-results

- store_artifacts:
path: packages/react-native-platform/android/build/reports
destination: react-native-platform-android-test-reports

test-rn-platform-ios:
executor: macos
steps:
- checkout

- restore_cache:
keys:
- swift-spm-rn-platform-{{ checksum "packages/react-native-platform/ios/Package.swift" }}
- swift-spm-rn-platform-

- run:
name: Run React Native Platform iOS Tests
command: |
cd packages/react-native-platform/ios
swift test --verbose

- save_cache:
key: swift-spm-rn-platform-{{ checksum "packages/react-native-platform/ios/Package.swift" }}
paths:
- packages/react-native-platform/ios/.build

- store_test_results:
path: packages/react-native-platform/ios/.build/test-results

- store_artifacts:
path: packages/react-native-platform/ios/.build
destination: react-native-platform-ios-build-artifacts

workflows:
version: 2
build_and_test:
jobs:
- test-android
- test-ios
- test-rn-webcrypto-android
- test-rn-webcrypto-ios
- test-rn-platform-android
- test-rn-platform-ios
1 change: 0 additions & 1 deletion e2e/apps/react-native-oidc/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ dist/
web-build/
expo-env.d.ts
ios/
android/

# Native
.kotlin/
Expand Down
17 changes: 17 additions & 0 deletions e2e/apps/react-native-oidc/android/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# OSX
#
.DS_Store

# Android/IntelliJ
#
build/
.idea
.gradle
local.properties
*.iml
*.hprof
.cxx/

# Bundle artifacts
*.jsbundle
.claude/
188 changes: 188 additions & 0 deletions e2e/apps/react-native-oidc/android/app/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
apply plugin: "com.android.application"
apply plugin: "org.jetbrains.kotlin.android"
apply plugin: "com.facebook.react"

def projectRoot = rootDir.getAbsoluteFile().getParentFile().getAbsolutePath()

/**
* This is the configuration block to customize your React Native Android app.
* By default you don't need to apply any configuration, just uncomment the lines you need.
*/
react {
entryFile = file(["node", "-e", "require('expo/scripts/resolveAppEntry')", projectRoot, "android", "absolute"].execute(null, rootDir).text.trim())
reactNativeDir = new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim()).getParentFile().getAbsoluteFile()
hermesCommand = new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim()).getParentFile().getAbsolutePath() + "/sdks/hermesc/%OS-BIN%/hermesc"
codegenDir = new File(["node", "--print", "require.resolve('@react-native/codegen/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim()).getParentFile().getAbsoluteFile()

enableBundleCompression = (findProperty('android.enableBundleCompression') ?: false).toBoolean()
// Use Expo CLI to bundle the app, this ensures the Metro config
// works correctly with Expo projects.
cliFile = new File(["node", "--print", "require.resolve('@expo/cli', { paths: [require.resolve('expo/package.json')] })"].execute(null, rootDir).text.trim())
bundleCommand = "export:embed"

/* Folders */
// The root of your project, i.e. where "package.json" lives. Default is '../..'
// root = file("../../")
// The folder where the react-native NPM package is. Default is ../../node_modules/react-native
// reactNativeDir = file("../../node_modules/react-native")
// The folder where the react-native Codegen package is. Default is ../../node_modules/@react-native/codegen
// codegenDir = file("../../node_modules/@react-native/codegen")

/* Variants */
// The list of variants to that are debuggable. For those we're going to
// skip the bundling of the JS bundle and the assets. By default is just 'debug'.
// If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants.
// debuggableVariants = ["liteDebug", "prodDebug"]

/* Bundling */
// A list containing the node command and its flags. Default is just 'node'.
// nodeExecutableAndArgs = ["node"]

//
// The path to the CLI configuration file. Default is empty.
// bundleConfig = file(../rn-cli.config.js)
//
// The name of the generated asset file containing your JS bundle
// bundleAssetName = "MyApplication.android.bundle"
//
// The entry file for bundle generation. Default is 'index.android.js' or 'index.js'
// entryFile = file("../js/MyApplication.android.js")
//
// A list of extra flags to pass to the 'bundle' commands.
// See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle
// extraPackagerArgs = []

/* Hermes Commands */
// The hermes compiler command to run. By default it is 'hermesc'
// hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc"
//
// The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map"
// hermesFlags = ["-O", "-output-source-map"]

/* Autolinking */
autolinkLibrariesWithApp()
}

/**
* Set this to true in release builds to optimize the app using [R8](https://developer.android.com/topic/performance/app-optimization/enable-app-optimization).
*/
def enableMinifyInReleaseBuilds = (findProperty('android.enableMinifyInReleaseBuilds') ?: false).toBoolean()

/**
* The preferred build flavor of JavaScriptCore (JSC)
*
* For example, to use the international variant, you can use:
* `def jscFlavor = 'org.webkit:android-jsc-intl:+'`
*
* The international variant includes ICU i18n library and necessary data
* allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
* give correct results when using with locales other than en-US. Note that
* this variant is about 6MiB larger per architecture than default.
*/
def jscFlavor = 'io.github.react-native-community:jsc-android:2026004.+'

android {
ndkVersion rootProject.ext.ndkVersion

buildToolsVersion rootProject.ext.buildToolsVersion
compileSdk rootProject.ext.compileSdkVersion

namespace 'com.anonymous.reporeactnativeoidc'
defaultConfig {
applicationId 'com.anonymous.reporeactnativeoidc'
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 1
versionName "1.0.0"

buildConfigField "String", "REACT_NATIVE_RELEASE_LEVEL", "\"${findProperty('reactNativeReleaseLevel') ?: 'stable'}\""
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
signingConfigs {
debug {
storeFile file('debug.keystore')
storePassword 'android'
keyAlias 'androiddebugkey'
keyPassword 'android'
}
}
buildTypes {
debug {
signingConfig signingConfigs.debug
}
release {
// Caution! In production, you need to generate your own keystore file.
// see https://reactnative.dev/docs/signed-apk-android.
signingConfig signingConfigs.debug
def enableShrinkResources = findProperty('android.enableShrinkResourcesInReleaseBuilds') ?: 'false'
shrinkResources enableShrinkResources.toBoolean()
minifyEnabled enableMinifyInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
def enablePngCrunchInRelease = findProperty('android.enablePngCrunchInReleaseBuilds') ?: 'true'
crunchPngs enablePngCrunchInRelease.toBoolean()
}
}
packagingOptions {
jniLibs {
def enableLegacyPackaging = findProperty('expo.useLegacyPackaging') ?: 'false'
useLegacyPackaging enableLegacyPackaging.toBoolean()
}
}
androidResources {
ignoreAssetsPattern '!.svn:!.git:!.ds_store:!*.scc:!CVS:!thumbs.db:!picasa.ini:!*~'
}
}

// Apply static values from `gradle.properties` to the `android.packagingOptions`
// Accepts values in comma delimited lists, example:
// android.packagingOptions.pickFirsts=/LICENSE,**/picasa.ini
["pickFirsts", "excludes", "merges", "doNotStrip"].each { prop ->
// Split option: 'foo,bar' -> ['foo', 'bar']
def options = (findProperty("android.packagingOptions.$prop") ?: "").split(",");
// Trim all elements in place.
for (i in 0..<options.size()) options[i] = options[i].trim();
// `[] - ""` is essentially `[""].filter(Boolean)` removing all empty strings.
options -= ""

if (options.length > 0) {
println "android.packagingOptions.$prop += $options ($options.length)"
// Ex: android.packagingOptions.pickFirsts += '**/SCCS/**'
options.each {
android.packagingOptions[prop] += it
}
}
}

dependencies {
// The version of react-native is set by the React Native Gradle Plugin
implementation("com.facebook.react:react-android")

def isGifEnabled = (findProperty('expo.gif.enabled') ?: "") == "true";
def isWebpEnabled = (findProperty('expo.webp.enabled') ?: "") == "true";
def isWebpAnimatedEnabled = (findProperty('expo.webp.animated') ?: "") == "true";

if (isGifEnabled) {
// For animated gif support
implementation("com.facebook.fresco:animated-gif:${expoLibs.versions.fresco.get()}")
}

if (isWebpEnabled) {
// For webp support
implementation("com.facebook.fresco:webpsupport:${expoLibs.versions.fresco.get()}")
if (isWebpAnimatedEnabled) {
// Animated webp support
implementation("com.facebook.fresco:animated-webp:${expoLibs.versions.fresco.get()}")
}
}

if (hermesEnabled.toBoolean()) {
implementation("com.facebook.react:hermes-android")
} else {
implementation jscFlavor
}

androidTestImplementation("androidx.test.ext:junit:1.2.1")
androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")
androidTestImplementation("androidx.test:runner:1.6.2")
androidTestImplementation("androidx.test:rules:1.6.1")
}
Binary file not shown.
14 changes: 14 additions & 0 deletions e2e/apps/react-native-oidc/android/app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# react-native-reanimated
-keep class com.swmansion.reanimated.** { *; }
-keep class com.facebook.react.turbomodule.** { *; }

# Add any project specific keep options here:
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.anonymous.reporeactnativeoidc

import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Assert.assertNotNull
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class AppLaunchTest {

@get:Rule
val activityRule = ActivityScenarioRule(MainActivity::class.java)

@Test
fun mainActivity_LaunchesSuccessfully() {
activityRule.scenario.onActivity { activity ->
assertNotNull(activity)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

<application android:usesCleartextTraffic="true" tools:targetApi="28" tools:ignore="GoogleAppIndexingWarning" tools:replace="android:usesCleartextTraffic" />
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

<application android:usesCleartextTraffic="true" tools:targetApi="28" tools:ignore="GoogleAppIndexingWarning" tools:replace="android:usesCleartextTraffic" />
</manifest>
Loading