├── e2e ├── .gitattributes ├── ios │ ├── .xcode.env │ ├── E2EOktaReactNative │ │ ├── Images.xcassets │ │ │ ├── Contents.json │ │ │ ├── AppIcon.appiconset │ │ │ │ ├── 100.png │ │ │ │ ├── 1024.png │ │ │ │ ├── 114.png │ │ │ │ ├── 120.png │ │ │ │ ├── 144.png │ │ │ │ ├── 152.png │ │ │ │ ├── 167.png │ │ │ │ ├── 180.png │ │ │ │ ├── 20.png │ │ │ │ ├── 29.png │ │ │ │ ├── 40.png │ │ │ │ ├── 50.png │ │ │ │ ├── 57.png │ │ │ │ ├── 58.png │ │ │ │ ├── 60.png │ │ │ │ ├── 72.png │ │ │ │ ├── 76.png │ │ │ │ ├── 80.png │ │ │ │ ├── 87.png │ │ │ │ ├── App-Icon-1024x1024@1x.png │ │ │ │ └── Contents.json │ │ │ ├── SplashScreenLogo.imageset │ │ │ │ ├── image.png │ │ │ │ ├── image@2x.png │ │ │ │ ├── image@3x.png │ │ │ │ ├── dark_image.png │ │ │ │ ├── dark_image@2x.png │ │ │ │ ├── dark_image@3x.png │ │ │ │ └── Contents.json │ │ │ ├── SplashScreenBackground.imageset │ │ │ │ ├── image.png │ │ │ │ └── Contents.json │ │ │ └── SplashScreenBackground.colorset │ │ │ │ └── Contents.json │ │ ├── noop-file.swift │ │ ├── E2EOktaReactNative-Bridging-Header.h │ │ ├── E2EOktaReactNative.entitlements │ │ ├── Supporting │ │ │ └── Expo.plist │ │ ├── AppDelegate.h │ │ ├── main.m │ │ ├── PrivacyInfo.xcprivacy │ │ ├── Info.plist │ │ ├── AppDelegate.mm │ │ ├── SplashScreen.storyboard │ │ └── Base.lproj │ │ │ └── LaunchScreen.xib │ ├── Podfile.properties.json │ ├── .gitignore │ ├── E2EOktaReactNative-Bridging-Header.h │ ├── Dummy.swift │ ├── E2EOktaReactNativeUITests │ │ ├── Info.plist │ │ ├── ABColdStartTests.swift │ │ ├── LoginTests.swift │ │ ├── CustomLoginTests.swift │ │ └── BrowserLoginTests.swift │ ├── Podfile │ └── E2EOktaReactNative.xcodeproj │ │ └── xcshareddata │ │ └── xcschemes │ │ └── E2EOktaReactNative.xcscheme ├── app_logo.png ├── android │ ├── app │ │ ├── debug.keystore │ │ ├── src │ │ │ ├── main │ │ │ │ ├── res │ │ │ │ │ ├── values-night │ │ │ │ │ │ └── colors.xml │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ │ ├── ic_launcher.webp │ │ │ │ │ │ └── ic_launcher_round.webp │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ │ ├── ic_launcher.webp │ │ │ │ │ │ └── ic_launcher_round.webp │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ │ ├── ic_launcher.webp │ │ │ │ │ │ └── ic_launcher_round.webp │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ │ ├── ic_launcher.webp │ │ │ │ │ │ └── ic_launcher_round.webp │ │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ │ ├── ic_launcher.webp │ │ │ │ │ │ └── ic_launcher_round.webp │ │ │ │ │ ├── drawable-hdpi │ │ │ │ │ │ └── splashscreen_logo.png │ │ │ │ │ ├── drawable-mdpi │ │ │ │ │ │ └── splashscreen_logo.png │ │ │ │ │ ├── drawable-xhdpi │ │ │ │ │ │ └── splashscreen_logo.png │ │ │ │ │ ├── drawable-xxhdpi │ │ │ │ │ │ └── splashscreen_logo.png │ │ │ │ │ ├── drawable-xxxhdpi │ │ │ │ │ │ └── splashscreen_logo.png │ │ │ │ │ ├── drawable-night-hdpi │ │ │ │ │ │ └── splashscreen_logo.png │ │ │ │ │ ├── drawable-night-mdpi │ │ │ │ │ │ └── splashscreen_logo.png │ │ │ │ │ ├── drawable-night-xhdpi │ │ │ │ │ │ └── splashscreen_logo.png │ │ │ │ │ ├── drawable-night-xxhdpi │ │ │ │ │ │ └── splashscreen_logo.png │ │ │ │ │ ├── drawable-night-xxxhdpi │ │ │ │ │ │ └── splashscreen_logo.png │ │ │ │ │ ├── values │ │ │ │ │ │ ├── colors.xml │ │ │ │ │ │ ├── strings.xml │ │ │ │ │ │ └── styles.xml │ │ │ │ │ └── drawable │ │ │ │ │ │ ├── ic_launcher_background.xml │ │ │ │ │ │ └── rn_edit_text_material.xml │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java │ │ │ │ │ └── com │ │ │ │ │ └── e2eoktareactnative │ │ │ │ │ ├── MainApplication.kt │ │ │ │ │ └── MainActivity.kt │ │ │ ├── debug │ │ │ │ └── AndroidManifest.xml │ │ │ └── androidTest │ │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── e2eoktareactnative │ │ │ │ ├── test │ │ │ │ ├── AdbUtil.kt │ │ │ │ ├── EndToEndCredentials.kt │ │ │ │ └── UiAutomationHelpers.kt │ │ │ │ ├── dashboard │ │ │ │ └── DashboardPage.kt │ │ │ │ ├── login │ │ │ │ ├── LoginPage.kt │ │ │ │ ├── CustomLoginTest.kt │ │ │ │ └── BrowserLoginTest.kt │ │ │ │ ├── customlogin │ │ │ │ └── CustomLoginPage.kt │ │ │ │ └── web │ │ │ │ └── WebPage.kt │ │ └── proguard-rules.pro │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── .gitignore │ ├── runTestsInFirebaseTestLab.sh │ ├── licenseTemplate.txt │ ├── forceVersions.gradle │ ├── settings.gradle │ ├── build.gradle │ ├── gradle.properties │ └── gradlew.bat ├── app.json ├── metro.config.js ├── index.js ├── babel.config.js ├── package.json ├── config.js ├── App.js └── pages │ ├── ProfilePage.js │ ├── CustomLogin.js │ └── Home.js ├── ios ├── .xcode.env ├── Podfile ├── Tests │ ├── Info.plist │ ├── Mocks │ │ ├── OktaSdkBridgeMock.swift │ │ ├── OktaOidcStateManagerMock.swift │ │ ├── OktaOidcMock.swift │ │ └── OktaOidcStateManager+Factory.swift │ ├── OktaSdkConstantTests.swift │ └── OktaReactNativeErrorTests.swift ├── OktaSdkBridge │ ├── ReactNativeOktaSdkBridge-Bridging-Header.h │ ├── OktaSdkConstant.swift │ ├── OktaSDKError.swift │ └── ReactNativeOktaSdkBridge.m └── ReactNativeOktaSdkBridge.xcodeproj │ └── xcshareddata │ └── xcschemes │ └── ReactNativeOktaSdkBridge.xcscheme ├── .gitattributes ├── .circleci ├── android_sdk_checksum └── config.yml ├── android ├── src │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── com │ │ └── oktareactnative │ │ ├── OktaSdkBridgePackage.java │ │ ├── OktaSdkError.java │ │ ├── OktaSdkConstant.java │ │ └── HttpClientImpl.java ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── forceVersions.gradle ├── gradle.properties ├── gradlew.bat └── build.gradle ├── types ├── tslint.json ├── tsconfig.json ├── index.test-d.ts └── index.d.ts ├── babel.config.js ├── scripts ├── sast_scan.sh ├── lint.sh ├── unit.sh ├── snyk.sh ├── publish.sh ├── setup.sh └── build.js ├── .github ├── ISSUE_TEMPLATE │ ├── config.yml │ ├── feature-request.yml │ └── bug-report.yml ├── SECURITY.md ├── PULL_REQUEST_TEMPLATE │ └── PULL_REQUEST_TEMPLATE.md └── workflows │ └── composite │ └── configure-node │ └── action.yml ├── jsconfig.json ├── .vscode └── launch.json ├── setupJest.js ├── OktaSdkBridgeReactNative.podspec ├── .gitignore ├── .bacon.yml ├── .eslintrc.js ├── CONTRIBUTING.md └── package.json /e2e/.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | -------------------------------------------------------------------------------- /ios/.xcode.env: -------------------------------------------------------------------------------- 1 | export NODE_BINARY=$(command -v node) 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.cjs filter=lfs diff=lfs merge=lfs -text 2 | -------------------------------------------------------------------------------- /e2e/ios/.xcode.env: -------------------------------------------------------------------------------- 1 | export NODE_BINARY=$(command -v node) 2 | -------------------------------------------------------------------------------- /e2e/app_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/app_logo.png -------------------------------------------------------------------------------- /e2e/android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/android/app/debug.keystore -------------------------------------------------------------------------------- /.circleci/android_sdk_checksum: -------------------------------------------------------------------------------- 1 | 2d2d50857e4eb553af5a6dc3ad507a17adf43d115264b1afc116f95c92e5e258 android-commandline.zip 2 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /types/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "dtslint/dtslint.json", 3 | "rules": { 4 | "no-useless-files": false 5 | } 6 | } -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /e2e/android/app/src/main/res/values-night/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | #000000 3 | -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "expo" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /e2e/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /e2e/ios/Podfile.properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo.jsEngine": "hermes", 3 | "EX_DEV_CLIENT_NETWORK_INSPECTOR": "true", 4 | "newArchEnabled": "false" 5 | } 6 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:metro-react-native-babel-preset'], 3 | plugins: ['@babel/plugin-transform-async-to-generator'] 4 | }; 5 | -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/noop-file.swift: -------------------------------------------------------------------------------- 1 | // 2 | // @generated 3 | // A blank Swift file must be created for native modules with Swift files to work correctly. 4 | // -------------------------------------------------------------------------------- /scripts/sast_scan.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd ${OKTA_HOME}/${REPO} 4 | 5 | if ! sast_scan; 6 | then 7 | exit ${FAILURE} 8 | fi 9 | 10 | exit ${SUCCESS} 11 | -------------------------------------------------------------------------------- /e2e/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /e2e/android/app/src/main/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/android/app/src/main/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /e2e/android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /e2e/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /e2e/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/E2EOktaReactNative-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | -------------------------------------------------------------------------------- /e2e/android/app/src/main/res/drawable-hdpi/splashscreen_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/android/app/src/main/res/drawable-hdpi/splashscreen_logo.png -------------------------------------------------------------------------------- /e2e/android/app/src/main/res/drawable-mdpi/splashscreen_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/android/app/src/main/res/drawable-mdpi/splashscreen_logo.png -------------------------------------------------------------------------------- /e2e/android/app/src/main/res/drawable-xhdpi/splashscreen_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/android/app/src/main/res/drawable-xhdpi/splashscreen_logo.png -------------------------------------------------------------------------------- /e2e/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /e2e/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /e2e/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /e2e/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /e2e/android/app/src/main/res/drawable-xxhdpi/splashscreen_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/android/app/src/main/res/drawable-xxhdpi/splashscreen_logo.png -------------------------------------------------------------------------------- /e2e/android/app/src/main/res/drawable-xxxhdpi/splashscreen_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/android/app/src/main/res/drawable-xxxhdpi/splashscreen_logo.png -------------------------------------------------------------------------------- /e2e/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /e2e/android/app/src/main/res/drawable-night-hdpi/splashscreen_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/android/app/src/main/res/drawable-night-hdpi/splashscreen_logo.png -------------------------------------------------------------------------------- /e2e/android/app/src/main/res/drawable-night-mdpi/splashscreen_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/android/app/src/main/res/drawable-night-mdpi/splashscreen_logo.png -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/100.png -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/1024.png -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/114.png -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/120.png -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/144.png -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/152.png -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/167.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/167.png -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/180.png -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/20.png -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/29.png -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/40.png -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/50.png -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/57.png -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/58.png -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/60.png -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/72.png -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/76.png -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/80.png -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/87.png -------------------------------------------------------------------------------- /e2e/android/app/src/main/res/drawable-night-xhdpi/splashscreen_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/android/app/src/main/res/drawable-night-xhdpi/splashscreen_logo.png -------------------------------------------------------------------------------- /e2e/android/app/src/main/res/drawable-night-xxhdpi/splashscreen_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/android/app/src/main/res/drawable-night-xxhdpi/splashscreen_logo.png -------------------------------------------------------------------------------- /e2e/android/app/src/main/res/drawable-night-xxxhdpi/splashscreen_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/android/app/src/main/res/drawable-night-xxxhdpi/splashscreen_logo.png -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/Images.xcassets/SplashScreenLogo.imageset/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/ios/E2EOktaReactNative/Images.xcassets/SplashScreenLogo.imageset/image.png -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/Images.xcassets/SplashScreenLogo.imageset/image@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/ios/E2EOktaReactNative/Images.xcassets/SplashScreenLogo.imageset/image@2x.png -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/Images.xcassets/SplashScreenLogo.imageset/image@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/ios/E2EOktaReactNative/Images.xcassets/SplashScreenLogo.imageset/image@3x.png -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/Images.xcassets/SplashScreenBackground.imageset/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/ios/E2EOktaReactNative/Images.xcassets/SplashScreenBackground.imageset/image.png -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/Images.xcassets/SplashScreenLogo.imageset/dark_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/ios/E2EOktaReactNative/Images.xcassets/SplashScreenLogo.imageset/dark_image.png -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | contact_links: 2 | - name: Developer Forum 3 | url: https://devforum.okta.com/ 4 | about: Get help with building your application on the Okta Platform. 5 | blank_issues_enabled: false 6 | -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/App-Icon-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/App-Icon-1024x1024@1x.png -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/Images.xcassets/SplashScreenLogo.imageset/dark_image@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/ios/E2EOktaReactNative/Images.xcassets/SplashScreenLogo.imageset/dark_image@2x.png -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/Images.xcassets/SplashScreenLogo.imageset/dark_image@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/okta-react-native/HEAD/e2e/ios/E2EOktaReactNative/Images.xcassets/SplashScreenLogo.imageset/dark_image@3x.png -------------------------------------------------------------------------------- /e2e/android/app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | #ffffff 3 | #023c69 4 | #ffffff 5 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES6" 4 | }, 5 | "typeAcquisition": { 6 | "include": [ 7 | "jest" 8 | ], 9 | }, 10 | "exclude": [ 11 | "node_modules", 12 | ] 13 | } -------------------------------------------------------------------------------- /.github/SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Report a Vulnerability 4 | At Okta we take the protection of our customers’ data very seriously. If you need to report a vulnerability, please visit https://www.okta.com/vulnerability-reporting-policy/ for more information. 5 | -------------------------------------------------------------------------------- /e2e/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | E2E-Okta-React-Native 3 | contain 4 | false 5 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-all.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /e2e/android/app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /e2e/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /e2e/android/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Android/IntelliJ 6 | # 7 | build/ 8 | .idea 9 | .gradle 10 | local.properties 11 | *.iml 12 | *.hprof 13 | .cxx/ 14 | 15 | # Bundle artifacts 16 | *.jsbundle 17 | index.android.bundle 18 | 19 | # E2E credentials 20 | e2eCredentials.properties 21 | okta.properties 22 | -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/E2EOktaReactNative.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | aps-environment 6 | development 7 | 8 | -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "filename": "App-Icon-1024x1024@1x.png", 5 | "idiom": "universal", 6 | "platform": "ios", 7 | "size": "1024x1024" 8 | } 9 | ], 10 | "info": { 11 | "version": 1, 12 | "author": "expo" 13 | } 14 | } -------------------------------------------------------------------------------- /e2e/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/Supporting/Expo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | EXUpdatesCheckOnLaunch 6 | ALWAYS 7 | EXUpdatesEnabled 8 | 9 | EXUpdatesLaunchWaitMs 10 | 0 11 | 12 | -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/Images.xcassets/SplashScreenBackground.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "idiom": "universal", 5 | "filename": "image.png", 6 | "scale": "1x" 7 | }, 8 | { 9 | "idiom": "universal", 10 | "scale": "2x" 11 | }, 12 | { 13 | "idiom": "universal", 14 | "scale": "3x" 15 | } 16 | ], 17 | "info": { 18 | "version": 1, 19 | "author": "expo" 20 | } 21 | } -------------------------------------------------------------------------------- /e2e/ios/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | project.xcworkspace 24 | .xcode.env.local 25 | 26 | # Bundle artifacts 27 | *.jsbundle 28 | 29 | # CocoaPods 30 | /Pods/ 31 | -------------------------------------------------------------------------------- /scripts/lint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source ${OKTA_HOME}/${REPO}/scripts/setup.sh 4 | 5 | export TEST_SUITE_TYPE="checkstyle" 6 | export TEST_RESULT_FILE_DIR="${REPO}/test-reports" 7 | 8 | if ! yarn lint:report; then 9 | echo "lint failed! Exiting..." 10 | exit ${TEST_FAILURE} 11 | fi 12 | 13 | echo ${TEST_SUITE_TYPE} > ${TEST_SUITE_TYPE_FILE} 14 | echo ${TEST_RESULT_FILE_DIR} > ${TEST_RESULT_FILE_DIR_FILE} 15 | exit ${PUBLISH_TYPE_AND_RESULT_DIR_BUT_SUCCEED_IF_NO_RESULTS} 16 | -------------------------------------------------------------------------------- /scripts/unit.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source ${OKTA_HOME}/${REPO}/scripts/setup.sh 4 | 5 | export TEST_SUITE_TYPE="junit" 6 | export TEST_RESULT_FILE_DIR="${REPO}/test-reports/unit" 7 | 8 | # Run jest with "ci" flag 9 | if ! yarn test --ci; then 10 | echo "unit failed! Exiting..." 11 | exit ${TEST_FAILURE} 12 | fi 13 | 14 | echo ${TEST_SUITE_TYPE} > ${TEST_SUITE_TYPE_FILE} 15 | echo ${TEST_RESULT_FILE_DIR} > ${TEST_RESULT_FILE_DIR_FILE} 16 | exit ${PUBLISH_TYPE_AND_RESULT_DIR} 17 | -------------------------------------------------------------------------------- /android/forceVersions.gradle: -------------------------------------------------------------------------------- 1 | def forceVersions(ConfigurationContainer configurations) { 2 | configurations.configureEach { configuration -> 3 | configuration.resolutionStrategy { 4 | force 'org.bouncycastle:bcprov-jdk18on:1.78.1' 5 | force 'io.netty:netty-handler:4.1.125.Final' 6 | force 'io.netty:netty-codec-http:4.1.125.Final' 7 | force 'io.netty:netty-codec-http2:4.1.125.Final' 8 | force 'com.google.protobuf:protobuf-java:4.29.3' 9 | } 10 | } 11 | } 12 | 13 | ext.forceVersions = this.&forceVersions 14 | -------------------------------------------------------------------------------- /ios/Podfile: -------------------------------------------------------------------------------- 1 | # Resolve react_native_pods.rb with node to allow for hoisting 2 | require Pod::Executable.execute_command('node', ['-p', 3 | 'require.resolve( 4 | "react-native/scripts/react_native_pods.rb", 5 | {paths: [process.argv[1]]}, 6 | )', __dir__]).strip 7 | 8 | platform :ios, min_ios_version_supported 9 | prepare_react_native_project! 10 | 11 | def shared_pods 12 | use_react_native!(:hermes_enabled => false) 13 | pod 'OktaOidc' 14 | end 15 | 16 | target 'ReactNativeOktaSdkBridge' do 17 | shared_pods 18 | end 19 | 20 | target 'Tests' do 21 | shared_pods 22 | end 23 | -------------------------------------------------------------------------------- /e2e/android/runTestsInFirebaseTestLab.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e # Fail on error. 4 | 5 | gcloud firebase test android run \ 6 | --no-auto-google-login \ 7 | --type instrumentation \ 8 | --app app/build/outputs/apk/debug/app-debug.apk \ 9 | --test app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk \ 10 | --device model=oriole,version=32,locale=en_US,orientation=portrait \ 11 | --timeout 5m --no-performance-metrics \ 12 | --use-orchestrator \ 13 | --environment-variables clearPackageData=true \ 14 | & PID_APP=$! 15 | 16 | wait $PID_APP 17 | -------------------------------------------------------------------------------- /e2e/android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # react-native-reanimated 11 | -keep class com.swmansion.reanimated.** { *; } 12 | -keep class com.facebook.react.turbomodule.** { *; } 13 | 14 | # Add any project specific keep options here: 15 | -------------------------------------------------------------------------------- /e2e/android/licenseTemplate.txt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright $YEAR-Present Okta, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021-Present, Okta, Inc. and/or its affiliates. All rights reserved. 3 | * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.") 4 | * 5 | * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. 6 | * Unless required by applicable law or agreed to in writing, software 7 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 8 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 | * 10 | * See the License for the specific language governing permissions and limitations under the License. 11 | */ 12 | -------------------------------------------------------------------------------- /scripts/snyk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # When packages change their dependency tree, we want to run snyk monitor. This 4 | # sends the updated dependency tree to snyk for monitoring. We want to do this 5 | # when a commit has been made to master, not on PRs because the dependency tree 6 | # is likely still in flux while review is happening. 7 | # 8 | # For simplicity, this script just runs snyk monitor against all packages on 9 | # master commits, it doesn't try to figure out which packages were updated. 10 | 11 | if [[ "$TRAVIS_BRANCH" == "master" && "$TRAVIS_PULL_REQUEST" == "false" ]]; then 12 | yarn global add snyk 13 | snyk auth $SNYK_API_TOKEN 14 | echo "snyk monitor --org=$SNYK_ORG_ID" 15 | fi 16 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "node", 9 | "name": "Tests", 10 | "request": "launch", 11 | "program": "${workspaceFolder}/node_modules/jest/bin/jest", 12 | "args": [ 13 | "--runInBand" 14 | ], 15 | "cwd": "${workspaceFolder}", 16 | "console": "integratedTerminal", 17 | "internalConsoleOptions": "neverOpen", 18 | "disableOptimisticBPs": true 19 | } 20 | ] 21 | } -------------------------------------------------------------------------------- /e2e/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "E2E-Okta-React-Native", 4 | "slug": "E2E-Okta-React-Native", 5 | "version": "1.0.0", 6 | "assetBundlePatterns": [ 7 | "**/*" 8 | ], 9 | "android": { 10 | "package": "com.e2eoktareactnative" 11 | }, 12 | "ios": { 13 | "bundleIdentifier": "com.e2eoktareactnative" 14 | }, 15 | "plugins": [ 16 | [ 17 | "expo-splash-screen", 18 | { 19 | "backgroundColor": "#ffffff", 20 | "image": "./app_logo.png", 21 | "dark": { 22 | "image": "./app_logo.png", 23 | "backgroundColor": "#000000" 24 | }, 25 | "imageWidth": 200 26 | } 27 | ] 28 | ] 29 | }, 30 | "name": "E2E-Okta-React-Native" 31 | } 32 | -------------------------------------------------------------------------------- /e2e/ios/Dummy.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021-Present, Okta, Inc. and/or its affiliates. All rights reserved. 3 | * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.") 4 | * 5 | * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. 6 | * Unless required by applicable law or agreed to in writing, software 7 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 8 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 | * 10 | * See the License for the specific language governing permissions and limitations under the License. 11 | */ 12 | 13 | // This is a dummy file to compile CocoaPods and tests. Because React Native project is created as Obj-C project. 14 | -------------------------------------------------------------------------------- /types/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "lib": [ 5 | "es6" 6 | ], 7 | "noEmit": true, 8 | "strict": true, 9 | "alwaysStrict": true, 10 | "noUnusedParameters": true, 11 | "noImplicitReturns": true, 12 | "noFallthroughCasesInSwitch": true, 13 | "allowJs": true, 14 | "allowSyntheticDefaultImports": true, 15 | "esModuleInterop": true, 16 | "isolatedModules": true, 17 | "jsx": "react-native", 18 | "moduleResolution": "node", 19 | "target": "esnext", 20 | "baseUrl": "./", 21 | "paths": { 22 | "OktaSDK": [ 23 | "../" 24 | ] 25 | } 26 | }, 27 | "exclude": [ 28 | "node_modules", 29 | "babel.config.js", 30 | "metro.config.js", 31 | "jest.config.js" 32 | ] 33 | } -------------------------------------------------------------------------------- /ios/Tests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /setupJest.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Okta, Inc. and/or its affiliates. All rights reserved. 3 | * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.") 4 | * 5 | * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. 6 | * Unless required by applicable law or agreed to in writing, software 7 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 8 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 | * 10 | * See the License for the specific language governing permissions and limitations under the License. 11 | */ 12 | global.XMLHttpRequest = jest.fn(); 13 | global.fetch = jest.fn(); 14 | 15 | if (typeof window !== 'object') { 16 | global.window = global; 17 | global.window.navigator = {}; 18 | } -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNativeUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/AppDelegate.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021-Present, Okta, Inc. and/or its affiliates. All rights reserved. 3 | * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.") 4 | * 5 | * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. 6 | * Unless required by applicable law or agreed to in writing, software 7 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 8 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 | * 10 | * See the License for the specific language governing permissions and limitations under the License. 11 | */ 12 | 13 | #import 14 | #import 15 | #import 16 | 17 | @interface AppDelegate : EXAppDelegateWrapper 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /ios/OktaSdkBridge/ReactNativeOktaSdkBridge-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-Present, Okta, Inc. and/or its affiliates. All rights reserved. 3 | * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.") 4 | * 5 | * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. 6 | * Unless required by applicable law or agreed to in writing, software 7 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 8 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 | * 10 | * See the License for the specific language governing permissions and limitations under the License. 11 | */ 12 | 13 | #import 14 | #import 15 | #import 16 | #import 17 | 18 | -------------------------------------------------------------------------------- /OktaSdkBridgeReactNative.podspec: -------------------------------------------------------------------------------- 1 | require "json" 2 | 3 | package = JSON.parse(File.read(File.join(__dir__, "package.json"))) 4 | version = package['version'] 5 | source = { :git => 'https://github.com/okta/okta-react-native.git' } 6 | source[:tag] = "@okta/okta-react-native@#{version}" 7 | 8 | Pod::Spec.new do |s| 9 | s.name = package['podname'] 10 | s.version = version 11 | s.summary = package['description'] 12 | s.license = package['license'] 13 | 14 | s.authors = package['author'] 15 | s.homepage = package['homepage'] 16 | s.platform = :ios, '12.4' 17 | s.swift_version = '5.0' 18 | 19 | s.source = source 20 | s.source_files = 'ios/OktaSdkBridge/**/*.{h,m,swift}', 'packages/okta-react-native/ios/OktaSdkBridge/**/*.{h,m,swift}' 21 | 22 | s.dependency 'React' 23 | s.dependency 'OktaOidc', '3.11.7' 24 | end 25 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | org.gradle.jvmargs=-Xmx2048m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | android.useAndroidX=true 19 | android.enableJetifier=true 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /test-reports 3 | /dist 4 | node_modules 5 | npm-debug.log 6 | yarn-error.* 7 | .env 8 | *.hprof 9 | .idea/ 10 | .yarn/install-state.gz 11 | e2e/.yarn/install-state.gz 12 | 13 | .watchmanconfig 14 | 15 | .vscode 16 | !.vscode/launch.json 17 | 18 | # Expo 19 | .expo/ 20 | web-build/ 21 | 22 | # Android/iOS related for react native 23 | .gradle/ 24 | build/ 25 | local.properties 26 | *.iml 27 | xcuserdata/ 28 | e2e/ios/main.jsbundle 29 | e2e/android/app/src/main/java/com/e2eoktareactnative/generated/ 30 | 31 | # General 32 | *.swp 33 | *.swo 34 | *.rbo 35 | *.gem 36 | .DS_Store 37 | .rbenv-version 38 | xcuserdata 39 | *.xcworkspace/ 40 | ReactNativeOktaSdkBridge.xcworkspace 41 | DerivedData 42 | /.build 43 | 44 | # Xcode 45 | *.xccheckout 46 | 47 | ## Obj-C/Swift specific 48 | *.hmap 49 | 50 | ## App packaging 51 | *.ipa 52 | *.dSYM.zip 53 | *.dSYM 54 | 55 | # CocoaPods 56 | Pods/ 57 | -------------------------------------------------------------------------------- /e2e/metro.config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021-Present, Okta, Inc. and/or its affiliates. All rights reserved. 3 | * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.") 4 | * 5 | * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. 6 | * Unless required by applicable law or agreed to in writing, software 7 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 8 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 | * 10 | * See the License for the specific language governing permissions and limitations under the License. 11 | */ 12 | 13 | /* eslint-disable node/no-missing-import */ 14 | 15 | // Learn more https://docs.expo.io/guides/customizing-metro 16 | const { getDefaultConfig } = require('expo/metro-config'); 17 | 18 | module.exports = getDefaultConfig(__dirname); 19 | -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/main.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021-Present, Okta, Inc. and/or its affiliates. All rights reserved. 3 | * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.") 4 | * 5 | * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. 6 | * Unless required by applicable law or agreed to in writing, software 7 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 8 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 | * 10 | * See the License for the specific language governing permissions and limitations under the License. 11 | */ 12 | 13 | #import 14 | 15 | #import "AppDelegate.h" 16 | 17 | int main(int argc, char * argv[]) { 18 | @autoreleasepool { 19 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /scripts/publish.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source $OKTA_HOME/$REPO/scripts/setup.sh 4 | 5 | export TEST_SUITE_TYPE="build" 6 | export REGISTRY="${ARTIFACTORY_URL}/api/npm/npm-topic" 7 | 8 | # Install required dependencies 9 | export PATH="${PATH}:$(yarn global bin)" 10 | yarn global add @okta/ci-append-sha 11 | 12 | if [ -n "${action_branch}" ]; 13 | then 14 | echo "Publishing from bacon task using branch ${action_branch}" 15 | TARGET_BRANCH=${action_branch} 16 | else 17 | echo "Publishing from bacon testSuite using branch ${BRANCH}" 18 | TARGET_BRANCH=${BRANCH} 19 | fi 20 | 21 | pushd ./dist 22 | 23 | if ! ci-append-sha; then 24 | echo "ci-append-sha failed! Exiting..." 25 | exit ${FAILED_SETUP} 26 | fi 27 | 28 | npm config set @okta:registry ${REGISTRY} 29 | if ! npm publish --registry ${REGISTRY}; then 30 | echo "npm publish failed! Exiting..." 31 | exit ${PUBLISH_ARTIFACTORY_FAILURE} 32 | fi 33 | 34 | popd 35 | 36 | exit $SUCCESS 37 | -------------------------------------------------------------------------------- /e2e/android/app/src/androidTest/java/com/e2eoktareactnative/test/AdbUtil.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023-Present Okta, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.e2eoktareactnative.test 17 | 18 | import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation 19 | 20 | fun execShellCommand(cmd: String) { 21 | getInstrumentation().uiAutomation.executeShellCommand(cmd).close() 22 | } 23 | -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/Images.xcassets/SplashScreenBackground.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors": [ 3 | { 4 | "color": { 5 | "components": { 6 | "alpha": "1.000", 7 | "blue": "1.00000000000000", 8 | "green": "1.00000000000000", 9 | "red": "1.00000000000000" 10 | }, 11 | "color-space": "srgb" 12 | }, 13 | "idiom": "universal" 14 | }, 15 | { 16 | "color": { 17 | "components": { 18 | "alpha": "1.000", 19 | "blue": "0.00000000000000", 20 | "green": "0.00000000000000", 21 | "red": "0.00000000000000" 22 | }, 23 | "color-space": "srgb" 24 | }, 25 | "idiom": "universal", 26 | "appearances": [ 27 | { 28 | "appearance": "luminosity", 29 | "value": "dark" 30 | } 31 | ] 32 | } 33 | ], 34 | "info": { 35 | "version": 1, 36 | "author": "expo" 37 | } 38 | } -------------------------------------------------------------------------------- /.bacon.yml: -------------------------------------------------------------------------------- 1 | test_suites: 2 | - name: lint 3 | script_path: /root/okta/okta-react-native/scripts 4 | sort_order: '1' 5 | timeout: '60' 6 | script_name: lint 7 | criteria: MERGE 8 | queue_name: ci-queue-productionJenga-AL2023 9 | - name: unit 10 | script_path: /root/okta/okta-react-native/scripts 11 | sort_order: '2' 12 | timeout: '10' 13 | script_name: unit 14 | criteria: MERGE 15 | queue_name: ci-queue-productionJenga-AL2023 16 | - name: publish 17 | script_path: /root/okta/okta-react-native/scripts 18 | sort_order: '3' 19 | timeout: '60' 20 | script_name: publish 21 | criteria: MERGE 22 | queue_name: ci-queue-productionJenga-AL2023 23 | - name: sast_scan 24 | script_path: /root/okta/okta-react-native/scripts 25 | script_name: sast_scan 26 | sort_order: '4' 27 | timeout: '200' 28 | criteria: MERGE 29 | queue_name: small 30 | trigger: AUTO 31 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature-request.yml: -------------------------------------------------------------------------------- 1 | name: Feature Request 2 | description: Request a new feature for this SDK? 3 | labels: [ enhancement ] 4 | body: 5 | - type: textarea 6 | id: description 7 | attributes: 8 | label: Describe the feature request? 9 | description: | 10 | Please leave a helpful description of the feature request here. 11 | validations: 12 | required: true 13 | 14 | - type: textarea 15 | id: resources 16 | attributes: 17 | label: New or Affected Resource(s) 18 | description: | 19 | Please list the new or affected resources 20 | validations: 21 | required: true 22 | 23 | - type: textarea 24 | id: documentation 25 | attributes: 26 | label: Provide a documentation link 27 | description: | 28 | Please provide any links to the documentation that is at 29 | https://developer.okta.com/. This will help us with this 30 | feature request. 31 | 32 | - type: textarea 33 | id: additional 34 | attributes: 35 | label: Additional Information? 36 | -------------------------------------------------------------------------------- /e2e/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021-Present, Okta, Inc. and/or its affiliates. All rights reserved. 3 | * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.") 4 | * 5 | * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. 6 | * Unless required by applicable law or agreed to in writing, software 7 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 8 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 | * 10 | * See the License for the specific language governing permissions and limitations under the License. 11 | */ 12 | 13 | /* eslint-disable node/no-missing-import */ 14 | 15 | import 'react-native-gesture-handler'; 16 | import { registerRootComponent } from 'expo'; 17 | 18 | import App from './App'; 19 | 20 | // registerRootComponent calls AppRegistry.registerComponent('main', () => App); 21 | // It also ensures that whether you load the app in Expo Go or in a native build, 22 | // the environment is set up appropriately 23 | registerRootComponent(App); 24 | -------------------------------------------------------------------------------- /e2e/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 14 | 19 | -------------------------------------------------------------------------------- /e2e/babel.config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021-Present, Okta, Inc. and/or its affiliates. All rights reserved. 3 | * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.") 4 | * 5 | * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. 6 | * Unless required by applicable law or agreed to in writing, software 7 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 8 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 | * 10 | * See the License for the specific language governing permissions and limitations under the License. 11 | */ 12 | 13 | module.exports = function(api) { 14 | api.cache(false); 15 | return { 16 | presets: ['babel-preset-expo'], 17 | plugins: [ 18 | 'react-native-reanimated/plugin', 19 | [ 20 | 'module:react-native-dotenv', { 21 | 'moduleName': '@env', 22 | 'path': '.env', 23 | 'blacklist': null, 24 | 'whitelist': null, 25 | 'safe': false, 26 | 'allowUndefined': true 27 | } 28 | ] 29 | ] 30 | }; 31 | }; 32 | -------------------------------------------------------------------------------- /e2e/android/app/src/androidTest/java/com/e2eoktareactnative/test/EndToEndCredentials.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023-Present Okta, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.e2eoktareactnative.test 17 | 18 | import java.util.Properties 19 | 20 | object EndToEndCredentials { 21 | private val properties = Properties() 22 | 23 | init { 24 | val inputStream = EndToEndCredentials::class.java.classLoader!!.getResourceAsStream("e2eCredentials.properties") 25 | properties.load(inputStream) 26 | } 27 | 28 | operator fun get(key: String): String { 29 | return properties.getProperty(key) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /e2e/android/forceVersions.gradle: -------------------------------------------------------------------------------- 1 | def forceVersions(ConfigurationContainer configurations) { 2 | configurations.configureEach { configuration -> 3 | configuration.resolutionStrategy { 4 | force 'commons-fileupload:commons-fileupload:1.6.0' 5 | force 'com.google.guava:guava:32.1.3-android' 6 | force 'org.xerial:sqlite-jdbc:3.44.1.0' 7 | force 'com.google.code.gson:gson:2.10.1' 8 | force 'org.json:json:20231013' 9 | force 'org.bouncycastle:bcutil-jdk15to18:1.78.1' 10 | force 'org.bouncycastle:bcprov-jdk15to18:1.78.1' 11 | force 'org.bouncycastle:bcprov-jdk18on:1.78.1' 12 | force 'org.robolectric:robolectric:4.12.2' 13 | force 'junit:junit:4.13.2' 14 | force 'commons-io:commons-io:2.15.1' 15 | force 'commons-codec:commons-codec:1.17.0' 16 | force 'io.netty:netty-handler:4.1.125.Final' 17 | force 'io.netty:netty-codec-http:4.1.125.Final' 18 | force 'io.netty:netty-codec-http2:4.1.125.Final' 19 | force 'com.google.protobuf:protobuf-java:3.25.6' 20 | } 21 | } 22 | } 23 | 24 | ext.forceVersions = this.&forceVersions 25 | -------------------------------------------------------------------------------- /e2e/android/app/src/androidTest/java/com/e2eoktareactnative/dashboard/DashboardPage.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023-Present Okta, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.e2eoktareactnative.dashboard 17 | 18 | import com.e2eoktareactnative.login.LoginPage 19 | import com.e2eoktareactnative.test.clickButtonWithText 20 | import com.e2eoktareactnative.test.waitForTextMatching 21 | 22 | internal class DashboardPage { 23 | init { 24 | waitForTextMatching("Welcome back, .*!") 25 | waitForTextMatching("User: .*") 26 | } 27 | 28 | fun logout(): LoginPage { 29 | clickButtonWithText("LOGOUT") 30 | return LoginPage() 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## PR Checklist 2 | Please check if your PR fulfills the following requirements: 3 | 4 | - [ ] The commit message follows our [guidelines](/okta/okta-react-native/blob/master/CONTRIBUTING.md#commit) 5 | - [ ] Tests for the changes have been added (for bug fixes / features) 6 | - [ ] Docs have been added / updated (for bug fixes / features) 7 | 8 | 9 | ## PR Type 10 | What kind of change does this PR introduce? 11 | 12 | - [ ] Bugfix 13 | - [ ] Feature 14 | - [ ] Code style update (formatting, local variables) 15 | - [ ] Refactoring (no functional changes, no api changes) 16 | - [ ] Adding Tests 17 | - [ ] Build related changes 18 | - [ ] CI related changes 19 | - [ ] Documentation changes 20 | - [ ] Other... Please describe: 21 | 22 | 23 | ## What is the current behavior? 24 | 25 | 26 | Issue Number: N/A 27 | 28 | 29 | ## What is the new behavior? 30 | 31 | 32 | ## Does this PR introduce a breaking change? 33 | - [ ] Yes 34 | - [ ] No 35 | 36 | 37 | 38 | 39 | ## Other information 40 | 41 | 42 | ## Reviewers 43 | 44 | -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/Images.xcassets/SplashScreenLogo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "idiom": "universal", 5 | "filename": "image.png", 6 | "scale": "1x" 7 | }, 8 | { 9 | "idiom": "universal", 10 | "filename": "image@2x.png", 11 | "scale": "2x" 12 | }, 13 | { 14 | "idiom": "universal", 15 | "filename": "image@3x.png", 16 | "scale": "3x" 17 | }, 18 | { 19 | "idiom": "universal", 20 | "appearances": [ 21 | { 22 | "appearance": "luminosity", 23 | "value": "dark" 24 | } 25 | ], 26 | "scale": "1x", 27 | "filename": "dark_image.png" 28 | }, 29 | { 30 | "idiom": "universal", 31 | "appearances": [ 32 | { 33 | "appearance": "luminosity", 34 | "value": "dark" 35 | } 36 | ], 37 | "scale": "2x", 38 | "filename": "dark_image@2x.png" 39 | }, 40 | { 41 | "idiom": "universal", 42 | "appearances": [ 43 | { 44 | "appearance": "luminosity", 45 | "value": "dark" 46 | } 47 | ], 48 | "scale": "3x", 49 | "filename": "dark_image@3x.png" 50 | } 51 | ], 52 | "info": { 53 | "version": 1, 54 | "author": "expo" 55 | } 56 | } -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNativeUITests/ABColdStartTests.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021-Present, Okta, Inc. and/or its affiliates. All rights reserved. 3 | * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.") 4 | * 5 | * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. 6 | * Unless required by applicable law or agreed to in writing, software 7 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 8 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 | * 10 | * See the License for the specific language governing permissions and limitations under the License. 11 | */ 12 | 13 | import XCTest 14 | 15 | // This test case launches first in test suite. 16 | // The problem that the first launch of application has more load due to initializing libraries and internal cache. 17 | // Because of naming this test case is the first in queue. 18 | final class ABColdStart: XCTestCase { 19 | 20 | private var app: XCUIApplication! 21 | 22 | override func setUpWithError() throws { 23 | app = XCUIApplication() 24 | app.launch() 25 | } 26 | 27 | func testABColdStart() { 28 | XCTAssertTrue(app.buttons.firstMatch.waitForExistence(timeout: .testing * 3)) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /scripts/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export NVM_DIR="/root/.nvm" 4 | 5 | # Install required node version 6 | setup_service node v20.9.0 7 | 8 | # determine the linux distro 9 | distro=$(awk -F= '$1=="ID" { print $2 ;}' /etc/os-release | tr -d '"') 10 | echo $distro 11 | 12 | # yarn installation is different, depending on distro 13 | if [ "$distro" = "centos" ]; then 14 | # Use the cacert bundled with centos as okta root CA is self-signed and cause issues downloading from yarn 15 | setup_service yarn 1.21.1 /etc/pki/tls/certs/ca-bundle.crt 16 | # Add yarn to the $PATH so npm cli commands do not fail 17 | export PATH="${PATH}:$(yarn global bin)" 18 | elif [ "$distro" = "amzn" ]; then 19 | yum install -y git-lfs 20 | git-lfs install 21 | npm install -g yarn 22 | export PATH="$PATH:$(npm config get prefix)/bin" 23 | else 24 | echo "Unknown OS environment, exiting..." 25 | exit ${FAILED_SETUP} 26 | fi 27 | 28 | cd ${OKTA_HOME}/${REPO} 29 | 30 | # undo permissions change on scripts/publish.sh 31 | git checkout -- scripts 32 | 33 | # ensure we're in a branch on the correct sha 34 | git checkout $BRANCH 35 | git-lfs pull 36 | git reset --hard $SHA 37 | 38 | git config --global user.email "oktauploader@okta.com" 39 | git config --global user.name "oktauploader-okta" 40 | 41 | if ! yarn install ; then 42 | echo "yarn install failed! Exiting..." 43 | exit ${FAILED_SETUP} 44 | fi 45 | -------------------------------------------------------------------------------- /.github/workflows/composite/configure-node/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Setup node, run yarn, cache node_modules' 2 | description: 'Checkout and run yarn install' 3 | author: 'okta' 4 | 5 | inputs: 6 | node-version: 7 | description: 'Node version' 8 | required: false 9 | default: 18 10 | node-path: 11 | description: 'Path to node_modules' 12 | required: true 13 | lock-hash: 14 | # We should pass a full hash because `hashFiles('${{ inputs.lock-path }}/yarn.lock')` doesn't work 15 | description: 'Hash of yarn.lock file' 16 | required: true 17 | install-path: 18 | description: 'yarn --cwd ${install-path} install' 19 | required: false 20 | default: ./ 21 | 22 | outputs: 23 | cache-hit: 24 | description: "Cache node_files succeeded" 25 | value: ${{ steps.cache-node.outputs.cache-hit }} 26 | 27 | runs: 28 | using: "composite" 29 | steps: 30 | - name: Checkout 31 | uses: actions/setup-node@v3 32 | with: 33 | node-version: ${{ inputs.node-version }} 34 | - name: Install yarn 35 | run: npm install -g yarn 36 | shell: bash 37 | - name: Retrieve/save cache node_modules 38 | id: cache-node 39 | uses: actions/cache@v3 40 | with: 41 | path: ${{ inputs.node-path }} 42 | key: node-modules-${{ inputs.lock-hash }} 43 | - name: Install deps 44 | if: steps.cache-node.outputs.cache-hit != 'true' 45 | run: yarn --cwd ${{ inputs.install-path }} install --frozen-lockfile 46 | shell: bash -------------------------------------------------------------------------------- /e2e/android/app/src/androidTest/java/com/e2eoktareactnative/login/LoginPage.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023-Present Okta, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.e2eoktareactnative.login 17 | 18 | import com.e2eoktareactnative.customlogin.CustomLoginPage 19 | import com.e2eoktareactnative.test.clickButtonWithText 20 | import com.e2eoktareactnative.test.waitForText 21 | import com.e2eoktareactnative.web.WebPage 22 | import kotlin.time.Duration.Companion.seconds 23 | 24 | internal class LoginPage { 25 | init { 26 | waitForText("BROWSER SIGN-IN", timeout = 10L.seconds.inWholeMilliseconds) 27 | } 28 | 29 | fun browserLogin(): WebPage { 30 | clickButtonWithText("BROWSER SIGN-IN") 31 | return WebPage(this) 32 | } 33 | 34 | fun customLogin(): CustomLoginPage { 35 | clickButtonWithText("CUSTOM SIGN-IN") 36 | return CustomLoginPage() 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/PrivacyInfo.xcprivacy: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSPrivacyAccessedAPITypes 6 | 7 | 8 | NSPrivacyAccessedAPIType 9 | NSPrivacyAccessedAPICategoryUserDefaults 10 | NSPrivacyAccessedAPITypeReasons 11 | 12 | CA92.1 13 | 14 | 15 | 16 | NSPrivacyAccessedAPIType 17 | NSPrivacyAccessedAPICategoryFileTimestamp 18 | NSPrivacyAccessedAPITypeReasons 19 | 20 | 0A2A.1 21 | 3B52.1 22 | C617.1 23 | 24 | 25 | 26 | NSPrivacyAccessedAPIType 27 | NSPrivacyAccessedAPICategoryDiskSpace 28 | NSPrivacyAccessedAPITypeReasons 29 | 30 | E174.1 31 | 85F4.1 32 | 33 | 34 | 35 | NSPrivacyAccessedAPIType 36 | NSPrivacyAccessedAPICategorySystemBootTime 37 | NSPrivacyAccessedAPITypeReasons 38 | 39 | 35F9.1 40 | 41 | 42 | 43 | NSPrivacyCollectedDataTypes 44 | 45 | NSPrivacyTracking 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /android/src/main/java/com/oktareactnative/OktaSdkBridgePackage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Okta, Inc. and/or its affiliates. All rights reserved. 3 | * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.") 4 | * 5 | * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. 6 | * Unless required by applicable law or agreed to in writing, software 7 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 8 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 | * 10 | * See the License for the specific language governing permissions and limitations under the License. 11 | */ 12 | 13 | package com.oktareactnative; 14 | 15 | import java.util.Arrays; 16 | import java.util.Collections; 17 | import java.util.List; 18 | 19 | import com.facebook.react.ReactPackage; 20 | import com.facebook.react.bridge.NativeModule; 21 | import com.facebook.react.bridge.ReactApplicationContext; 22 | import com.facebook.react.uimanager.ViewManager; 23 | import com.facebook.react.bridge.JavaScriptModule; 24 | 25 | public class OktaSdkBridgePackage implements ReactPackage { 26 | 27 | @Override 28 | public List createNativeModules(ReactApplicationContext reactContext) { 29 | return Arrays.asList(new OktaSdkBridgeModule(reactContext)); 30 | } 31 | 32 | @Override 33 | public List createViewManagers(ReactApplicationContext reactContext) { 34 | return Collections.emptyList(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-report.yml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: Report a bug you encountered with the Okta React Native SDK 3 | labels: [ bug ] 4 | body: 5 | - type: textarea 6 | id: problem 7 | attributes: 8 | label: Describe the bug? 9 | description: | 10 | Please be as detailed as possible. This will help us address the bug in a timely manner. 11 | validations: 12 | required: true 13 | 14 | - type: textarea 15 | id: expected 16 | attributes: 17 | label: What is expected to happen? 18 | validations: 19 | required: true 20 | 21 | - type: textarea 22 | id: actual 23 | attributes: 24 | label: What is the actual behavior? 25 | validations: 26 | required: true 27 | 28 | - type: textarea 29 | id: repro 30 | attributes: 31 | label: Reproduction Steps? 32 | description: | 33 | Please provide as much detail as possible to help us reproduce your bug. 34 | A reproduction repo is very helpful for us as well. 35 | validations: 36 | required: true 37 | 38 | - type: textarea 39 | id: additional 40 | attributes: 41 | label: Additional Information? 42 | 43 | - type: textarea 44 | id: sdkVersion 45 | attributes: 46 | label: SDK Version 47 | validations: 48 | required: true 49 | 50 | - type: textarea 51 | id: buildInformation 52 | attributes: 53 | label: Build Information 54 | description: If this is an issue related to building, please supply relevant Android/Gradle/iOS/Xcode version information. 55 | -------------------------------------------------------------------------------- /e2e/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "index.js", 3 | "scripts": { 4 | "android": "expo run:android", 5 | "ios": "expo run:ios", 6 | "web": "expo start --web", 7 | "start": "expo start --dev-client", 8 | "bundle:ios": "react-native bundle --entry-file index.js --bundle-output ios/main.jsbundle --dev false --platform ios --assets-dest ios", 9 | "bundle:android": "mkdir -p android/app/src/main/assets; react-native bundle --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --dev false --platform android --assets-dest android/app/src/main/res" 10 | }, 11 | "dependencies": { 12 | "@okta/okta-react-native": "file:../dist", 13 | "@react-navigation/native": "^6.1.17", 14 | "@react-navigation/native-stack": "^6.9.26", 15 | "expo": "^52.0.31", 16 | "expo-splash-screen": "~0.29.21", 17 | "expo-status-bar": "~2.0.1", 18 | "react": "18.3.1", 19 | "react-dom": "18.3.1", 20 | "react-native": "0.76.7", 21 | "react-native-dotenv": "^3.4.9", 22 | "react-native-gesture-handler": "~2.20.2", 23 | "react-native-reanimated": "^3.11.0", 24 | "react-native-safe-area-context": "4.12.0", 25 | "react-native-screens": "~4.4.0", 26 | "semver": "^7.6.2", 27 | "ws": "^8.18.0" 28 | }, 29 | "resolutions": { 30 | "glob": "^9.3.5", 31 | "tar": "^6.2.1", 32 | "micromatch": "^4.0.7", 33 | "braces": "^3.0.3", 34 | "ws": "^8.18.0" 35 | }, 36 | "devDependencies": { 37 | "@babel/core": "^7.24.6" 38 | }, 39 | "private": true, 40 | "name": "e2e", 41 | "version": "1.0.0" 42 | } 43 | -------------------------------------------------------------------------------- /ios/OktaSdkBridge/OktaSdkConstant.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-Present, Okta, Inc. and/or its affiliates. All rights reserved. 3 | * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.") 4 | * 5 | * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. 6 | * Unless required by applicable law or agreed to in writing, software 7 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 8 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 | * 10 | * See the License for the specific language governing permissions and limitations under the License. 11 | */ 12 | 13 | import Foundation 14 | 15 | struct OktaSdkConstant { 16 | /** ======== Keys ======== **/ 17 | static let RESOLVE_TYPE_KEY = "resolve_type" 18 | static let ACCESS_TOKEN_KEY = "access_token" 19 | static let ID_TOKEN_KEY = "id_token" 20 | static let REFRESH_TOKEN_KEY = "refresh_token" 21 | static let AUTHENTICATED_KEY = "authenticated" 22 | static let ERROR_CODE_KEY = "error_code"; 23 | static let ERROR_MSG_KEY = "error_message"; 24 | 25 | /** ======== Values ======== **/ 26 | static let AUTHORIZED = "authorized" 27 | static let SIGNED_OUT = "signed_out" 28 | static let CANCELLED = "cancelled" 29 | 30 | /** ======== Event names ======== **/ 31 | static let SIGN_IN_SUCCESS = "signInSuccess"; 32 | static let ON_ERROR = "onError"; 33 | static let SIGN_OUT_SUCCESS = "signOutSuccess"; 34 | static let ON_CANCELLED = "onCancelled"; 35 | } 36 | -------------------------------------------------------------------------------- /e2e/config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021-Present, Okta, Inc. and/or its affiliates. All rights reserved. 3 | * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.") 4 | * 5 | * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. 6 | * Unless required by applicable law or agreed to in writing, software 7 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 8 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 | * 10 | * See the License for the specific language governing permissions and limitations under the License. 11 | */ 12 | 13 | /* eslint-disable node/no-missing-import */ 14 | 15 | import { CLIENT_ID, REDIRECT_URI, LOGOUT_REDIRECT_URI, ISSUER } from '@env'; 16 | 17 | /* 18 | clientId, redirectUri, endSessionRedirectUri - these values can be found on the "General" tab 19 | of the application that you created earlier in Admin Console. 20 | discoveryUri - this is the URL of the authorization server that will perform authentication. 21 | 22 | For more details, https://developer.okta.com/docs/guides/sign-into-mobile-app/create-okta-application/ 23 | */ 24 | 25 | export default { 26 | oidc: { 27 | clientId: CLIENT_ID, // e.g.: `a0abcEf0gH123ssJS4o5` 28 | redirectUri: REDIRECT_URI, // e.g.: `com.okta.example:/callback` 29 | endSessionRedirectUri: LOGOUT_REDIRECT_URI, // e.g.: com.okta.example:/logout 30 | discoveryUri: ISSUER, // e.g.: https://dev-1234.okta.com/ 31 | scopes: ['openid', 'profile', 'offline_access'], 32 | requireHardwareBackedKeyStore: false, 33 | }, 34 | }; 35 | -------------------------------------------------------------------------------- /e2e/android/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | includeBuild(new File(["node", "--print", "require.resolve('@react-native/gradle-plugin/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim()).getParentFile().toString()) 3 | } 4 | plugins { id("com.facebook.react.settings") } 5 | 6 | extensions.configure(com.facebook.react.ReactSettingsExtension) { ex -> 7 | if (System.getenv('EXPO_USE_COMMUNITY_AUTOLINKING') == '1') { 8 | ex.autolinkLibrariesFromCommand() 9 | } else { 10 | def command = [ 11 | 'node', 12 | '--no-warnings', 13 | '--eval', 14 | 'require(require.resolve(\'expo-modules-autolinking\', { paths: [require.resolve(\'expo/package.json\')] }))(process.argv.slice(1))', 15 | 'react-native-config', 16 | '--json', 17 | '--platform', 18 | 'android' 19 | ].toList() 20 | ex.autolinkLibrariesFromCommand(command) 21 | } 22 | } 23 | 24 | rootProject.name = 'E2E-Okta-React-Native' 25 | 26 | dependencyResolutionManagement { 27 | versionCatalogs { 28 | reactAndroidLibs { 29 | from(files(new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim(), "../gradle/libs.versions.toml"))) 30 | } 31 | } 32 | } 33 | 34 | apply from: new File(["node", "--print", "require.resolve('expo/package.json')"].execute(null, rootDir).text.trim(), "../scripts/autolinking.gradle"); 35 | useExpoModules() 36 | 37 | include ':app' 38 | includeBuild(new File(["node", "--print", "require.resolve('@react-native/gradle-plugin/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim()).getParentFile()) 39 | -------------------------------------------------------------------------------- /e2e/App.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021-Present, Okta, Inc. and/or its affiliates. All rights reserved. 3 | * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.") 4 | * 5 | * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. 6 | * Unless required by applicable law or agreed to in writing, software 7 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 8 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 | * 10 | * See the License for the specific language governing permissions and limitations under the License. 11 | */ 12 | 13 | /* eslint-disable no-unused-vars */ 14 | /* eslint-disable node/no-missing-import */ 15 | 16 | import * as React from 'react'; 17 | import { NavigationContainer } from '@react-navigation/native'; 18 | import { createNativeStackNavigator } from '@react-navigation/native-stack'; 19 | import CustomLogin from './pages/CustomLogin'; 20 | import Home from './pages/Home'; 21 | import ProfilePage from './pages/ProfilePage'; 22 | 23 | const Stack = createNativeStackNavigator(); 24 | 25 | const App = () => { 26 | return ( 27 | 28 | 29 | 33 | 37 | 44 | 45 | 46 | ); 47 | }; 48 | 49 | export default App; -------------------------------------------------------------------------------- /android/src/main/java/com/oktareactnative/OktaSdkError.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Okta, Inc. and/or its affiliates. All rights reserved. 3 | * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.") 4 | * 5 | * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. 6 | * Unless required by applicable law or agreed to in writing, software 7 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 8 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 | * 10 | * See the License for the specific language governing permissions and limitations under the License. 11 | */ 12 | 13 | package com.oktareactnative; 14 | 15 | public enum OktaSdkError { 16 | NOT_CONFIGURED("-100", "OktaOidc client isn't configured, check if you have created a configuration with createConfig"), 17 | NO_VIEW("-200", "No current view exists"), 18 | NO_ID_TOKEN("-500", "Id token does not exist"), 19 | OKTA_OIDC_ERROR("-600", "Okta Oidc error"), 20 | ERROR_TOKEN_TYPE("-700", "Token type not found"), 21 | NO_ACCESS_TOKEN("-900", "No access token found"), 22 | SIGN_IN_FAILED("-1000", "Sign in was not authorized"), 23 | NO_TOKENS("-1100", "Tokens not found"), 24 | CANCELLED("-1200", "User cancelled a session"); 25 | 26 | private final String errorCode; 27 | private final String errorMessage; 28 | 29 | OktaSdkError(String errorCode, String errorMessage) { 30 | this.errorCode = errorCode; 31 | this.errorMessage = errorMessage; 32 | } 33 | 34 | String getErrorCode() { 35 | return errorCode; 36 | } 37 | 38 | String getErrorMessage() { 39 | return errorMessage; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /ios/Tests/Mocks/OktaSdkBridgeMock.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021-Present, Okta, Inc. and/or its affiliates. All rights reserved. 3 | * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.") 4 | * 5 | * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. 6 | * Unless required by applicable law or agreed to in writing, software 7 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 8 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 | * 10 | * See the License for the specific language governing permissions and limitations under the License. 11 | */ 12 | 13 | import XCTest 14 | import OktaOidc 15 | @testable import ReactNativeOktaSdkBridge 16 | 17 | final class OktaSdkBridgeMock: OktaSdkBridge { 18 | private(set) var eventsRegister: [String: Any] = [:] 19 | private var customStateManager: StateManagerProtocol? 20 | 21 | override var storedStateManager: StateManagerProtocol? { 22 | if customStateManager != nil { 23 | return customStateManager 24 | } 25 | 26 | return config.flatMap { 27 | OktaOidcStateManager.makeOidcStateManager(with: $0) 28 | } 29 | } 30 | 31 | func setCustomStateManager(_ stateManager: StateManagerProtocol) { 32 | self.customStateManager = stateManager 33 | } 34 | 35 | // Must be overriden 36 | override func supportedEvents() -> [String]! { 37 | super.supportedEvents() 38 | } 39 | 40 | override func sendEvent(withName name: String!, body: Any!) { 41 | eventsRegister[name] = body 42 | } 43 | 44 | override func presentedViewController() -> UIViewController? { 45 | UIViewController() 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /ios/Tests/OktaSdkConstantTests.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021-Present, Okta, Inc. and/or its affiliates. All rights reserved. 3 | * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.") 4 | * 5 | * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. 6 | * Unless required by applicable law or agreed to in writing, software 7 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 8 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 | * 10 | * See the License for the specific language governing permissions and limitations under the License. 11 | */ 12 | 13 | import XCTest 14 | @testable import ReactNativeOktaSdkBridge 15 | 16 | final class OktaSdkConstantTests: XCTestCase { 17 | func testKeys() { 18 | XCTAssertEqual(OktaSdkConstant.RESOLVE_TYPE_KEY, "resolve_type") 19 | XCTAssertEqual(OktaSdkConstant.ACCESS_TOKEN_KEY, "access_token") 20 | XCTAssertEqual(OktaSdkConstant.ID_TOKEN_KEY, "id_token") 21 | XCTAssertEqual(OktaSdkConstant.REFRESH_TOKEN_KEY, "refresh_token") 22 | XCTAssertEqual(OktaSdkConstant.AUTHENTICATED_KEY, "authenticated") 23 | XCTAssertEqual(OktaSdkConstant.ERROR_CODE_KEY, "error_code") 24 | XCTAssertEqual(OktaSdkConstant.ERROR_MSG_KEY, "error_message") 25 | } 26 | 27 | func testValues() { 28 | XCTAssertEqual(OktaSdkConstant.AUTHORIZED, "authorized") 29 | XCTAssertEqual(OktaSdkConstant.SIGNED_OUT, "signed_out") 30 | XCTAssertEqual(OktaSdkConstant.CANCELLED, "cancelled") 31 | } 32 | 33 | func testEvents() { 34 | XCTAssertEqual(OktaSdkConstant.SIGN_IN_SUCCESS, "signInSuccess") 35 | XCTAssertEqual(OktaSdkConstant.ON_ERROR, "onError") 36 | XCTAssertEqual(OktaSdkConstant.SIGN_OUT_SUCCESS, "signOutSuccess") 37 | XCTAssertEqual(OktaSdkConstant.ON_CANCELLED, "onCancelled") 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /e2e/android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | apply from: 'forceVersions.gradle' 5 | forceVersions(configurations) 6 | 7 | ext { 8 | buildToolsVersion = findProperty('android.buildToolsVersion') ?: '35.0.0' 9 | minSdkVersion = Integer.parseInt(findProperty('android.minSdkVersion') ?: '24') 10 | compileSdkVersion = Integer.parseInt(findProperty('android.compileSdkVersion') ?: '35') 11 | targetSdkVersion = Integer.parseInt(findProperty('android.targetSdkVersion') ?: '34') 12 | kotlinVersion = findProperty('android.kotlinVersion') ?: '1.9.25' 13 | 14 | ndkVersion = "26.1.10909125" 15 | } 16 | repositories { 17 | google() 18 | mavenCentral() 19 | } 20 | dependencies { 21 | classpath('com.android.tools.build:gradle') 22 | classpath('com.facebook.react:react-native-gradle-plugin') 23 | classpath('org.jetbrains.kotlin:kotlin-gradle-plugin') 24 | } 25 | } 26 | 27 | apply plugin: "com.facebook.react.rootproject" 28 | 29 | subprojects { 30 | task allDeps(type: DependencyReportTask) {} 31 | } 32 | 33 | allprojects { 34 | forceVersions(configurations) 35 | 36 | repositories { 37 | maven { 38 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 39 | url(new File(['node', '--print', "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim(), '../android')) 40 | } 41 | maven { 42 | // Android JSC is installed from npm 43 | url(new File(['node', '--print', "require.resolve('jsc-android/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim(), '../dist')) 44 | } 45 | 46 | google() 47 | mavenCentral() 48 | maven { url 'https://www.jitpack.io' } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNativeUITests/LoginTests.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021-Present, Okta, Inc. and/or its affiliates. All rights reserved. 3 | * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.") 4 | * 5 | * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. 6 | * Unless required by applicable law or agreed to in writing, software 7 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 8 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 | * 10 | * See the License for the specific language governing permissions and limitations under the License. 11 | */ 12 | 13 | import XCTest 14 | 15 | extension TimeInterval { 16 | 17 | static let testing: TimeInterval = 15 18 | } 19 | 20 | class LoginTests: XCTestCase { 21 | let username = ProcessInfo.processInfo.environment["USERNAME"]! 22 | let password = ProcessInfo.processInfo.environment["PASSWORD"]! 23 | 24 | private(set) var app: XCUIApplication! 25 | 26 | var logoutButton: XCUIElement { 27 | app.buttons["logout_button"] 28 | } 29 | 30 | var browserLoginButton: XCUIElement { 31 | app.buttons["browser_login_button"] 32 | } 33 | 34 | var customLoginButton: XCUIElement { 35 | app.buttons["custom_login_button"] 36 | } 37 | 38 | var welcomeLabel: XCUIElement { 39 | app.staticTexts["welcome_text"] 40 | } 41 | 42 | var userNameLabel: XCUIElement { 43 | app.staticTexts["user_name"] 44 | } 45 | 46 | override func setUpWithError() throws { 47 | try super.setUpWithError() 48 | 49 | continueAfterFailure = false 50 | 51 | try XCTSkipIf(username.isEmpty, "Username is empty") 52 | try XCTSkipIf(password.isEmpty, "Password is empty") 53 | 54 | app = XCUIApplication() 55 | app.launch() 56 | } 57 | 58 | func testRootScreen() throws { 59 | // then 60 | XCTAssertTrue(browserLoginButton.waitForExistence(timeout: .testing)) 61 | XCTAssertTrue(customLoginButton.exists) 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /e2e/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /e2e/android/app/src/main/res/drawable/rn_edit_text_material.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 22 | 23 | 24 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /scripts/build.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const shell = require('shelljs'); 4 | const path = require('path'); 5 | const chalk = require('chalk'); 6 | const fs = require('fs'); 7 | 8 | const NPM_DIR = `dist`; 9 | const FILES_TO_COPY = [ 10 | 'index.js', 11 | 'types/index.d.ts', 12 | 'android', 13 | 'ios/OktaSdkBridge', 14 | 'ios/ReactNativeOktaSdkBridge.xcodeproj', 15 | 'LICENSE', 16 | '*.md', 17 | 'package.json', 18 | 'OktaSdkBridgeReactNative.podspec' 19 | ]; 20 | 21 | shell.echo(`Start building...`); 22 | 23 | shell.mkdir(`-p`, `${NPM_DIR}`); 24 | 25 | // Check whether a build folder isn't empty. If so, then delete any contents there. 26 | const folderSize = parseInt(shell.exec(`du -s ${NPM_DIR} | cut -f1`).stdout); 27 | const folderContents = shell.exec(`ls -A ${NPM_DIR}`).stdout; 28 | if ((folderSize && folderSize > 0) || (folderContents && folderContents != '')) { 29 | shell.echo(`Removing contents of build folder...`); 30 | shell.rm(`-Rf`, `${NPM_DIR}/*`); 31 | } 32 | 33 | // Create the nested folders to mirror files structure. 34 | FILES_TO_COPY.forEach(function(filePath) { 35 | const parentDir = path.join(NPM_DIR, path.dirname(filePath)); 36 | if (parentDir != NPM_DIR) { 37 | shell.mkdir(`-p`, parentDir); 38 | } 39 | 40 | shell.cp(`-Rf`, filePath, parentDir); 41 | }); 42 | 43 | 44 | shell.echo(`Modifying final package.json`); 45 | let packageJSON = JSON.parse(fs.readFileSync(`./${NPM_DIR}/package.json`)); 46 | delete packageJSON.private; // remove private flag 47 | delete packageJSON.scripts; // remove all scripts 48 | delete packageJSON.jest; // remove jest section 49 | delete packageJSON['jest-junit']; // remove jest-junit section 50 | delete packageJSON.workspaces; // remove yarn workspace section 51 | 52 | // Remove "dist/" from the entrypoint paths. 53 | ['main', 'module', 'types'].forEach(function(key) { 54 | if (packageJSON[key]) { 55 | packageJSON[key] = packageJSON[key].replace(`${NPM_DIR}/`, ''); 56 | } 57 | }); 58 | 59 | fs.writeFileSync(`./${NPM_DIR}/package.json`, JSON.stringify(packageJSON, null, 4)); 60 | 61 | shell.echo(chalk.green(`End building`)); 62 | -------------------------------------------------------------------------------- /e2e/android/app/src/androidTest/java/com/e2eoktareactnative/login/CustomLoginTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023-Present Okta, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.e2eoktareactnative.login 17 | 18 | import androidx.test.ext.junit.rules.activityScenarioRule 19 | import androidx.test.ext.junit.runners.AndroidJUnit4 20 | import com.e2eoktareactnative.MainActivity 21 | import com.e2eoktareactnative.test.EndToEndCredentials 22 | import org.junit.Rule 23 | import org.junit.Test 24 | import org.junit.runner.RunWith 25 | 26 | @RunWith(AndroidJUnit4::class) 27 | internal class CustomLoginTest { 28 | @get:Rule 29 | val activityRule = activityScenarioRule() 30 | 31 | private val testUsername = EndToEndCredentials.get("username") 32 | private val testPassword = EndToEndCredentials.get("password") 33 | 34 | @Test 35 | fun testCustomLogin() { 36 | LoginPage().customLogin() 37 | .username(testUsername) 38 | .password(testPassword) 39 | .login() 40 | } 41 | 42 | @Test 43 | fun testCustomLoginError() { 44 | LoginPage().customLogin() 45 | .username(testUsername) 46 | .password("wrongPassword") 47 | .loginExpectingError() 48 | .assertHasError("Sign in was not authorized") 49 | .pressAlertOkButton() 50 | } 51 | 52 | @Test 53 | fun testCustomLoginLogout() { 54 | LoginPage().customLogin() 55 | .username(testUsername) 56 | .password(testPassword) 57 | .login() 58 | .logout() 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /ios/Tests/Mocks/OktaOidcStateManagerMock.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021-Present, Okta, Inc. and/or its affiliates. All rights reserved. 3 | * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.") 4 | * 5 | * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. 6 | * Unless required by applicable law or agreed to in writing, software 7 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 8 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 | * 10 | * See the License for the specific language governing permissions and limitations under the License. 11 | */ 12 | 13 | import XCTest 14 | import OktaOidc 15 | @testable import ReactNativeOktaSdkBridge 16 | 17 | final class OktaOidcStateManagerMock: StateManagerProtocol { 18 | var accessToken: String? 19 | var idToken: String? 20 | var refreshToken: String? 21 | 22 | private let shouldFail: Bool 23 | private let config: OktaOidcConfig 24 | 25 | init(shouldFail: Bool, config: OktaOidcConfig) { 26 | self.shouldFail = shouldFail 27 | self.config = config 28 | } 29 | 30 | func getUser(_ callback: @escaping ([String: Any]?, Error?) -> Void) { 31 | callback(shouldFail ? nil : ["name": "mock"], 32 | shouldFail ? OktaOidcError.noUserInfoEndpoint : nil) 33 | } 34 | 35 | func renew(callback: @escaping ((OktaOidcStateManager?, Error?) -> Void)) { 36 | callback(shouldFail ? nil : OktaOidcStateManager.makeOidcStateManager(with: config), 37 | shouldFail ? OktaOidcError.noRefreshToken : nil) 38 | } 39 | 40 | func revoke(_ token: String?, callback: @escaping (Bool, Error?) -> Void) { 41 | callback(!shouldFail, shouldFail ? OktaOidcError.noBearerToken : nil) 42 | } 43 | 44 | func introspect(token: String?, callback: @escaping ([String: Any]?, Error?) -> Void) { 45 | callback(shouldFail ? nil : ["exp": "mock"], 46 | shouldFail ? OktaOidcError.noBearerToken : nil) 47 | } 48 | 49 | func removeFromSecureStorage() throws { 50 | 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /ios/Tests/Mocks/OktaOidcMock.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021-Present, Okta, Inc. and/or its affiliates. All rights reserved. 3 | * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.") 4 | * 5 | * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. 6 | * Unless required by applicable law or agreed to in writing, software 7 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 8 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 | * 10 | * See the License for the specific language governing permissions and limitations under the License. 11 | */ 12 | 13 | import XCTest 14 | import OktaOidc 15 | @testable import ReactNativeOktaSdkBridge 16 | 17 | class OktaOidcMock: OktaOidcProtocol { 18 | let configuration: OktaOidcConfig 19 | 20 | private let shouldFail: Bool 21 | private let oidcManager: OktaOidcStateManager 22 | private let failedError: Error? 23 | 24 | private var callbackError: Error { 25 | failedError ?? OktaReactNativeError.oktaOidcError 26 | } 27 | 28 | init(configuration: OktaOidcConfig, shouldFail: Bool, failedError: Error? = nil) { 29 | self.configuration = configuration 30 | self.shouldFail = shouldFail 31 | self.failedError = failedError 32 | self.oidcManager = OktaOidcStateManager.makeOidcStateManager(with: configuration) 33 | } 34 | 35 | func signInWithBrowser(from presenter: UIViewController, 36 | additionalParameters: [String: String], 37 | callback: @escaping ((OktaOidcStateManager?, Error?) -> Void)) { 38 | callback(shouldFail ? nil : oidcManager, 39 | shouldFail ? callbackError : nil) 40 | } 41 | 42 | func signOutOfOkta(_ authStateManager: OktaOidcStateManager, from presenter: UIViewController, callback: @escaping ((Error?) -> Void)) { 43 | callback(shouldFail ? callbackError : nil) 44 | } 45 | 46 | func authenticate(withSessionToken sessionToken: String, callback: @escaping ((OktaOidcStateManager?, Error?) -> Void)) { 47 | callback(shouldFail ? nil : oidcManager, 48 | shouldFail ? callbackError : nil) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /e2e/android/app/src/main/java/com/e2eoktareactnative/MainApplication.kt: -------------------------------------------------------------------------------- 1 | package com.e2eoktareactnative 2 | 3 | import android.app.Application 4 | import android.content.res.Configuration 5 | 6 | import com.facebook.react.PackageList 7 | import com.facebook.react.ReactApplication 8 | import com.facebook.react.ReactNativeHost 9 | import com.facebook.react.ReactPackage 10 | import com.facebook.react.ReactHost 11 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load 12 | import com.facebook.react.defaults.DefaultReactNativeHost 13 | import com.facebook.react.soloader.OpenSourceMergedSoMapping 14 | import com.facebook.soloader.SoLoader 15 | 16 | import expo.modules.ApplicationLifecycleDispatcher 17 | import expo.modules.ReactNativeHostWrapper 18 | 19 | class MainApplication : Application(), ReactApplication { 20 | 21 | override val reactNativeHost: ReactNativeHost = ReactNativeHostWrapper( 22 | this, 23 | object : DefaultReactNativeHost(this) { 24 | override fun getPackages(): List { 25 | val packages = PackageList(this).packages 26 | // Packages that cannot be autolinked yet can be added manually here, for example: 27 | // packages.add(new MyReactNativePackage()); 28 | return packages 29 | } 30 | 31 | override fun getJSMainModuleName(): String = ".expo/.virtual-metro-entry" 32 | 33 | override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG 34 | 35 | override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED 36 | override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED 37 | } 38 | ) 39 | 40 | override val reactHost: ReactHost 41 | get() = ReactNativeHostWrapper.createReactHost(applicationContext, reactNativeHost) 42 | 43 | override fun onCreate() { 44 | super.onCreate() 45 | SoLoader.init(this, OpenSourceMergedSoMapping) 46 | if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { 47 | // If you opted-in for the New Architecture, we load the native entry point for this app. 48 | load() 49 | } 50 | ApplicationLifecycleDispatcher.onApplicationCreate(this) 51 | } 52 | 53 | override fun onConfigurationChanged(newConfig: Configuration) { 54 | super.onConfigurationChanged(newConfig) 55 | ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /e2e/android/app/src/androidTest/java/com/e2eoktareactnative/login/BrowserLoginTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023-Present Okta, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.e2eoktareactnative.login 17 | 18 | import androidx.test.ext.junit.rules.activityScenarioRule 19 | import androidx.test.ext.junit.runners.AndroidJUnit4 20 | import com.e2eoktareactnative.MainActivity 21 | import com.e2eoktareactnative.test.EndToEndCredentials 22 | import com.e2eoktareactnative.web.WebPage 23 | import org.junit.Before 24 | import org.junit.Rule 25 | import org.junit.Test 26 | import org.junit.runner.RunWith 27 | 28 | @RunWith(AndroidJUnit4::class) 29 | internal class BrowserLoginTest { 30 | @get:Rule 31 | val activityRule = activityScenarioRule() 32 | 33 | private val testUsername = EndToEndCredentials.get("username") 34 | private val testPassword = EndToEndCredentials.get("password") 35 | 36 | @Before 37 | fun clearWebData() { 38 | WebPage.clearData() 39 | } 40 | 41 | @Test 42 | fun testLoginPageExists() { 43 | LoginPage() 44 | } 45 | 46 | @Test 47 | fun testBrowserLogin() { 48 | LoginPage().browserLogin() 49 | .username(testUsername) 50 | .password(testPassword) 51 | .login() 52 | } 53 | 54 | @Test 55 | fun testFailedBrowserLogin() { 56 | LoginPage().browserLogin() 57 | .username(testUsername) 58 | .password("wrongPassword") 59 | .loginExpectingError() 60 | .assertHasError("Unable to sign in") 61 | .cancel() 62 | } 63 | 64 | @Test 65 | fun testBrowserLogout() { 66 | LoginPage().browserLogin() 67 | .username(testUsername) 68 | .password(testPassword) 69 | .login() 70 | .logout() 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | 3 | orbs: 4 | general-platform-helpers: okta/general-platform-helpers@1.9 5 | node: circleci/node@5.1.0 6 | 7 | executors: 8 | linux: 9 | machine: 10 | image: ubuntu-2404:current 11 | 12 | commands: 13 | install_android_sdk: 14 | description: "Install Android SDK" 15 | steps: 16 | - run: wget --quiet --output-document="$HOME/android-commandline.zip" https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip 17 | - run: (cp .circleci/android_sdk_checksum $HOME/checksum; cd $HOME; shasum -a256 -c checksum) 18 | - run: set +o pipefail 19 | - run: unzip "$HOME/android-commandline.zip" -d "$HOME" 20 | - run: mkdir "$HOME/android-sdk" 21 | - run: echo y | $HOME/cmdline-tools/bin/sdkmanager --sdk_root="$HOME/android-sdk" "platforms;android-35" > /dev/null 22 | - run: echo y | $HOME/cmdline-tools/bin/sdkmanager --sdk_root="$HOME/android-sdk" "platform-tools" > /dev/null 23 | - run: echo y | $HOME/cmdline-tools/bin/sdkmanager --sdk_root="$HOME/android-sdk" "build-tools;35.0.0" > /dev/null 24 | - run: (yes || true) | $HOME/cmdline-tools/bin/sdkmanager --sdk_root="$HOME/android-sdk" --licenses 25 | - run: echo 'export ANDROID_HOME="$HOME/android-sdk"' >> "$BASH_ENV" 26 | - run: set -o pipefail 27 | 28 | setup: 29 | description: "Setup project for security scan" 30 | steps: 31 | - checkout 32 | - install_android_sdk 33 | - run: yarn install --frozen-lockfile 34 | - run: (cd android; ./gradlew assembleDebug) # Avoid gradle build during snyk scan 35 | - run: (cd e2e; yarn install --frozen-lockfile) 36 | - run: (cd e2e/android; echo "signInRedirectUri=com.example.redirect:/login" > okta.properties; ./gradlew assembleDebug) # Avoid gradle build during snyk scan 37 | 38 | jobs: 39 | snyk-scan: 40 | executor: linux 41 | steps: 42 | - setup 43 | - run: pip install setuptools 44 | - general-platform-helpers/step-load-dependencies 45 | - general-platform-helpers/step-run-snyk-monitor: 46 | run-on-non-main: true 47 | additional-arguments: --exclude=dist 48 | 49 | workflows: 50 | security-scan: 51 | jobs: 52 | - snyk-scan: 53 | name: execute-snyk 54 | context: 55 | - static-analysis 56 | filters: 57 | branches: 58 | only: 59 | - master 60 | -------------------------------------------------------------------------------- /e2e/android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx512m -XX:MaxMetaspaceSize=256m 13 | org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | # AndroidX package structure to make it clearer which packages are bundled with the 21 | # Android operating system, and which are packaged with your app's APK 22 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 23 | android.useAndroidX=true 24 | 25 | # Enable AAPT2 PNG crunching 26 | android.enablePngCrunchInReleaseBuilds=true 27 | 28 | # Use this property to specify which architecture you want to build. 29 | # You can also override it from the CLI using 30 | # ./gradlew -PreactNativeArchitectures=x86_64 31 | reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64 32 | 33 | # Use this property to enable support to the new architecture. 34 | # This will allow you to use TurboModules and the Fabric render in 35 | # your application. You should enable this flag either if you want 36 | # to write custom TurboModules/Fabric components OR use libraries that 37 | # are providing them. 38 | newArchEnabled=false 39 | 40 | # Use this property to enable or disable the Hermes JS engine. 41 | # If set to false, you will be using JSC instead. 42 | hermesEnabled=true 43 | 44 | # Enable GIF support in React Native images (~200 B increase) 45 | expo.gif.enabled=true 46 | # Enable webp support in React Native images (~85 KB increase) 47 | expo.webp.enabled=true 48 | # Enable animated webp support (~3.4 MB increase) 49 | # Disabled by default because iOS doesn't support animated webp 50 | expo.webp.animated=false 51 | 52 | # Enable network inspector 53 | EX_DEV_CLIENT_NETWORK_INSPECTOR=true 54 | 55 | # Use legacy packaging to compress native libraries in the resulting APK. 56 | expo.useLegacyPackaging=false 57 | -------------------------------------------------------------------------------- /e2e/android/app/src/main/java/com/e2eoktareactnative/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.e2eoktareactnative 2 | import expo.modules.splashscreen.SplashScreenManager 3 | 4 | import android.os.Build 5 | import android.os.Bundle 6 | 7 | import com.facebook.react.ReactActivity 8 | import com.facebook.react.ReactActivityDelegate 9 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled 10 | import com.facebook.react.defaults.DefaultReactActivityDelegate 11 | 12 | import expo.modules.ReactActivityDelegateWrapper 13 | 14 | class MainActivity : ReactActivity() { 15 | override fun onCreate(savedInstanceState: Bundle?) { 16 | // Set the theme to AppTheme BEFORE onCreate to support 17 | // coloring the background, status bar, and navigation bar. 18 | // This is required for expo-splash-screen. 19 | // setTheme(R.style.AppTheme); 20 | // @generated begin expo-splashscreen - expo prebuild (DO NOT MODIFY) sync-f3ff59a738c56c9a6119210cb55f0b613eb8b6af 21 | SplashScreenManager.registerOnActivity(this) 22 | // @generated end expo-splashscreen 23 | super.onCreate(null) 24 | } 25 | 26 | /** 27 | * Returns the name of the main component registered from JavaScript. This is used to schedule 28 | * rendering of the component. 29 | */ 30 | override fun getMainComponentName(): String = "main" 31 | 32 | /** 33 | * Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate] 34 | * which allows you to enable New Architecture with a single boolean flags [fabricEnabled] 35 | */ 36 | override fun createReactActivityDelegate(): ReactActivityDelegate { 37 | return ReactActivityDelegateWrapper( 38 | this, 39 | BuildConfig.IS_NEW_ARCHITECTURE_ENABLED, 40 | object : DefaultReactActivityDelegate( 41 | this, 42 | mainComponentName, 43 | fabricEnabled 44 | ){}) 45 | } 46 | 47 | /** 48 | * Align the back button behavior with Android S 49 | * where moving root activities to background instead of finishing activities. 50 | * @see onBackPressed 51 | */ 52 | override fun invokeDefaultOnBackPressed() { 53 | if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) { 54 | if (!moveTaskToBack(false)) { 55 | // For non-root activities, use the default implementation to finish them. 56 | super.invokeDefaultOnBackPressed() 57 | } 58 | return 59 | } 60 | 61 | // Use the default back button implementation on Android S 62 | // because it's doing more than [Activity.moveTaskToBack] in fact. 63 | super.invokeDefaultOnBackPressed() 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /android/src/main/java/com/oktareactnative/OktaSdkConstant.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Okta, Inc. and/or its affiliates. All rights reserved. 3 | * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.") 4 | * 5 | * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. 6 | * Unless required by applicable law or agreed to in writing, software 7 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 8 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 | * 10 | * See the License for the specific language governing permissions and limitations under the License. 11 | */ 12 | 13 | 14 | package com.oktareactnative; 15 | 16 | final class OktaSdkConstant { 17 | 18 | /** ======== Keys ======== **/ 19 | 20 | static final String RESOLVE_TYPE_KEY = "resolve_type"; 21 | 22 | static final String ACCESS_TOKEN_KEY = "access_token"; 23 | 24 | static final String ID_TOKEN_KEY = "id_token"; 25 | 26 | static final String REFRESH_TOKEN_KEY = "refresh_token"; 27 | 28 | static final String AUTHENTICATED_KEY = "authenticated"; 29 | 30 | static final String ERROR_CODE_KEY = "error_code"; 31 | 32 | static final String ERROR_MSG_KEY = "error_message"; 33 | 34 | static final String ERROR_STACK_TRACE_KEY = "error_stack_trace"; 35 | 36 | static final String ACTIVE_KEY = "active"; 37 | 38 | static final String TOKEN_TYPE_KEY = "token_type"; 39 | 40 | static final String SCOPE_KEY = "scope"; 41 | 42 | static final String CLIENT_ID_KEY = "client_id"; 43 | 44 | static final String DEVICE_ID_KEY = "device_id"; 45 | 46 | static final String USERNAME_KEY = "username"; 47 | 48 | static final String NBF_KEY = "nbf"; 49 | 50 | static final String EXP_KEY = "exp"; 51 | 52 | static final String IAT_KEY = "iat"; 53 | 54 | static final String SUB_KEY = "sub"; 55 | 56 | static final String AUD_KEY = "aud"; 57 | 58 | static final String ISS_KEY = "iss"; 59 | 60 | static final String JTI_KEY = "jti"; 61 | 62 | static final String UID_KEY = "uid"; 63 | 64 | /** ======== Values ======== **/ 65 | 66 | static final String AUTHORIZED = "authorized"; 67 | 68 | static final String SIGNED_OUT = "signed_out"; 69 | 70 | static final String CANCELLED = "cancelled"; 71 | 72 | /** ======== Event names ======== **/ 73 | 74 | static final String SIGN_IN_SUCCESS = "signInSuccess"; 75 | 76 | static final String ON_ERROR = "onError"; 77 | 78 | static final String SIGN_OUT_SUCCESS = "signOutSuccess"; 79 | 80 | static final String ON_CANCELLED = "onCancelled"; 81 | 82 | private OktaSdkConstant() { 83 | throw new AssertionError(); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /e2e/android/app/src/androidTest/java/com/e2eoktareactnative/customlogin/CustomLoginPage.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023-Present Okta, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.e2eoktareactnative.customlogin 17 | 18 | import androidx.test.uiautomator.UiSelector 19 | import com.e2eoktareactnative.dashboard.DashboardPage 20 | import com.e2eoktareactnative.test.applyOnViewWithSelector 21 | import com.e2eoktareactnative.test.clickButtonWithText 22 | import com.e2eoktareactnative.test.setTextForIndex 23 | import com.e2eoktareactnative.test.waitForText 24 | import org.hamcrest.CoreMatchers.equalTo 25 | import org.hamcrest.MatcherAssert.assertThat 26 | import kotlin.time.Duration.Companion.seconds 27 | 28 | internal class CustomLoginPage { 29 | init { 30 | waitForText("CustomLogin", timeout = 10L.seconds.inWholeMilliseconds) 31 | } 32 | 33 | fun username(username: String): CustomLoginPage { 34 | setTextForIndex(0, username) 35 | return this 36 | } 37 | 38 | fun password(password: String): CustomLoginPage { 39 | setTextForIndex(1, password) 40 | return this 41 | } 42 | 43 | fun login(): DashboardPage { 44 | clickButtonWithText("SIGN IN") 45 | return DashboardPage() 46 | } 47 | 48 | fun loginExpectingError(): CustomLoginPage { 49 | clickButtonWithText("SIGN IN") 50 | return this 51 | } 52 | 53 | fun assertHasError(error: String): CustomLoginPage { 54 | waitForText(error) 55 | return this 56 | } 57 | 58 | fun pressAlertOkButton(): CustomLoginPage { 59 | applyOnViewWithSelector(UiSelector().text("OK")) { uiObject -> 60 | assertThat(uiObject.waitForExists(10.seconds.inWholeMilliseconds), equalTo(true)) 61 | // Checking if clicking "OK" was successful doesn't work on CI device. As an alternative, 62 | // click OK button, and check if the button is no longer visible afterwards 63 | uiObject.click() 64 | assertThat(uiObject.waitForExists(2.seconds.inWholeMilliseconds), equalTo(false)) 65 | } 66 | waitForText("CustomLogin", timeout = 10.seconds.inWholeMilliseconds) 67 | return this 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /e2e/ios/E2EOktaReactNative/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CADisableMinimumFrameDurationOnPhone 6 | 7 | CFBundleDevelopmentRegion 8 | $(DEVELOPMENT_LANGUAGE) 9 | CFBundleDisplayName 10 | E2E-Okta-React-Native 11 | CFBundleExecutable 12 | $(EXECUTABLE_NAME) 13 | CFBundleIdentifier 14 | $(PRODUCT_BUNDLE_IDENTIFIER) 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | $(PRODUCT_NAME) 19 | CFBundlePackageType 20 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 21 | CFBundleShortVersionString 22 | 1.0.0 23 | CFBundleSignature 24 | ???? 25 | CFBundleURLTypes 26 | 27 | 28 | CFBundleURLSchemes 29 | 30 | com.e2eoktareactnative 31 | 32 | 33 | 34 | CFBundleVersion 35 | 1 36 | LSRequiresIPhoneOS 37 | 38 | NSAppTransportSecurity 39 | 40 | NSAllowsArbitraryLoads 41 | 42 | NSAllowsLocalNetworking 43 | 44 | 45 | UILaunchStoryboardName 46 | SplashScreen 47 | UIRequiredDeviceCapabilities 48 | 49 | armv64 50 | 51 | UIRequiresFullScreen 52 | 53 | UIStatusBarStyle 54 | UIStatusBarStyleDefault 55 | UISupportedInterfaceOrientations 56 | 57 | UIInterfaceOrientationPortrait 58 | UIInterfaceOrientationPortraitUpsideDown 59 | UIInterfaceOrientationLandscapeLeft 60 | UIInterfaceOrientationLandscapeRight 61 | 62 | UISupportedInterfaceOrientations~ipad 63 | 64 | UIInterfaceOrientationPortrait 65 | UIInterfaceOrientationPortraitUpsideDown 66 | UIInterfaceOrientationLandscapeLeft 67 | UIInterfaceOrientationLandscapeRight 68 | 69 | UIUserInterfaceStyle 70 | Automatic 71 | UIViewControllerBasedStatusBarAppearance 72 | 73 | 74 | -------------------------------------------------------------------------------- /e2e/ios/Podfile: -------------------------------------------------------------------------------- 1 | require File.join(File.dirname(`node --print "require.resolve('expo/package.json')"`), "scripts/autolinking") 2 | require File.join(File.dirname(`node --print "require.resolve('react-native/package.json')"`), "scripts/react_native_pods") 3 | 4 | require 'json' 5 | podfile_properties = JSON.parse(File.read(File.join(__dir__, 'Podfile.properties.json'))) rescue {} 6 | 7 | ENV['RCT_NEW_ARCH_ENABLED'] = podfile_properties['newArchEnabled'] == 'true' ? '1' : '0' 8 | ENV['EX_DEV_CLIENT_NETWORK_INSPECTOR'] = podfile_properties['EX_DEV_CLIENT_NETWORK_INSPECTOR'] 9 | 10 | platform :ios, podfile_properties['ios.deploymentTarget'] || '15.1' 11 | install! 'cocoapods', 12 | :deterministic_uuids => false 13 | 14 | prepare_react_native_project! 15 | 16 | target 'E2EOktaReactNative' do 17 | use_expo_modules! 18 | 19 | if ENV['EXPO_USE_COMMUNITY_AUTOLINKING'] == '1' 20 | config_command = ['node', '-e', "process.argv=['', '', 'config'];require('@react-native-community/cli').run()"]; 21 | else 22 | config_command = [ 23 | 'node', 24 | '--no-warnings', 25 | '--eval', 26 | 'require(require.resolve(\'expo-modules-autolinking\', { paths: [require.resolve(\'expo/package.json\')] }))(process.argv.slice(1))', 27 | 'react-native-config', 28 | '--json', 29 | '--platform', 30 | 'ios' 31 | ] 32 | end 33 | 34 | config = use_native_modules!(config_command) 35 | 36 | use_frameworks! :linkage => podfile_properties['ios.useFrameworks'].to_sym if podfile_properties['ios.useFrameworks'] 37 | use_frameworks! :linkage => ENV['USE_FRAMEWORKS'].to_sym if ENV['USE_FRAMEWORKS'] 38 | 39 | use_react_native!( 40 | :path => config[:reactNativePath], 41 | :hermes_enabled => podfile_properties['expo.jsEngine'] == nil || podfile_properties['expo.jsEngine'] == 'hermes', 42 | # An absolute path to your application root. 43 | :app_path => "#{Pod::Config.instance.installation_root}/..", 44 | :privacy_file_aggregation_enabled => podfile_properties['apple.privacyManifestAggregationEnabled'] != 'false', 45 | ) 46 | 47 | post_install do |installer| 48 | react_native_post_install( 49 | installer, 50 | config[:reactNativePath], 51 | :mac_catalyst_enabled => false, 52 | :ccache_enabled => podfile_properties['apple.ccacheEnabled'] == 'true', 53 | ) 54 | 55 | # This is necessary for Xcode 14, because it signs resource bundles by default 56 | # when building for devices. 57 | installer.target_installation_results.pod_target_installation_results 58 | .each do |pod_name, target_installation_result| 59 | target_installation_result.resource_bundle_targets.each do |resource_bundle_target| 60 | resource_bundle_target.build_configurations.each do |config| 61 | config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO' 62 | end 63 | end 64 | end 65 | end 66 | end 67 | -------------------------------------------------------------------------------- /ios/Tests/OktaReactNativeErrorTests.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021-Present, Okta, Inc. and/or its affiliates. All rights reserved. 3 | * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.") 4 | * 5 | * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. 6 | * Unless required by applicable law or agreed to in writing, software 7 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 8 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 | * 10 | * See the License for the specific language governing permissions and limitations under the License. 11 | */ 12 | 13 | import XCTest 14 | @testable import ReactNativeOktaSdkBridge 15 | 16 | final class OktaReactNativeErrorTests: XCTestCase { 17 | func testLocalizedDescription() { 18 | XCTAssertEqual(OktaReactNativeError.notConfigured.localizedDescription, "OktaOidc client isn't configured, check if you have created a configuration with createConfig") 19 | XCTAssertEqual(OktaReactNativeError.noView.localizedDescription, "No current view exists") 20 | XCTAssertEqual(OktaReactNativeError.unauthenticated.localizedDescription, "User is not authenticated, cannot perform the specific action") 21 | XCTAssertEqual(OktaReactNativeError.noStateManager.localizedDescription, "State Manager does not exist.") 22 | XCTAssertEqual(OktaReactNativeError.noIdToken.localizedDescription, "Id token does not exist") 23 | XCTAssertEqual(OktaReactNativeError.oktaOidcError.localizedDescription, "Okta Oidc error") 24 | XCTAssertEqual(OktaReactNativeError.errorTokenType.localizedDescription, "Token type not found") 25 | XCTAssertEqual(OktaReactNativeError.errorPayload.localizedDescription, "Error in retrieving payload") 26 | XCTAssertEqual(OktaReactNativeError.noAccessToken.localizedDescription, "No access token found") 27 | XCTAssertEqual(OktaReactNativeError.cancelled.localizedDescription, "User cancelled a session") 28 | } 29 | 30 | func testErrorCode() { 31 | XCTAssertEqual(OktaReactNativeError.notConfigured.errorCode, "-100") 32 | XCTAssertEqual(OktaReactNativeError.noView.errorCode, "-200") 33 | XCTAssertEqual(OktaReactNativeError.unauthenticated.errorCode, "-300") 34 | XCTAssertEqual(OktaReactNativeError.noStateManager.errorCode, "-400") 35 | XCTAssertEqual(OktaReactNativeError.noIdToken.errorCode, "-500") 36 | XCTAssertEqual(OktaReactNativeError.oktaOidcError.errorCode, "-600") 37 | XCTAssertEqual(OktaReactNativeError.errorTokenType.errorCode, "-700") 38 | XCTAssertEqual(OktaReactNativeError.errorPayload.errorCode, "-800") 39 | XCTAssertEqual(OktaReactNativeError.noAccessToken.errorCode, "-900") 40 | XCTAssertEqual(OktaReactNativeError.cancelled.errorCode, "-1200") 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | // https://eslint.org/docs/user-guide/configuring 2 | 3 | module.exports = { 4 | ignorePatterns: ['node_modules/', 'dist/', 'e2e'], 5 | extends: [ 6 | 'eslint:recommended', 7 | 'plugin:node/recommended-script', 8 | 'plugin:jest/recommended', 9 | ], 10 | rules: { 11 | 'semi': ['error', 'always'], 12 | 'indent': ['error', 2], 13 | 'no-var': 0, 14 | 'prefer-rest-params': 0, 15 | 'prefer-spread': 0, 16 | 'prefer-const': 0, 17 | 'node/no-unpublished-require': 0, 18 | 'node/no-unpublished-import': 0, 19 | 'camelcase': 2, 20 | 'complexity': [2, 7], 21 | 'curly': 2, 22 | 'dot-notation': 0, 23 | 'guard-for-in': 2, 24 | 'new-cap': [2, { 'properties': false }], 25 | 'no-caller': 2, 26 | 'no-empty': 2, 27 | 'no-eval': 2, 28 | 'no-implied-eval': 2, 29 | 'no-multi-str': 0, 30 | 'no-new': 2, 31 | 'no-plusplus': 0, 32 | 'no-undef': 2, 33 | 'no-unused-expressions': [2, { 'allowShortCircuit': true, 'allowTernary': true }], 34 | 'no-unused-vars': 2, 35 | 'max-depth': [2, 3], 36 | 'max-len': [2, 150], 37 | 'max-params': [2, 5], 38 | 'max-statements': [2, 25], 39 | 'quotes': [2, 'single', { 'allowTemplateLiterals': true }], 40 | 'strict': 0, 41 | 'wrap-iife': [2, 'any'], 42 | }, 43 | overrides: [ 44 | { 45 | files: ['*.ts', '*.tsx'], 46 | extends: [ 47 | 'plugin:@typescript-eslint/eslint-recommended', 48 | 'plugin:@typescript-eslint/recommended' 49 | ], 50 | parser: '@typescript-eslint/parser', 51 | parserOptions: { 52 | ecmaVersion: 2020, 53 | ecmaFeatures: { 'jsx': true }, 54 | sourceType: 'module', 55 | project: 'types/tsconfig.json' 56 | }, 57 | env: { 58 | es6: true, 59 | node: false 60 | }, 61 | plugins: ['@typescript-eslint'], 62 | rules: { 63 | 'node/no-unsupported-features/es-syntax': 0, 64 | 'node/no-unsupported-features/node-builtins': 0 65 | } 66 | }, 67 | { 68 | // ES6 processed by Babel 69 | files: [ 70 | '*.js', 71 | '*.test.js' 72 | ], 73 | plugins: [ 74 | 'node', 75 | 'jest', 76 | ], 77 | parser: '@babel/eslint-parser', 78 | parserOptions: { 79 | ecmaVersion: 2020, 80 | sourceType: 'module' 81 | }, 82 | env: { 83 | es6: true, 84 | node: false 85 | }, 86 | rules: { 87 | 'node/no-unsupported-features/es-syntax': 0, 88 | 'node/no-unsupported-features/node-builtins': 0 89 | } 90 | }, 91 | { 92 | // Jest specs 93 | files: ['*.test.js'], 94 | plugins: [ 95 | 'node', 96 | 'jest', 97 | ], 98 | env: { 99 | jest: true 100 | } 101 | } 102 | ] 103 | }; 104 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Okta Open Source Repos 2 | 3 | Thank you for your interest in contributing to Okta's Open Source Projects! Before submitting a PR, please take a moment to read over our [Contributer License Agreement](https://developer.okta.com/cla/). In certain cases, we ask that you [sign a CLA](https://developer.okta.com/sites/all/themes/developer/pdf/okta_individual_contributor_license_agreement_2016-11.pdf) before we merge your pull request. 4 | 5 | - [Commit Message Guidelines](#commit-message-guidelines) 6 | * [Git Commit Messages](#git-commit-messages) 7 | * [Template](#template) 8 | * [Template for specific package change](#template-for-specific-package-change) 9 | * [Type](#type) 10 | * [Example](#example) 11 | * [Example for specific package change](#example-for-specific-package-change) 12 | * [Breaking changes](#breaking-changes) 13 | * [Example for a breaking change](#example-for-a-breaking-change) 14 | 15 | ## Commit Message Guidelines 16 | 17 | ### Git Commit Messages 18 | 19 | We use an adapted form of [Conventional Commits](http://conventionalcommits.org/). 20 | 21 | * Use the present tense ("Adds feature" not "Added feature") 22 | * Limit the first line to 72 characters or less 23 | * Add one feature per commit. If you have multiple features, have multiple commits. 24 | 25 | ### Template 26 | 27 | : Short Description of Commit 28 | 29 | More detailed description of commit 30 | 31 | (Optional) Resolves: 32 | 33 | ### Template for specific package change 34 | 35 | []: Short Description of Commit 36 | 37 | More detailed description of commit 38 | 39 | (Optional) Resolves: 40 | 41 | ### Type 42 | Our types include: 43 | * `feat` when creating a new feature 44 | * `fix` when fixing a bug 45 | * `test` when adding tests 46 | * `refactor` when improving the format/structure of the code 47 | * `docs` when writing docs 48 | * `release` when pushing a new release 49 | * `chore` others (ex: upgrading/downgrading dependencies) 50 | 51 | 52 | ### Example 53 | 54 | docs: Updates CONTRIBUTING.md 55 | 56 | Updates Contributing.md with new emoji categories 57 | Updates Contributing.md with new template 58 | 59 | Resolves: #1234 60 | 61 | ### Example for specific package change 62 | fix[okta-angular]: Fixes bad bug 63 | 64 | Fixes a very bad bug in okta-angular 65 | 66 | Resolves: #5678 67 | 68 | ### Breaking changes 69 | 70 | * Breaking changes MUST be indicated at the very beginning of the body section of a commit. A breaking change MUST consist of the uppercase text `BREAKING CHANGE`, followed by a colon and a space. 71 | * A description MUST be provided after the `BREAKING CHANGE:`, describing what has changed about the API. 72 | 73 | ### Example for a breaking change 74 | 75 | feat: Allows provided config object to extend other configs 76 | 77 | BREAKING CHANGE: `extends` key in config file is now used for extending other config files 78 | -------------------------------------------------------------------------------- /ios/OktaSdkBridge/OktaSDKError.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-Present, Okta, Inc. and/or its affiliates. All rights reserved. 3 | * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.") 4 | * 5 | * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. 6 | * Unless required by applicable law or agreed to in writing, software 7 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 8 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 | * 10 | * See the License for the specific language governing permissions and limitations under the License. 11 | */ 12 | 13 | import Foundation 14 | 15 | public enum OktaReactNativeError: Error { 16 | case notConfigured 17 | case noView 18 | case unauthenticated 19 | case noStateManager 20 | case noIdToken 21 | case oktaOidcError 22 | case errorTokenType 23 | case errorPayload 24 | case noAccessToken 25 | case cancelled 26 | } 27 | 28 | extension OktaReactNativeError: LocalizedError { 29 | public var errorDescription: String? { 30 | switch self { 31 | case .notConfigured: 32 | return NSLocalizedString("OktaOidc client isn't configured, check if you have created a configuration with createConfig", comment: "") 33 | case .noView: 34 | return NSLocalizedString("No current view exists", comment: "") 35 | case .unauthenticated: 36 | return NSLocalizedString("User is not authenticated, cannot perform the specific action", comment: "") 37 | case .noStateManager: 38 | return NSLocalizedString("State Manager does not exist.", comment: "") 39 | case .noIdToken: 40 | return NSLocalizedString("Id token does not exist", comment: "") 41 | case .oktaOidcError: 42 | return NSLocalizedString("Okta Oidc error", comment: "") 43 | case .errorTokenType: 44 | return NSLocalizedString("Token type not found", comment: "") 45 | case .errorPayload: 46 | return NSLocalizedString("Error in retrieving payload", comment: "") 47 | case .noAccessToken: 48 | return NSLocalizedString("No access token found", comment: "") 49 | case .cancelled: 50 | return NSLocalizedString("User cancelled a session", comment: "") 51 | } 52 | } 53 | public var errorCode: String? { 54 | switch self { 55 | case .notConfigured: 56 | return "-100" 57 | case .noView: 58 | return "-200" 59 | case .unauthenticated: 60 | return "-300" 61 | case .noStateManager: 62 | return "-400" 63 | case .noIdToken: 64 | return "-500" 65 | case .oktaOidcError: 66 | return "-600" 67 | case .errorTokenType: 68 | return "-700" 69 | case .errorPayload: 70 | return "-800" 71 | case .noAccessToken: 72 | return "-900" 73 | case .cancelled: 74 | return "-1200" 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%"=="" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%"=="" set DIRNAME=. 29 | @rem This is normally unused 30 | set APP_BASE_NAME=%~n0 31 | set APP_HOME=%DIRNAME% 32 | 33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 35 | 36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 38 | 39 | @rem Find java.exe 40 | if defined JAVA_HOME goto findJavaFromJavaHome 41 | 42 | set JAVA_EXE=java.exe 43 | %JAVA_EXE% -version >NUL 2>&1 44 | if %ERRORLEVEL% equ 0 goto execute 45 | 46 | echo. 1>&2 47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 48 | echo. 1>&2 49 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 50 | echo location of your Java installation. 1>&2 51 | 52 | goto fail 53 | 54 | :findJavaFromJavaHome 55 | set JAVA_HOME=%JAVA_HOME:"=% 56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 57 | 58 | if exist "%JAVA_EXE%" goto execute 59 | 60 | echo. 1>&2 61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 62 | echo. 1>&2 63 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 64 | echo location of your Java installation. 1>&2 65 | 66 | goto fail 67 | 68 | :execute 69 | @rem Setup the command line 70 | 71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 72 | 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if %ERRORLEVEL% equ 0 goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | set EXIT_CODE=%ERRORLEVEL% 85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 87 | exit /b %EXIT_CODE% 88 | 89 | :mainEnd 90 | if "%OS%"=="Windows_NT" endlocal 91 | 92 | :omega 93 | -------------------------------------------------------------------------------- /e2e/android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | @rem SPDX-License-Identifier: Apache-2.0 17 | @rem 18 | 19 | @if "%DEBUG%"=="" @echo off 20 | @rem ########################################################################## 21 | @rem 22 | @rem Gradle startup script for Windows 23 | @rem 24 | @rem ########################################################################## 25 | 26 | @rem Set local scope for the variables with windows NT shell 27 | if "%OS%"=="Windows_NT" setlocal 28 | 29 | set DIRNAME=%~dp0 30 | if "%DIRNAME%"=="" set DIRNAME=. 31 | @rem This is normally unused 32 | set APP_BASE_NAME=%~n0 33 | set APP_HOME=%DIRNAME% 34 | 35 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 36 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 37 | 38 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 39 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 40 | 41 | @rem Find java.exe 42 | if defined JAVA_HOME goto findJavaFromJavaHome 43 | 44 | set JAVA_EXE=java.exe 45 | %JAVA_EXE% -version >NUL 2>&1 46 | if %ERRORLEVEL% equ 0 goto execute 47 | 48 | echo. 1>&2 49 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 50 | echo. 1>&2 51 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 52 | echo location of your Java installation. 1>&2 53 | 54 | goto fail 55 | 56 | :findJavaFromJavaHome 57 | set JAVA_HOME=%JAVA_HOME:"=% 58 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 59 | 60 | if exist "%JAVA_EXE%" goto execute 61 | 62 | echo. 1>&2 63 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 64 | echo. 1>&2 65 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 66 | echo location of your Java installation. 1>&2 67 | 68 | goto fail 69 | 70 | :execute 71 | @rem Setup the command line 72 | 73 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 74 | 75 | 76 | @rem Execute Gradle 77 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 78 | 79 | :end 80 | @rem End local scope for the variables with windows NT shell 81 | if %ERRORLEVEL% equ 0 goto mainEnd 82 | 83 | :fail 84 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 85 | rem the _cmd.exe /c_ return code! 86 | set EXIT_CODE=%ERRORLEVEL% 87 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 88 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 89 | exit /b %EXIT_CODE% 90 | 91 | :mainEnd 92 | if "%OS%"=="Windows_NT" endlocal 93 | 94 | :omega 95 | -------------------------------------------------------------------------------- /types/index.test-d.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021-Present, Okta, Inc. and/or its affiliates. All rights reserved. 3 | * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.") 4 | * 5 | * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. 6 | * Unless required by applicable law or agreed to in writing, software 7 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 8 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 | * 10 | * See the License for the specific language governing permissions and limitations under the License. 11 | */ 12 | 13 | 14 | /* eslint-disable node/no-missing-import, camelcase */ 15 | import OktaSDK, { Okta } from './index'; 16 | import { expectType } from 'tsd'; 17 | import { OktaAuth } from '@okta/okta-auth-js'; 18 | 19 | expectType>(OktaSDK.createConfig({ 20 | issuer: '{issuer}', 21 | clientId: '{clientID}', 22 | redirectUri: '{redirectUri}', 23 | endSessionRedirectUri: '{endSessionRedirectUri}', 24 | discoveryUri: '{discoveryUri}', 25 | scopes: ['scope1', 'scope2'], 26 | requireHardwareBackedKeyStore: false, 27 | androidChromeTabColor: '#00000', 28 | httpConnectionTimeout: 15, 29 | httpReadTimeout: 10, 30 | browserMatchAll: false, 31 | oktaAuthConfig: { issuer: '{issuer}' } 32 | })); 33 | 34 | expectType(OktaSDK.getAuthClient()); 35 | 36 | expectType>(OktaSDK.signIn()); 37 | 38 | expectType>(OktaSDK.signIn({ username: '{username}', password: '{password}' })); 39 | 40 | expectType>(OktaSDK.signInWithBrowser()); 41 | 42 | expectType>(OktaSDK.signInWithBrowser({ idp: '{idp}' })); 43 | 44 | expectType>(OktaSDK.signInWithBrowser({ noSSO: true })); 45 | 46 | expectType>(OktaSDK.signInWithBrowser({ login_hint: 'some@email.com' })); 47 | 48 | expectType>(OktaSDK.signInWithBrowser({ prompt: 'Prompt' })); 49 | 50 | expectType>(OktaSDK.authenticate({ sessionToken: 'sessionToken' })); 51 | 52 | expectType>(OktaSDK.signOut()); 53 | 54 | expectType>(OktaSDK.getIdToken()); 55 | 56 | expectType>(OktaSDK.getAccessToken()); 57 | 58 | expectType>(OktaSDK.getUser()); 59 | 60 | expectType>(OktaSDK.getUserFromIdToken()); 61 | 62 | expectType>(OktaSDK.isAuthenticated()); 63 | 64 | expectType>(OktaSDK.revokeAccessToken()); 65 | 66 | expectType>(OktaSDK.revokeIdToken()); 67 | 68 | expectType>(OktaSDK.revokeRefreshToken()); 69 | 70 | expectType>(OktaSDK.introspectAccessToken()); 71 | 72 | expectType>(OktaSDK.introspectIdToken()); 73 | 74 | expectType>(OktaSDK.introspectRefreshToken()); 75 | 76 | expectType>(OktaSDK.refreshTokens()); 77 | 78 | expectType>(OktaSDK.clearTokens()); 79 | -------------------------------------------------------------------------------- /e2e/android/app/src/androidTest/java/com/e2eoktareactnative/test/UiAutomationHelpers.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023-Present Okta, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.e2eoktareactnative.test 17 | 18 | import android.widget.EditText 19 | import androidx.test.platform.app.InstrumentationRegistry 20 | import androidx.test.uiautomator.UiDevice 21 | import androidx.test.uiautomator.UiObject 22 | import androidx.test.uiautomator.UiSelector 23 | import org.hamcrest.CoreMatchers.equalTo 24 | import org.hamcrest.MatcherAssert.assertThat 25 | import kotlin.time.Duration.Companion.seconds 26 | 27 | fun clickButtonWithText(text: String, timeout: Long? = null) { 28 | clickButtonWithSelector(UiSelector().text(text), timeout) 29 | } 30 | 31 | fun clickButtonWithTextMatching(text: String, timeout: Long? = null) { 32 | clickButtonWithSelector(UiSelector().textMatches(text), timeout) 33 | } 34 | 35 | fun clickButtonWithSelector(selector: UiSelector, timeout: Long? = null) { 36 | applyOnViewWithSelector(selector) { uiObject -> 37 | timeout?.let { 38 | assertThat(uiObject.waitForExists(timeout), equalTo(true)) 39 | } 40 | assertThat(uiObject.click(), equalTo(true)) 41 | } 42 | } 43 | 44 | fun setTextForIndex(index: Int, text: String) { 45 | val uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) 46 | val selector = UiSelector().className(EditText::class.java).instance(index) 47 | assertThat(uiDevice.findObject(selector).setText(text), equalTo(true)) 48 | } 49 | 50 | fun waitForText(text: String, timeout: Long = 10.seconds.inWholeMilliseconds) { 51 | waitForViewWithSelector(UiSelector().text(text), timeout) 52 | } 53 | 54 | fun waitForTextMatching(text: String, timeout: Long = 10.seconds.inWholeMilliseconds) { 55 | waitForViewWithSelector(UiSelector().textMatches(text), timeout) 56 | } 57 | 58 | fun waitForResourceIdWithText(resourceId: String, text: String, timeout: Long = 10.seconds.inWholeMilliseconds) { 59 | waitForViewWithSelector(UiSelector().resourceIdMatches(resourceId).text(text), timeout) 60 | } 61 | 62 | fun waitForResourceId(resourceId: String, timeout: Long = 10.seconds.inWholeMilliseconds) { 63 | waitForViewWithSelector(UiSelector().resourceIdMatches(resourceId), timeout) 64 | } 65 | 66 | fun waitForViewWithSelector(selector: UiSelector, timeout: Long = 10.seconds.inWholeMilliseconds) { 67 | applyOnViewWithSelector(selector) { uiObject -> 68 | assertThat(uiObject.waitForExists(timeout), equalTo(true)) 69 | } 70 | } 71 | 72 | fun applyOnViewWithSelector(selector: UiSelector, uiObjectFunction: (UiObject) -> Unit) { 73 | val uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) 74 | uiObjectFunction(uiDevice.findObject(selector)) 75 | } 76 | -------------------------------------------------------------------------------- /e2e/pages/ProfilePage.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021-Present, Okta, Inc. and/or its affiliates. All rights reserved. 3 | * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.") 4 | * 5 | * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. 6 | * Unless required by applicable law or agreed to in writing, software 7 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 8 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 | * 10 | * See the License for the specific language governing permissions and limitations under the License. 11 | */ 12 | 13 | /* eslint-disable no-unused-vars */ 14 | /* eslint-disable node/no-missing-import */ 15 | 16 | import React from 'react'; 17 | import { 18 | Text, 19 | Button, 20 | StyleSheet, 21 | TextInput, 22 | View, 23 | } from 'react-native'; 24 | 25 | import { 26 | signOut, 27 | revokeAccessToken, 28 | revokeIdToken, 29 | clearTokens, 30 | getAccessToken, 31 | getAuthClient, 32 | } from '@okta/okta-react-native'; 33 | 34 | export default class ProfilePage extends React.Component { 35 | constructor(props) { 36 | super(props); 37 | 38 | this.state = { 39 | idToken: props.route.params.idToken, 40 | isBrowserScenario: props.route.params.isBrowserScenario, 41 | userInfo: {} 42 | }; 43 | } 44 | 45 | async getUserInfo() { 46 | const oktaAuth = getAuthClient(); 47 | const issuer = oktaAuth.options.issuer; 48 | const baseUrl = issuer.indexOf('/oauth2') > 0 ? issuer : issuer + '/oauth2'; 49 | const accessToken = await getAccessToken(); 50 | const url = baseUrl + '/v1/userinfo'; 51 | const headers = { 52 | 'Authorization': 'Bearer ' + accessToken.access_token 53 | }; 54 | const resp = await fetch(url, { 55 | method: 'GET', 56 | headers, 57 | }); 58 | const userInfo = await resp.json(); 59 | this.setState({ 60 | ...this.state, 61 | userInfo, 62 | }); 63 | } 64 | 65 | componentDidMount() { 66 | this.getUserInfo(); 67 | } 68 | 69 | logout = () => { 70 | if (this.state.isBrowserScenario == true) { 71 | signOut().then(() => { 72 | this.props.navigation.popToTop(); 73 | }).catch(error => { 74 | console.log(error); 75 | }); 76 | } 77 | 78 | Promise.all([revokeAccessToken(), clearTokens()]) 79 | .then(() => { 80 | this.props.navigation.popToTop(); 81 | }).catch(error => { 82 | console.log(error); 83 | }); 84 | } 85 | 86 | render() { 87 | const userName = this.state.userInfo.name; 88 | const preferredUserName = this.state.userInfo.preferred_username; 89 | return ( 90 | 91 | {userName && User: {userName}} 92 | Welcome back, {preferredUserName}! 93 |