├── .circleci ├── android_sdk_checksum └── config.yml ├── .github ├── ISSUE_TEMPLATE │ ├── bug-report.yml │ ├── config.yml │ └── feature-request.yml └── SECURITY.md ├── .gitignore ├── .travis.yml ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── browser-sign-in ├── .eslintrc.js ├── .gitattributes ├── .vscode │ └── launch.json ├── App.js ├── README.md ├── android │ ├── .gitignore │ ├── app │ │ ├── build.gradle │ │ ├── debug.keystore │ │ ├── proguard-rules.pro │ │ └── src │ │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ └── com │ │ │ │ └── browsersignin │ │ │ │ ├── MainActivity.kt │ │ │ │ └── MainApplication.kt │ │ │ └── res │ │ │ ├── drawable-hdpi │ │ │ └── splashscreen_logo.png │ │ │ ├── drawable-mdpi │ │ │ └── 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 │ │ │ ├── drawable-xhdpi │ │ │ └── splashscreen_logo.png │ │ │ ├── drawable-xxhdpi │ │ │ └── splashscreen_logo.png │ │ │ ├── drawable-xxxhdpi │ │ │ └── splashscreen_logo.png │ │ │ ├── drawable │ │ │ ├── ic_launcher_background.xml │ │ │ └── rn_edit_text_material.xml │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_foreground.webp │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_foreground.webp │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_foreground.webp │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_foreground.webp │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_foreground.webp │ │ │ ├── values-night │ │ │ └── colors.xml │ │ │ └── values │ │ │ ├── colors.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle ├── app.json ├── app_logo.png ├── babel.config.js ├── index.js ├── ios │ ├── .gitignore │ ├── .xcode.env │ ├── Podfile │ ├── Podfile.lock │ ├── Podfile.properties.json │ ├── browserSignIn.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── browserSignIn.xcscheme │ ├── browserSignIn.xcworkspace │ │ └── contents.xcworkspacedata │ └── browserSignIn │ │ ├── AppDelegate.h │ │ ├── AppDelegate.mm │ │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── App-Icon-1024x1024@1x.png │ │ │ └── Contents.json │ │ ├── Contents.json │ │ ├── SplashScreenBackground.colorset │ │ │ └── Contents.json │ │ └── SplashScreenLogo.imageset │ │ │ ├── Contents.json │ │ │ ├── dark_image.png │ │ │ ├── dark_image@2x.png │ │ │ ├── dark_image@3x.png │ │ │ ├── image.png │ │ │ ├── image@2x.png │ │ │ └── image@3x.png │ │ ├── Info.plist │ │ ├── PrivacyInfo.xcprivacy │ │ ├── SplashScreen.storyboard │ │ ├── Supporting │ │ └── Expo.plist │ │ ├── browserSignIn-Bridging-Header.h │ │ ├── browserSignIn.entitlements │ │ ├── main.m │ │ └── noop-file.swift ├── metro.config.js ├── package.json ├── samples.config.js ├── setupJest.js ├── test │ ├── .eslintrc.js │ ├── App.test.js │ └── __snapshots__ │ │ └── App.test.js.snap ├── tsconfig.json └── yarn.lock ├── custom-sign-in ├── .eslintrc.js ├── .gitattributes ├── .vscode │ └── launch.json ├── App.js ├── README.md ├── android │ ├── .gitignore │ ├── app │ │ ├── build.gradle │ │ ├── debug.keystore │ │ ├── proguard-rules.pro │ │ └── src │ │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ └── com │ │ │ │ └── customsignin │ │ │ │ ├── MainActivity.kt │ │ │ │ └── MainApplication.kt │ │ │ └── res │ │ │ ├── drawable-hdpi │ │ │ └── splashscreen_logo.png │ │ │ ├── drawable-mdpi │ │ │ └── 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 │ │ │ ├── drawable-xhdpi │ │ │ └── splashscreen_logo.png │ │ │ ├── drawable-xxhdpi │ │ │ └── splashscreen_logo.png │ │ │ ├── drawable-xxxhdpi │ │ │ └── splashscreen_logo.png │ │ │ ├── drawable │ │ │ ├── ic_launcher_background.xml │ │ │ └── rn_edit_text_material.xml │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_foreground.webp │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_foreground.webp │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_foreground.webp │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_foreground.webp │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_foreground.webp │ │ │ ├── values-night │ │ │ └── colors.xml │ │ │ └── values │ │ │ ├── colors.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle ├── app.json ├── app │ ├── LoginScreen.js │ ├── ProfileScreen.js │ └── components │ │ └── Error.js ├── app_logo.png ├── babel.config.js ├── index.js ├── ios │ ├── .gitignore │ ├── .xcode.env │ ├── CustomSignIn.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── CustomSignIn.xcscheme │ ├── CustomSignIn.xcworkspace │ │ └── contents.xcworkspacedata │ ├── CustomSignIn │ │ ├── AppDelegate.h │ │ ├── AppDelegate.mm │ │ ├── CustomSignIn-Bridging-Header.h │ │ ├── CustomSignIn.entitlements │ │ ├── Images.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ ├── App-Icon-1024x1024@1x.png │ │ │ │ └── Contents.json │ │ │ ├── Contents.json │ │ │ ├── SplashScreenBackground.colorset │ │ │ │ └── Contents.json │ │ │ └── SplashScreenLogo.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── dark_image.png │ │ │ │ ├── dark_image@2x.png │ │ │ │ ├── dark_image@3x.png │ │ │ │ ├── image.png │ │ │ │ ├── image@2x.png │ │ │ │ └── image@3x.png │ │ ├── Info.plist │ │ ├── PrivacyInfo.xcprivacy │ │ ├── SplashScreen.storyboard │ │ ├── Supporting │ │ │ └── Expo.plist │ │ ├── main.m │ │ └── noop-file.swift │ ├── Podfile │ ├── Podfile.lock │ └── Podfile.properties.json ├── metro.config.js ├── package.json ├── samples.config.js └── yarn.lock ├── package.json ├── tools ├── create-config-file.js ├── license-banner.txt └── maintain-banners.js └── yarn.lock /.circleci/android_sdk_checksum: -------------------------------------------------------------------------------- 1 | 2d2d50857e4eb553af5a6dc3ad507a17adf43d115264b1afc116f95c92e5e258 android-commandline.zip 2 | -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | 3 | orbs: 4 | general-platform-helpers: okta/general-platform-helpers@1.9 5 | node: circleci/node@7.0.0 6 | 7 | executors: 8 | linux: 9 | machine: 10 | image: ubuntu-2404:current 11 | resource_class: xlarge 12 | 13 | commands: 14 | install_android_sdk: 15 | description: "Install Android SDK in macOS machine" 16 | steps: 17 | - run: wget --quiet --output-document="$HOME/android-commandline.zip" https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip 18 | - run: (cp .circleci/android_sdk_checksum $HOME/checksum; cd $HOME; shasum -a256 -c checksum) 19 | - run: set +o pipefail 20 | - run: unzip "$HOME/android-commandline.zip" -d "$HOME" 21 | - run: mkdir "$HOME/android-sdk" 22 | - run: echo y | $HOME/cmdline-tools/bin/sdkmanager --sdk_root="$HOME/android-sdk" "platforms;android-35" > /dev/null 23 | - run: echo y | $HOME/cmdline-tools/bin/sdkmanager --sdk_root="$HOME/android-sdk" "platform-tools" > /dev/null 24 | - run: echo y | $HOME/cmdline-tools/bin/sdkmanager --sdk_root="$HOME/android-sdk" "build-tools;35.0.0" > /dev/null 25 | - run: (yes || true) | $HOME/cmdline-tools/bin/sdkmanager --sdk_root="$HOME/android-sdk" --licenses 26 | - run: echo 'export ANDROID_HOME="$HOME/android-sdk"' >> "$BASH_ENV" 27 | - run: set -o pipefail 28 | 29 | setup: 30 | description: "Setup project for security scan" 31 | steps: 32 | - checkout 33 | - install_android_sdk 34 | - run: yarn install --frozen-lockfile 35 | - run: (cd browser-sign-in; yarn install --frozen-lockfile) 36 | - run: (cd browser-sign-in/android; ./gradlew assembleDebug) # Avoid gradle build during snyk scan 37 | - run: (cd custom-sign-in; yarn install --frozen-lockfile) 38 | - run: (cd custom-sign-in/android; ./gradlew assembleDebug) # Avoid gradle build during snyk scan 39 | 40 | jobs: 41 | snyk-scan: 42 | executor: linux 43 | steps: 44 | - setup 45 | - run: pip install setuptools 46 | - general-platform-helpers/step-load-dependencies 47 | - general-platform-helpers/step-run-snyk-monitor: 48 | run-on-non-main: true 49 | scan-all-projects: true 50 | skip-unresolved: false 51 | 52 | workflows: 53 | security-scan: 54 | jobs: 55 | - snyk-scan: 56 | name: execute-snyk 57 | context: 58 | - static-analysis 59 | filters: 60 | branches: 61 | only: 62 | - master -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-report.yml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: Report a bug you encountered with the Okta React Native Samples 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 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature-request.yml: -------------------------------------------------------------------------------- 1 | name: Feature Request 2 | description: Request a new feature for this sample? 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 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build2 2 | node_modules 3 | dist 4 | npm-debug.log 5 | travis_phantomjs 6 | test-reports 7 | 8 | ### VisualStudioCode ### 9 | .vscode/* 10 | !.vscode/launch.json 11 | 12 | # OSX 13 | # 14 | .DS_Store 15 | 16 | # Xcode 17 | # 18 | build/ 19 | *.pbxuser 20 | !default.pbxuser 21 | *.mode1v3 22 | !default.mode1v3 23 | *.mode2v3 24 | !default.mode2v3 25 | *.perspectivev3 26 | !default.perspectivev3 27 | xcuserdata 28 | *.xccheckout 29 | *.moved-aside 30 | DerivedData 31 | *.hmap 32 | *.ipa 33 | *.xcuserstate 34 | project.xcworkspace 35 | 36 | # Android/IntelliJ 37 | # 38 | build/ 39 | .idea 40 | .gradle 41 | local.properties 42 | *.iml 43 | 44 | # node.js 45 | # 46 | .expo/ 47 | node_modules/ 48 | npm-debug.log 49 | yarn-error.log 50 | 51 | # BUCK 52 | buck-out/ 53 | \.buckd/ 54 | *.keystore 55 | 56 | # fastlane 57 | # 58 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 59 | # screenshots whenever they are needed. 60 | # For more information about the recommended setup visit: 61 | # https://docs.fastlane.tools/best-practices/source-control/ 62 | 63 | */fastlane/report.xml 64 | */fastlane/Preview.html 65 | */fastlane/screenshots 66 | 67 | # Bundle artifact 68 | *.jsbundle 69 | 70 | # CocoaPods 71 | */ios/Pods/ 72 | 73 | # Secrets 74 | .env 75 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | cache: false 2 | 3 | before_install: 4 | - npm install -g yarn --ignore-dependencies 5 | - yarn install -g react-native-cli 6 | - yarn install -C browser-sign-in/ 7 | - yarn install -C custom-sign-in/ 8 | 9 | jobs: 10 | include: 11 | - language: node_js 12 | os: linux 13 | node_js: 14.15 14 | stage: Unit tests 15 | name: React Native 16 | script: 17 | - yarn run test:browser 18 | - language: objective-c 19 | os: osx 20 | osx_image: xcode12.5 21 | stage: UI tests 22 | name: Browser Sign In 23 | install: 24 | - echo -e "CLIENT_ID=${CLIENT_ID}\nISSUER=${ISSUER}\nREDIRECT_URI=${REDIRECT_URI}\nLOGOUT_REDIRECT_URI=${LOGOUT_REDIRECT_URI}" > browser-sign-in/.env 25 | - cd browser-sign-in/ios 26 | - pod install --repo-update 27 | - cd ../../ 28 | script: 29 | - set -o pipefail && xcodebuild -workspace browser-sign-in/ios/browserSignIn.xcworkspace -scheme browserSignIn -destination 'platform=iOS Simulator,OS=latest,name=iPhone 11' -sdk iphonesimulator clean test | xcpretty 30 | - language: objective-c 31 | os: osx 32 | osx_image: xcode12.5 33 | stage: UI tests 34 | name: Custom Sign In 35 | install: 36 | - echo -e "CLIENT_ID=${CLIENT_ID}\nISSUER=${ISSUER}\nREDIRECT_URI=${REDIRECT_URI}\nLOGOUT_REDIRECT_URI=${LOGOUT_REDIRECT_URI}" > custom-sign-in/.env 37 | - cd custom-sign-in/ios 38 | - pod install --repo-update 39 | - cd ../../ 40 | script: 41 | - set -o pipefail && xcodebuild -workspace custom-sign-in/ios/CustomSignIn.xcworkspace -scheme CustomSignIn -destination 'platform=iOS Simulator,OS=latest,name=iPhone 11' -sdk iphonesimulator clean test | xcpretty 42 | 43 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Okta Open Source Repos 2 | 3 | ## Style 4 | 5 | ### Git Commit Messages 6 | 7 | We use a simplified form of [Atom's](https://github.com/atom/atom/blob/master/CONTRIBUTING.md#git-commit-messages) commit convention. 8 | 9 | * Use the present tense ("Adds feature" not "Added feature") 10 | * Limit the first line to 72 characters or less 11 | * Add one feature per commit. If you have multiple features, have multiple commits. 12 | 13 | #### Template 14 | 15 | Short Description of Commit 16 | 17 | More detailed description of commit 18 | 19 | Resolves: 20 | 21 | #### Emoji Categories 22 | 23 | Our categories include: 24 | 25 | * :seedling: `:seedling:` when creating a new feature 26 | * :bug: `:bug:` when fixing a bug 27 | * :white_check_mark: `:white_check_mark:` when adding tests 28 | * :art: `:art:` when improving the format/structure of the code 29 | * :memo: `:memo:` when writing docs 30 | * :fire: `:fire:` when removing code or files 31 | * :package: `:package:` when pushing a new release 32 | * :arrow_up: `:arrow_up:` when upgrading dependencies, or generating files 33 | * :arrow_down: `:arrow_down:` when downgrading dependencies 34 | 35 | If you do not see an exact emoji match, use the best matching emoji. 36 | 37 | #### Example 38 | 39 | ```md 40 | :memo: Updates CONTRIBUTING.md 41 | 42 | Updates Contributing.md with new emoji categories 43 | Updates Contributing.md with new template 44 | 45 | Resolves: Issue #X 46 | ``` 47 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![CI Status](https://travis-ci.com/okta/samples-js-react-native.svg?branch=master)](https://travis-ci.com/github/okta/samples-js-react-native) 2 | 3 | # React Native Sample Applications for Okta 4 | 5 | This repository contains several sample applications that demonstrate various Okta use-cases in your React Native application. 6 | 7 | Each sample makes use of the [Okta React Native Library](https://github.com/okta/okta-react-native). 8 | 9 | ## Supported Platforms 10 | - iOS 11+ [Okta OIDC iOS Supported Platforms](https://github.com/okta/okta-oidc-ios#supported-platforms) 11 | - Android API 21+ [Okta OIDC Android MinSDK Requirements](https://github.com/okta/okta-oidc-android#requirements) 12 | 13 | ## Prerequisites 14 | 15 | Before running the samples, you will need the following: 16 | 17 | * An Okta Developer Account, you can sign up for one at . 18 | * An Okta Application, configured for Native mode. This is done from the Okta Developer Console. After login, from the Admin dashboard, navigate to `Applications → Add Application`. Choose Native as the platform. Populate your new Native OpenID Connect application with values similar to: 19 | * **Application Name** 20 | * Native OpenId Connect App (must be unique) 21 | * **Login redirect URIs** 22 | * `com.okta.example:/callback` 23 | * **Logout redirect URIs** 24 | * `com.okta.example:/logoutCallback` 25 | * **Grant type allowed** 26 | * Authorization Code 27 | * Refresh Token 28 | * If you are developing with an Android device emulator, make sure to check out the [React Native - Android Development](https://reactnative.dev/docs/environment-setup) setup instructions. 29 | 30 | ## Configuration 31 | 32 | For each sample, you will need to gather the following information from the Okta Developer Console: 33 | 34 | * **Client ID** - The client ID of the Native application that you created earlier. This can be found on the "General" tab of an application, or the list of applications. This identifies the application that tokens will be minted for. 35 | * **Redirect URI** This _must not be the same as_ **End Session Redirect URI**, otherwise Android will throw an error on `signOut`. 36 | * **Issuer/Discovery URI** - This is the URL of the authorization server that will perform authentication. All Developer Accounts have a "default" authorization server. The issuer is a combination of your Org URL (found in the upper right of the console home page) and `/oauth2/default`. For example, `https://dev-1234.oktapreview.com/oauth2/default`. 37 | 38 | Now place these values into the file `samples.config.js` located under each sample folder, here let's use `dev-1234.oktapreview.com` as the okta domain: 39 | 40 | ```javascript 41 | export default { 42 | oidc: { 43 | clientId: CLIENT_ID, // a1234abcdEf8gH1234mnIKS40 44 | discoveryUri: ISSUER, // https://dev-1234.oktapreview.com/oauth2/default 45 | redirectUri: REDIRECT_URI, // com.oktapreview.dev-1234:/callback 46 | endSessionRedirectUri: 'com.okta.{example}:/logoutCallback', // com.oktapreview.dev-1234:/logoutCallback 47 | scope: ["openid", "profile", "offline_access"], 48 | requireHardwareBackedKeyStore: false 49 | } 50 | }; 51 | ``` 52 | 53 | ## Samples 54 | 55 | Please find the sample that fits your use-case from the table below. 56 | 57 | | Sample | Description | 58 | |--------|-------------| 59 | | [Browser Sign In](/browser-sign-in) | A React Native application that will redirect the user to the Okta browser login page of your Org for authentication. The user is redirected back to the React Native application after authenticating. | 60 | | [Custom Sign In](/custom-sign-in) | A React Native application that adopts native authorization to take control over authorization flow and/or provide custom UI. | 61 | 62 | [Okta React Native Library]: https://github.com/okta/okta-oidc-js/tree/master/packages/okta-react-native 63 | -------------------------------------------------------------------------------- /browser-sign-in/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ignorePatterns: [ 3 | 'node_modules/', 4 | 'dist/', 5 | 'metro.config.js', 6 | '*.e2e.js', 7 | ], 8 | extends: [ 9 | 'eslint:recommended', 10 | 'plugin:react/recommended', 11 | ], 12 | rules: { 13 | 'jest/no-disabled-tests': 'warn', 14 | 'jest/no-focused-tests': 'error', 15 | 'jest/no-identical-title': 'error', 16 | 'jest/prefer-to-have-length': 'warn', 17 | 'jest/valid-expect': 'error', 18 | 'semi': ['error', 'always'], 19 | 'indent': ['error', 2], 20 | 'no-var': 0, 21 | 'prefer-rest-params': 0, 22 | 'prefer-spread': 0, 23 | 'prefer-const': 0, 24 | 'node/no-unpublished-require': 0, 25 | 'node/no-unpublished-import': 0, 26 | 'camelcase': 2, 27 | 'complexity': [2, 7], 28 | 'curly': 2, 29 | 'dot-notation': 0, 30 | 'guard-for-in': 2, 31 | 'new-cap': [2, {properties: false}], 32 | 'no-caller': 2, 33 | 'no-empty': 2, 34 | 'no-eval': 2, 35 | 'no-implied-eval': 2, 36 | 'no-multi-str': 0, 37 | 'no-new': 2, 38 | 'no-plusplus': 0, 39 | 'no-undef': 2, 40 | 'no-unused-expressions': [2, {allowShortCircuit: true, allowTernary: true}], 41 | 'no-unused-vars': ['warn', { argsIgnorePattern: '^_' }], 42 | 'max-depth': [2, 3], 43 | 'max-len': [2, 150], 44 | 'max-params': [2, 5], 45 | 'max-statements': [2, 25], 46 | 'quotes': [2, 'single', {allowTemplateLiterals: true}], 47 | 'strict': 0, 48 | 'wrap-iife': [2, 'any'], 49 | 'no-console': 'off', 50 | }, 51 | globals: { 52 | fetch: false 53 | }, 54 | overrides: [ 55 | { 56 | // ES6 processed by Babel 57 | files: ['*.js'], 58 | plugins: ['jest', 'react'], 59 | parser: '@babel/eslint-parser', 60 | parserOptions: { 61 | ecmaFeatures: { 62 | jsx: true 63 | }, 64 | ecmaVersion: 2020, 65 | sourceType: 'module', 66 | }, 67 | env: { 68 | es6: true, 69 | node: true, 70 | }, 71 | rules: { 72 | 'node/no-unsupported-features/es-syntax': 0, 73 | 'node/no-unsupported-features/node-builtins': 0, 74 | }, 75 | }, 76 | { 77 | // Jest specs 78 | files: ['*.test.js'], 79 | plugins: ['node', 'jest'], 80 | env: { 81 | jest: true, 82 | }, 83 | }, 84 | ], 85 | }; 86 | 87 | -------------------------------------------------------------------------------- /browser-sign-in/.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | -------------------------------------------------------------------------------- /browser-sign-in/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | 5 | { 6 | "name": "Debug iOS", 7 | "request": "launch", 8 | "type": "reactnative", 9 | "cwd": "${workspaceFolder}", 10 | "platform": "ios" 11 | }, 12 | { 13 | "type": "node", 14 | "name": "Run Tests", 15 | "request": "launch", 16 | "program": "${workspaceFolder}/node_modules/jest/bin/jest", 17 | "args": [ 18 | "--runInBand" 19 | ], 20 | "cwd": "${workspaceFolder}", 21 | "console": "integratedTerminal", 22 | "internalConsoleOptions": "neverOpen", 23 | "disableOptimisticBPs": true 24 | }, 25 | { 26 | "name": "Run iOS", 27 | "request": "launch", 28 | "type": "reactnative", 29 | "cwd": "${workspaceFolder}", 30 | "enableDebug": false, 31 | "platform": "ios" 32 | }, 33 | { 34 | "name": "Run Android", 35 | "request": "launch", 36 | "type": "reactnative", 37 | "cwd": "${workspaceFolder}", 38 | "enableDebug": false, 39 | "platform": "android" 40 | }, 41 | { 42 | "name": "Attach to packager", 43 | "request": "attach", 44 | "type": "reactnative", 45 | "cwd": "${workspaceFolder}" 46 | } 47 | ] 48 | } -------------------------------------------------------------------------------- /browser-sign-in/README.md: -------------------------------------------------------------------------------- 1 | # Okta React Native + Browser Sign In Example 2 | 3 | This example shows you how to use the [Okta React Native Library](https://github.com/okta/okta-react-native) to login a user to a React Native application. The login is achieved through the Auth Code Flow + PKCE, where the user is redirected to the Okta browser login page. After the user authenticates they are redirected back to the application with an Authorization Code, which is exchanged for an ID token and access token. 4 | 5 | ## Running This Example 6 | 7 | To run this application, you first need to clone this repo and then enter into this directory: 8 | 9 | ```bash 10 | git clone git@github.com:okta/samples-js-react-native.git 11 | cd samples-js-react-native/browser-sign-in 12 | ``` 13 | 14 | Then install dependencies: 15 | 16 | ```bash 17 | npm ci 18 | ``` 19 | 20 | Install dependecies for iOS. 21 | 22 | ```ruby 23 | cd ios 24 | pod install 25 | ``` 26 | 27 | For **Android** development, please make sure `redirect schema` is properly added by following [Add redirect schema](https://github.com/okta/okta-react-native#add-redirect-scheme) section from [Okta React Native](https://github.com/okta/okta-react-native#okta-react-native) README. 28 | 29 | Now start the app server: 30 | 31 | ```bash 32 | npm start 33 | ``` 34 | 35 | As an alternative, you can launch an Android Emulator or iOS Simulator: 36 | 37 | ```bash 38 | # Android 39 | npm run android 40 | 41 | # iOS 42 | npm run ios 43 | ``` 44 | 45 | If you see a home page that prompts you to login, then things are working! Clicking the **Log in** button will redirect you to the Okta browser sign-in page. 46 | 47 | You can login with the same account that you created when signing up for your Developer Org, or you can use a known username and password from your Okta Directory. 48 | 49 | ## Methods 50 | In this sample application, once the user logs in, there will be three methods that each shows a different way to get user info. 51 | 52 | ### Get User From ID Token ### 53 | This method calls `getUserFromIdToken()` to retrieve user info from decoding the ID Token claims. 54 | 55 | ### Get User From Request ### 56 | This method calls `getUser()` to retrieve user info by passing in the access token, and making a request to the user info endpoint. It is done on the native modules. 57 | 58 | ### Get User From Access Token ### 59 | This method shows you how to use the access token from `getAccessToken()` to exchange user information. It shows how to make a fetch request to the user info endpoint with access token as the header. 60 | -------------------------------------------------------------------------------- /browser-sign-in/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 | -------------------------------------------------------------------------------- /browser-sign-in/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.application" 2 | apply plugin: "org.jetbrains.kotlin.android" 3 | apply plugin: "com.facebook.react" 4 | 5 | def projectRoot = rootDir.getAbsoluteFile().getParentFile().getAbsolutePath() 6 | 7 | /** 8 | * This is the configuration block to customize your React Native Android app. 9 | * By default you don't need to apply any configuration, just uncomment the lines you need. 10 | */ 11 | react { 12 | entryFile = file(["node", "-e", "require('expo/scripts/resolveAppEntry')", projectRoot, "android", "absolute"].execute(null, rootDir).text.trim()) 13 | reactNativeDir = new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim()).getParentFile().getAbsoluteFile() 14 | hermesCommand = new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim()).getParentFile().getAbsolutePath() + "/sdks/hermesc/%OS-BIN%/hermesc" 15 | codegenDir = new File(["node", "--print", "require.resolve('@react-native/codegen/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim()).getParentFile().getAbsoluteFile() 16 | 17 | // Use Expo CLI to bundle the app, this ensures the Metro config 18 | // works correctly with Expo projects. 19 | cliFile = new File(["node", "--print", "require.resolve('@expo/cli', { paths: [require.resolve('expo/package.json')] })"].execute(null, rootDir).text.trim()) 20 | bundleCommand = "export:embed" 21 | 22 | /* Folders */ 23 | // The root of your project, i.e. where "package.json" lives. Default is '../..' 24 | // root = file("../../") 25 | // The folder where the react-native NPM package is. Default is ../../node_modules/react-native 26 | // reactNativeDir = file("../../node_modules/react-native") 27 | // The folder where the react-native Codegen package is. Default is ../../node_modules/@react-native/codegen 28 | // codegenDir = file("../../node_modules/@react-native/codegen") 29 | 30 | /* Variants */ 31 | // The list of variants to that are debuggable. For those we're going to 32 | // skip the bundling of the JS bundle and the assets. By default is just 'debug'. 33 | // If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants. 34 | // debuggableVariants = ["liteDebug", "prodDebug"] 35 | 36 | /* Bundling */ 37 | // A list containing the node command and its flags. Default is just 'node'. 38 | // nodeExecutableAndArgs = ["node"] 39 | 40 | // 41 | // The path to the CLI configuration file. Default is empty. 42 | // bundleConfig = file(../rn-cli.config.js) 43 | // 44 | // The name of the generated asset file containing your JS bundle 45 | // bundleAssetName = "MyApplication.android.bundle" 46 | // 47 | // The entry file for bundle generation. Default is 'index.android.js' or 'index.js' 48 | // entryFile = file("../js/MyApplication.android.js") 49 | // 50 | // A list of extra flags to pass to the 'bundle' commands. 51 | // See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle 52 | // extraPackagerArgs = [] 53 | 54 | /* Hermes Commands */ 55 | // The hermes compiler command to run. By default it is 'hermesc' 56 | // hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc" 57 | // 58 | // The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map" 59 | // hermesFlags = ["-O", "-output-source-map"] 60 | 61 | /* Autolinking */ 62 | autolinkLibrariesWithApp() 63 | } 64 | 65 | /** 66 | * Set this to true to Run Proguard on Release builds to minify the Java bytecode. 67 | */ 68 | def enableProguardInReleaseBuilds = (findProperty('android.enableProguardInReleaseBuilds') ?: false).toBoolean() 69 | 70 | /** 71 | * The preferred build flavor of JavaScriptCore (JSC) 72 | * 73 | * For example, to use the international variant, you can use: 74 | * `def jscFlavor = 'org.webkit:android-jsc-intl:+'` 75 | * 76 | * The international variant includes ICU i18n library and necessary data 77 | * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that 78 | * give correct results when using with locales other than en-US. Note that 79 | * this variant is about 6MiB larger per architecture than default. 80 | */ 81 | def jscFlavor = 'org.webkit:android-jsc:+' 82 | 83 | android { 84 | ndkVersion rootProject.ext.ndkVersion 85 | 86 | buildToolsVersion rootProject.ext.buildToolsVersion 87 | compileSdk rootProject.ext.compileSdkVersion 88 | 89 | namespace 'com.browsersignin' 90 | defaultConfig { 91 | applicationId 'com.browsersignin' 92 | minSdkVersion rootProject.ext.minSdkVersion 93 | targetSdkVersion rootProject.ext.targetSdkVersion 94 | versionCode 1 95 | versionName "1.0.0" 96 | 97 | manifestPlaceholders = [ 98 | appAuthRedirectScheme: 'customUriScheme' 99 | ] 100 | } 101 | signingConfigs { 102 | debug { 103 | storeFile file('debug.keystore') 104 | storePassword 'android' 105 | keyAlias 'androiddebugkey' 106 | keyPassword 'android' 107 | } 108 | } 109 | buildTypes { 110 | debug { 111 | signingConfig signingConfigs.debug 112 | } 113 | release { 114 | // Caution! In production, you need to generate your own keystore file. 115 | // see https://reactnative.dev/docs/signed-apk-android. 116 | signingConfig signingConfigs.debug 117 | shrinkResources (findProperty('android.enableShrinkResourcesInReleaseBuilds')?.toBoolean() ?: false) 118 | minifyEnabled enableProguardInReleaseBuilds 119 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 120 | crunchPngs (findProperty('android.enablePngCrunchInReleaseBuilds')?.toBoolean() ?: true) 121 | } 122 | } 123 | packagingOptions { 124 | jniLibs { 125 | useLegacyPackaging (findProperty('expo.useLegacyPackaging')?.toBoolean() ?: false) 126 | } 127 | } 128 | androidResources { 129 | ignoreAssetsPattern '!.svn:!.git:!.ds_store:!*.scc:!CVS:!thumbs.db:!picasa.ini:!*~' 130 | } 131 | } 132 | 133 | // Apply static values from `gradle.properties` to the `android.packagingOptions` 134 | // Accepts values in comma delimited lists, example: 135 | // android.packagingOptions.pickFirsts=/LICENSE,**/picasa.ini 136 | ["pickFirsts", "excludes", "merges", "doNotStrip"].each { prop -> 137 | // Split option: 'foo,bar' -> ['foo', 'bar'] 138 | def options = (findProperty("android.packagingOptions.$prop") ?: "").split(","); 139 | // Trim all elements in place. 140 | for (i in 0.. 0) { 145 | println "android.packagingOptions.$prop += $options ($options.length)" 146 | // Ex: android.packagingOptions.pickFirsts += '**/SCCS/**' 147 | options.each { 148 | android.packagingOptions[prop] += it 149 | } 150 | } 151 | } 152 | 153 | dependencies { 154 | // The version of react-native is set by the React Native Gradle Plugin 155 | implementation("com.facebook.react:react-android") 156 | 157 | def isGifEnabled = (findProperty('expo.gif.enabled') ?: "") == "true"; 158 | def isWebpEnabled = (findProperty('expo.webp.enabled') ?: "") == "true"; 159 | def isWebpAnimatedEnabled = (findProperty('expo.webp.animated') ?: "") == "true"; 160 | 161 | if (isGifEnabled) { 162 | // For animated gif support 163 | implementation("com.facebook.fresco:animated-gif:${reactAndroidLibs.versions.fresco.get()}") 164 | } 165 | 166 | if (isWebpEnabled) { 167 | // For webp support 168 | implementation("com.facebook.fresco:webpsupport:${reactAndroidLibs.versions.fresco.get()}") 169 | if (isWebpAnimatedEnabled) { 170 | // Animated webp support 171 | implementation("com.facebook.fresco:animated-webp:${reactAndroidLibs.versions.fresco.get()}") 172 | } 173 | } 174 | 175 | if (hermesEnabled.toBoolean()) { 176 | implementation("com.facebook.react:hermes-android") 177 | } else { 178 | implementation jscFlavor 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /browser-sign-in/android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/browser-sign-in/android/app/debug.keystore -------------------------------------------------------------------------------- /browser-sign-in/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 | -------------------------------------------------------------------------------- /browser-sign-in/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /browser-sign-in/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 | -------------------------------------------------------------------------------- /browser-sign-in/android/app/src/main/java/com/browsersignin/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.browsersignin 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 | -------------------------------------------------------------------------------- /browser-sign-in/android/app/src/main/java/com/browsersignin/MainApplication.kt: -------------------------------------------------------------------------------- 1 | package com.browsersignin 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 | -------------------------------------------------------------------------------- /browser-sign-in/android/app/src/main/res/drawable-hdpi/splashscreen_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/browser-sign-in/android/app/src/main/res/drawable-hdpi/splashscreen_logo.png -------------------------------------------------------------------------------- /browser-sign-in/android/app/src/main/res/drawable-mdpi/splashscreen_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/browser-sign-in/android/app/src/main/res/drawable-mdpi/splashscreen_logo.png -------------------------------------------------------------------------------- /browser-sign-in/android/app/src/main/res/drawable-night-hdpi/splashscreen_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/browser-sign-in/android/app/src/main/res/drawable-night-hdpi/splashscreen_logo.png -------------------------------------------------------------------------------- /browser-sign-in/android/app/src/main/res/drawable-night-mdpi/splashscreen_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/browser-sign-in/android/app/src/main/res/drawable-night-mdpi/splashscreen_logo.png -------------------------------------------------------------------------------- /browser-sign-in/android/app/src/main/res/drawable-night-xhdpi/splashscreen_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/browser-sign-in/android/app/src/main/res/drawable-night-xhdpi/splashscreen_logo.png -------------------------------------------------------------------------------- /browser-sign-in/android/app/src/main/res/drawable-night-xxhdpi/splashscreen_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/browser-sign-in/android/app/src/main/res/drawable-night-xxhdpi/splashscreen_logo.png -------------------------------------------------------------------------------- /browser-sign-in/android/app/src/main/res/drawable-night-xxxhdpi/splashscreen_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/browser-sign-in/android/app/src/main/res/drawable-night-xxxhdpi/splashscreen_logo.png -------------------------------------------------------------------------------- /browser-sign-in/android/app/src/main/res/drawable-xhdpi/splashscreen_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/browser-sign-in/android/app/src/main/res/drawable-xhdpi/splashscreen_logo.png -------------------------------------------------------------------------------- /browser-sign-in/android/app/src/main/res/drawable-xxhdpi/splashscreen_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/browser-sign-in/android/app/src/main/res/drawable-xxhdpi/splashscreen_logo.png -------------------------------------------------------------------------------- /browser-sign-in/android/app/src/main/res/drawable-xxxhdpi/splashscreen_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/browser-sign-in/android/app/src/main/res/drawable-xxxhdpi/splashscreen_logo.png -------------------------------------------------------------------------------- /browser-sign-in/android/app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /browser-sign-in/android/app/src/main/res/drawable/rn_edit_text_material.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 22 | 23 | 24 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /browser-sign-in/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/browser-sign-in/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /browser-sign-in/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/browser-sign-in/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /browser-sign-in/android/app/src/main/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/browser-sign-in/android/app/src/main/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /browser-sign-in/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/browser-sign-in/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /browser-sign-in/android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/browser-sign-in/android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /browser-sign-in/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/browser-sign-in/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /browser-sign-in/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/browser-sign-in/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /browser-sign-in/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/browser-sign-in/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /browser-sign-in/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/browser-sign-in/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /browser-sign-in/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/browser-sign-in/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /browser-sign-in/android/app/src/main/res/values-night/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | #000000 3 | -------------------------------------------------------------------------------- /browser-sign-in/android/app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | #232323 3 | #ffffff 4 | #023c69 5 | #232323 6 | -------------------------------------------------------------------------------- /browser-sign-in/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | browserSignIn 3 | contain 4 | false 5 | -------------------------------------------------------------------------------- /browser-sign-in/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 14 | 19 | -------------------------------------------------------------------------------- /browser-sign-in/android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | ext { 5 | buildToolsVersion = findProperty('android.buildToolsVersion') ?: '35.0.0' 6 | minSdkVersion = Integer.parseInt(findProperty('android.minSdkVersion') ?: '24') 7 | compileSdkVersion = Integer.parseInt(findProperty('android.compileSdkVersion') ?: '35') 8 | targetSdkVersion = Integer.parseInt(findProperty('android.targetSdkVersion') ?: '34') 9 | kotlinVersion = findProperty('android.kotlinVersion') ?: '1.9.24' 10 | 11 | ndkVersion = "26.1.10909125" 12 | } 13 | repositories { 14 | google() 15 | mavenCentral() 16 | } 17 | dependencies { 18 | classpath('com.android.tools.build:gradle') 19 | classpath('com.facebook.react:react-native-gradle-plugin') 20 | classpath('org.jetbrains.kotlin:kotlin-gradle-plugin') 21 | } 22 | } 23 | 24 | apply plugin: "com.facebook.react.rootproject" 25 | 26 | allprojects { 27 | repositories { 28 | maven { 29 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 30 | url(new File(['node', '--print', "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim(), '../android')) 31 | } 32 | maven { 33 | // Android JSC is installed from npm 34 | url(new File(['node', '--print', "require.resolve('jsc-android/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim(), '../dist')) 35 | } 36 | 37 | google() 38 | mavenCentral() 39 | maven { url 'https://www.jitpack.io' } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /browser-sign-in/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=-Xmx8192m -XX:MaxMetaspaceSize=2048m 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 | -------------------------------------------------------------------------------- /browser-sign-in/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/browser-sign-in/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /browser-sign-in/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 | -------------------------------------------------------------------------------- /browser-sign-in/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 | -------------------------------------------------------------------------------- /browser-sign-in/android/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | includeBuild(new File(["node", "--print", "require.resolve('@react-native/gradle-plugin/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 = 'browserSignIn' 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 | -------------------------------------------------------------------------------- /browser-sign-in/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "browserSignIn", 4 | "displayName": "browserSignIn", 5 | "version": "1.0.0", 6 | "assetBundlePatterns": [ 7 | "**/*" 8 | ], 9 | "icon": "./app_logo.png", 10 | "android": { 11 | "package": "com.browsersignin" 12 | }, 13 | "ios": { 14 | "bundleIdentifier": "com.browsersignin" 15 | }, 16 | "plugins": [ 17 | [ 18 | "expo-splash-screen", 19 | { 20 | "backgroundColor": "#ffffff", 21 | "image": "./app_logo.png", 22 | "dark": { 23 | "image": "./app_logo.png", 24 | "backgroundColor": "#000000" 25 | }, 26 | "imageWidth": 200 27 | } 28 | ] 29 | ] 30 | }, 31 | "name": "browserSignIn" 32 | } 33 | -------------------------------------------------------------------------------- /browser-sign-in/app_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/browser-sign-in/app_logo.png -------------------------------------------------------------------------------- /browser-sign-in/babel.config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018-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 | -------------------------------------------------------------------------------- /browser-sign-in/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018-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 | * @format 15 | */ 16 | 17 | import 'react-native-gesture-handler'; 18 | import { registerRootComponent } from 'expo'; 19 | 20 | import App from './App'; 21 | 22 | // registerRootComponent calls AppRegistry.registerComponent('main', () => App); 23 | // It also ensures that whether you load the app in Expo Go or in a native build, 24 | // the environment is set up appropriately 25 | registerRootComponent(App); 26 | -------------------------------------------------------------------------------- /browser-sign-in/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 | -------------------------------------------------------------------------------- /browser-sign-in/ios/.xcode.env: -------------------------------------------------------------------------------- 1 | # This `.xcode.env` file is versioned and is used to source the environment 2 | # used when running script phases inside Xcode. 3 | # To customize your local environment, you can create an `.xcode.env.local` 4 | # file that is not versioned. 5 | 6 | # NODE_BINARY variable contains the PATH to the node executable. 7 | # 8 | # Customize the NODE_BINARY variable here. 9 | # For example, to use nvm with brew, add the following line 10 | # . "$(brew --prefix nvm)/nvm.sh" --no-use 11 | export NODE_BINARY=$(command -v node) 12 | -------------------------------------------------------------------------------- /browser-sign-in/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 'browserSignIn' 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 | -------------------------------------------------------------------------------- /browser-sign-in/ios/Podfile.properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo.jsEngine": "hermes", 3 | "EX_DEV_CLIENT_NETWORK_INSPECTOR": "true", 4 | "newArchEnabled": "false" 5 | } 6 | -------------------------------------------------------------------------------- /browser-sign-in/ios/browserSignIn.xcodeproj/xcshareddata/xcschemes/browserSignIn.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 53 | 55 | 61 | 62 | 63 | 64 | 70 | 72 | 78 | 79 | 80 | 81 | 83 | 84 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /browser-sign-in/ios/browserSignIn.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /browser-sign-in/ios/browserSignIn/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | 5 | @interface AppDelegate : EXAppDelegateWrapper 6 | 7 | @end 8 | -------------------------------------------------------------------------------- /browser-sign-in/ios/browserSignIn/AppDelegate.mm: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | 3 | #import 4 | #import 5 | 6 | @implementation AppDelegate 7 | 8 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 9 | { 10 | self.moduleName = @"main"; 11 | 12 | // You can add your custom initial props in the dictionary below. 13 | // They will be passed down to the ViewController used by React Native. 14 | self.initialProps = @{}; 15 | 16 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 17 | } 18 | 19 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge 20 | { 21 | return [self bundleURL]; 22 | } 23 | 24 | - (NSURL *)bundleURL 25 | { 26 | #if DEBUG 27 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@".expo/.virtual-metro-entry"]; 28 | #else 29 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 30 | #endif 31 | } 32 | 33 | // Linking API 34 | - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary *)options { 35 | return [super application:application openURL:url options:options] || [RCTLinkingManager application:application openURL:url options:options]; 36 | } 37 | 38 | // Universal Links 39 | - (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray> * _Nullable))restorationHandler { 40 | BOOL result = [RCTLinkingManager application:application continueUserActivity:userActivity restorationHandler:restorationHandler]; 41 | return [super application:application continueUserActivity:userActivity restorationHandler:restorationHandler] || result; 42 | } 43 | 44 | // Explicitly define remote notification delegates to ensure compatibility with some third-party libraries 45 | - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken 46 | { 47 | return [super application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; 48 | } 49 | 50 | // Explicitly define remote notification delegates to ensure compatibility with some third-party libraries 51 | - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error 52 | { 53 | return [super application:application didFailToRegisterForRemoteNotificationsWithError:error]; 54 | } 55 | 56 | // Explicitly define remote notification delegates to ensure compatibility with some third-party libraries 57 | - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler 58 | { 59 | return [super application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler]; 60 | } 61 | 62 | @end 63 | -------------------------------------------------------------------------------- /browser-sign-in/ios/browserSignIn/Images.xcassets/AppIcon.appiconset/App-Icon-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/browser-sign-in/ios/browserSignIn/Images.xcassets/AppIcon.appiconset/App-Icon-1024x1024@1x.png -------------------------------------------------------------------------------- /browser-sign-in/ios/browserSignIn/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 | } -------------------------------------------------------------------------------- /browser-sign-in/ios/browserSignIn/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "expo" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /browser-sign-in/ios/browserSignIn/Images.xcassets/SplashScreenBackground.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors": [ 3 | { 4 | "color": { 5 | "components": { 6 | "alpha": "1.000", 7 | "blue": "0.137254901960784", 8 | "green": "0.137254901960784", 9 | "red": "0.137254901960784" 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 | } -------------------------------------------------------------------------------- /browser-sign-in/ios/browserSignIn/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 | } -------------------------------------------------------------------------------- /browser-sign-in/ios/browserSignIn/Images.xcassets/SplashScreenLogo.imageset/dark_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/browser-sign-in/ios/browserSignIn/Images.xcassets/SplashScreenLogo.imageset/dark_image.png -------------------------------------------------------------------------------- /browser-sign-in/ios/browserSignIn/Images.xcassets/SplashScreenLogo.imageset/dark_image@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/browser-sign-in/ios/browserSignIn/Images.xcassets/SplashScreenLogo.imageset/dark_image@2x.png -------------------------------------------------------------------------------- /browser-sign-in/ios/browserSignIn/Images.xcassets/SplashScreenLogo.imageset/dark_image@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/browser-sign-in/ios/browserSignIn/Images.xcassets/SplashScreenLogo.imageset/dark_image@3x.png -------------------------------------------------------------------------------- /browser-sign-in/ios/browserSignIn/Images.xcassets/SplashScreenLogo.imageset/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/browser-sign-in/ios/browserSignIn/Images.xcassets/SplashScreenLogo.imageset/image.png -------------------------------------------------------------------------------- /browser-sign-in/ios/browserSignIn/Images.xcassets/SplashScreenLogo.imageset/image@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/browser-sign-in/ios/browserSignIn/Images.xcassets/SplashScreenLogo.imageset/image@2x.png -------------------------------------------------------------------------------- /browser-sign-in/ios/browserSignIn/Images.xcassets/SplashScreenLogo.imageset/image@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/browser-sign-in/ios/browserSignIn/Images.xcassets/SplashScreenLogo.imageset/image@3x.png -------------------------------------------------------------------------------- /browser-sign-in/ios/browserSignIn/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CADisableMinimumFrameDurationOnPhone 6 | 7 | CFBundleDevelopmentRegion 8 | $(DEVELOPMENT_LANGUAGE) 9 | CFBundleDisplayName 10 | browserSignIn 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.browsersignin 31 | 32 | 33 | 34 | CFBundleVersion 35 | 1 36 | LSMinimumSystemVersion 37 | 12.0 38 | LSRequiresIPhoneOS 39 | 40 | NSAppTransportSecurity 41 | 42 | NSAllowsArbitraryLoads 43 | 44 | NSAllowsLocalNetworking 45 | 46 | 47 | UILaunchStoryboardName 48 | SplashScreen 49 | UIRequiredDeviceCapabilities 50 | 51 | arm64 52 | 53 | UIRequiresFullScreen 54 | 55 | UIStatusBarStyle 56 | UIStatusBarStyleDefault 57 | UISupportedInterfaceOrientations 58 | 59 | UIInterfaceOrientationPortrait 60 | UIInterfaceOrientationPortraitUpsideDown 61 | UIInterfaceOrientationLandscapeLeft 62 | UIInterfaceOrientationLandscapeRight 63 | 64 | UISupportedInterfaceOrientations~ipad 65 | 66 | UIInterfaceOrientationPortrait 67 | UIInterfaceOrientationPortraitUpsideDown 68 | UIInterfaceOrientationLandscapeLeft 69 | UIInterfaceOrientationLandscapeRight 70 | 71 | UIUserInterfaceStyle 72 | Automatic 73 | UIViewControllerBasedStatusBarAppearance 74 | 75 | 76 | -------------------------------------------------------------------------------- /browser-sign-in/ios/browserSignIn/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 | -------------------------------------------------------------------------------- /browser-sign-in/ios/browserSignIn/SplashScreen.storyboard: -------------------------------------------------------------------------------- 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 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /browser-sign-in/ios/browserSignIn/Supporting/Expo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | EXUpdatesCheckOnLaunch 6 | ALWAYS 7 | EXUpdatesEnabled 8 | 9 | EXUpdatesLaunchWaitMs 10 | 0 11 | 12 | -------------------------------------------------------------------------------- /browser-sign-in/ios/browserSignIn/browserSignIn-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 | -------------------------------------------------------------------------------- /browser-sign-in/ios/browserSignIn/browserSignIn.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /browser-sign-in/ios/browserSignIn/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char * argv[]) { 6 | @autoreleasepool { 7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 8 | } 9 | } 10 | 11 | -------------------------------------------------------------------------------- /browser-sign-in/ios/browserSignIn/noop-file.swift: -------------------------------------------------------------------------------- 1 | // 2 | // @generated 3 | // A blank Swift file must be created for native modules with Swift files to work correctly. 4 | // 5 | -------------------------------------------------------------------------------- /browser-sign-in/metro.config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018-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 | // Learn more https://docs.expo.io/guides/customizing-metro 14 | const { getDefaultConfig } = require('expo/metro-config'); 15 | 16 | /** @type {import('expo/metro-config').MetroConfig} */ 17 | const config = getDefaultConfig(__dirname); 18 | 19 | module.exports = config; 20 | -------------------------------------------------------------------------------- /browser-sign-in/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "browser-sign-in", 3 | "version": "1.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "react-native start", 7 | "android": "expo run:android", 8 | "ios": "expo run:ios", 9 | "test": "jest", 10 | "lint": "eslint ." 11 | }, 12 | "dependencies": { 13 | "@okta/okta-react-native": "~2.15.0", 14 | "@react-native/metro-config": "^0.76.3", 15 | "@react-navigation/native": "^6.1.17", 16 | "@react-navigation/native-stack": "^6.9.26", 17 | "expo": "^52.0.14", 18 | "expo-splash-screen": "~0.29.13", 19 | "expo-status-bar": "~2.0.0", 20 | "expo-updates": "~0.26.9", 21 | "react": "18.3.1", 22 | "react-dom": "18.3.1", 23 | "react-native": "0.76.3", 24 | "react-native-dotenv": "^3.4.9", 25 | "react-native-gesture-handler": "~2.20.2", 26 | "react-native-reanimated": "~3.16.1", 27 | "react-native-safe-area-context": "4.12.0", 28 | "react-native-screens": "~4.1.0", 29 | "semver": "^7.6.2" 30 | }, 31 | "devDependencies": { 32 | "@babel/core": "^7.24.6", 33 | "@types/react": "~18.3.12", 34 | "typescript": "^5.3.3" 35 | }, 36 | "jest": { 37 | "preset": "react-native", 38 | "automock": false, 39 | "transformIgnorePatterns": [ 40 | "node_modules/(?!@okta|react-native|@react-native)" 41 | ], 42 | "setupFiles": [ 43 | "./setupJest.js" 44 | ] 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /browser-sign-in/samples.config.js: -------------------------------------------------------------------------------- 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 { CLIENT_ID, REDIRECT_URI, LOGOUT_REDIRECT_URI, ISSUER } from '@env'; 14 | 15 | /* 16 | clientId, redirectUri, endSessionRedirectUri - these values can be found on the "General" tab of the application that you created earlier in Admin Console. 17 | discoveryUri - this is the URL of the authorization server that will perform authentication. 18 | 19 | For more details, https://developer.okta.com/docs/guides/sign-into-mobile-app/create-okta-application/ 20 | */ 21 | 22 | export default { 23 | oidc: { 24 | clientId: CLIENT_ID, // e.g.: `a0abcEf0gH123ssJS4o5` 25 | redirectUri: REDIRECT_URI, // e.g.: `com.okta.example:/callback` 26 | endSessionRedirectUri: LOGOUT_REDIRECT_URI, // e.g.: com.okta.example:/logout 27 | discoveryUri: ISSUER, // e.g.: https://dev-1234.okta.com/oauth2/default 28 | scopes: ['openid', 'profile', 'offline_access'], 29 | requireHardwareBackedKeyStore: false, 30 | }, 31 | }; 32 | -------------------------------------------------------------------------------- /browser-sign-in/setupJest.js: -------------------------------------------------------------------------------- 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 | // Required to correctly polyfill React-Native 14 | 15 | import { configure } from 'enzyme'; 16 | import Adapter from 'enzyme-adapter-react-16'; 17 | 18 | configure({ adapter: new Adapter() }); 19 | 20 | global.XMLHttpRequest = jest.fn(); 21 | global.fetch = jest.fn(); 22 | 23 | if (typeof window !== 'object') { 24 | global.window = global; 25 | global.window.navigator = {}; 26 | } 27 | 28 | import * as ReactNative from "react-native"; 29 | 30 | jest.doMock('react-native', () => { 31 | // Extend ReactNative 32 | return Object.setPrototypeOf( 33 | { 34 | NativeModules: { 35 | ...ReactNative.NativeModules, 36 | OktaSdkBridge: { 37 | createConfig: jest.fn(), 38 | signIn: jest.fn(), 39 | signOut: jest.fn(), 40 | getAccessToken: jest.fn(), 41 | getIdToken: jest.fn(), 42 | getUser: jest.fn(), 43 | isAuthenticated: jest.fn(), 44 | revokeAccessToken: jest.fn(), 45 | revokeIdToken: jest.fn(), 46 | revokeRefreshToken: jest.fn(), 47 | introspectAccessToken: jest.fn(), 48 | introspectIdToken: jest.fn(), 49 | introspectRefreshToken: jest.fn(), 50 | refreshTokens: jest.fn(), 51 | }, 52 | }, 53 | }, 54 | ReactNative, 55 | ); 56 | }); 57 | -------------------------------------------------------------------------------- /browser-sign-in/test/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ignorePatterns: [ 3 | 'node_modules/', 4 | 'dist/', 5 | 'metro.config.js', 6 | '*.e2e.js', 7 | ], 8 | plugins: ['jest', 'react'], 9 | parser: '@babel/eslint-parser', 10 | extends: [ 11 | 'eslint:recommended', 12 | 'plugin:react/recommended', 13 | 'plugin:jest/recommended', 14 | ], 15 | env: { 16 | es6: true, 17 | node: true, 18 | jest: true, 19 | }, 20 | parserOptions: { 21 | ecmaFeatures: { 22 | jsx: true 23 | }, 24 | ecmaVersion: 2020, 25 | sourceType: 'module', 26 | }, 27 | }; 28 | 29 | -------------------------------------------------------------------------------- /browser-sign-in/test/App.test.js: -------------------------------------------------------------------------------- 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 React from 'react'; 14 | import App from '../App'; 15 | import { shallow } from 'enzyme'; 16 | import renderer from 'react-test-renderer'; 17 | import { waitForState } from 'enzyme-async-helpers'; 18 | 19 | import { NativeEventEmitter } from 'react-native'; 20 | 21 | jest.mock( 22 | '../node_modules/react-native/Libraries/EventEmitter/NativeEventEmitter', 23 | ); 24 | 25 | const nativeEmitter = new NativeEventEmitter(); 26 | 27 | jest 28 | .mock( 29 | '../node_modules/react-native/Libraries/Components/StatusBar/StatusBar', 30 | () => 'StatusBar', 31 | ) 32 | .mock( 33 | '../node_modules/react-native/Libraries/Components/ScrollView/ScrollView', 34 | () => 'ScrollView', 35 | ); 36 | 37 | global.fetch = jest 38 | .fn() 39 | .mockImplementation(() => { 40 | const promise = new Promise((resolve, _reject) => { 41 | resolve({ 42 | json: () => { 43 | return { 44 | user: [{ foo: 'foo', bar: 'bar' }], 45 | }; 46 | }, 47 | ok: true, 48 | }); 49 | }); 50 | return promise; 51 | }) 52 | .mockImplementationOnce(() => { 53 | const promise = new Promise((resolve, _reject) => { 54 | resolve({ 55 | json: () => { 56 | return { 57 | // eslint-disable-next-line camelcase 58 | userinfo_endpoint: 'dummy_endpoint', 59 | }; 60 | }, 61 | ok: true, 62 | }); 63 | }); 64 | return promise; 65 | }); 66 | 67 | describe('app setup', () => { 68 | it('should render without crashing', () => { 69 | const rendered = renderer.create().toJSON(); 70 | expect(rendered).toBeTruthy(); 71 | }); 72 | 73 | it('should render correctly', () => { 74 | const rendered = renderer.create().toJSON(); 75 | expect(rendered).toMatchSnapshot(); 76 | }); 77 | 78 | it('should initialize with default state', () => { 79 | const wrapper = shallow(); 80 | expect(wrapper.state().authenticated).toBe(false); 81 | expect(wrapper.state().context).toBe(null); 82 | }); 83 | 84 | it('should render login button if not authenticated', () => { 85 | const wrapper = shallow(); 86 | const loginButton = wrapper.find('Button').get(0); 87 | expect(loginButton.props.title).toBe('Login'); 88 | }); 89 | 90 | it('should render logout and get user info buttons if authenticated', () => { 91 | const wrapper = shallow(); 92 | wrapper.setState({authenticated: true}); 93 | const logoutButton = wrapper.find('Button').get(0); 94 | const getUserFromIdButton = wrapper.find('Button').get(1); 95 | const getUserButton = wrapper.find('Button').get(2); 96 | const getUserFromTokenButton = wrapper.find('Button').get(3); 97 | const refreshMyTokensButton = wrapper.find('Button').get(4); 98 | expect(logoutButton.props.title).toBe('Logout'); 99 | expect(getUserFromIdButton.props.title).toBe('Get User From Id Token'); 100 | expect(getUserButton.props.title).toBe('Get User From Request'); 101 | expect(getUserFromTokenButton.props.title).toBe('Get User From Access Token'); 102 | expect(refreshMyTokensButton.props.title).toBe('Refresh Tokens'); 103 | }); 104 | 105 | it('should not render login button if authenticated', () => { 106 | const wrapper = shallow(); 107 | wrapper.setState({authenticated: true}); 108 | const loginButton = wrapper.find('Button').get(0); 109 | expect(loginButton.props.title).not.toBe('Login'); 110 | }); 111 | 112 | it('should not render logout and get user info buttons if not authenticated', () => { 113 | const wrapper = shallow(); 114 | const logoutButton = wrapper.find('Button').get(0); 115 | const getUserFromIdButton = wrapper.find('Button').get(1); 116 | const getUserButton = wrapper.find('Button').get(2); 117 | const getUserFromTokenButton = wrapper.find('Button').get(3); 118 | const refreshMyTokensButton = wrapper.find('Button').get(4); 119 | expect(logoutButton.props.title).not.toBe('Logout'); 120 | expect(getUserFromIdButton).toBe(undefined); 121 | expect(getUserButton).toBe(undefined); 122 | expect(getUserFromTokenButton).toBe(undefined); 123 | expect(refreshMyTokensButton).toBe(undefined); 124 | }); 125 | }); 126 | 127 | describe('authentication flow', () => { 128 | it('should detect when the user has logged in', async () => { 129 | const wrapper = shallow(); 130 | const loginButton = wrapper.find('Button').get(0); 131 | await loginButton.props.onPress(); 132 | expect(loginButton.props.title).toBe('Login'); 133 | nativeEmitter.emit('signInSuccess'); 134 | expect(wrapper.state().authenticated).toBe(true); 135 | expect(wrapper.state().context).toBe('Logged in!'); 136 | }); 137 | 138 | it('should detect when the user has signed out', async () => { 139 | const wrapper = shallow(); 140 | wrapper.setState({authenticated: true}); 141 | const logoutButton = wrapper.find('Button').get(0); 142 | await logoutButton.props.onPress(); 143 | expect(logoutButton.props.title).toBe('Logout'); 144 | nativeEmitter.emit('signOutSuccess'); 145 | expect(wrapper.state().authenticated).toBe(false); 146 | expect(wrapper.state().context).toBe('Logged out!'); 147 | }); 148 | 149 | it('should return user profile information from id token' , async () => { 150 | const mockGetIdToken = require('react-native').NativeModules.OktaSdkBridge.getIdToken; 151 | mockGetIdToken.mockImplementationOnce(() => { 152 | // id_token returns { a: 'b' } 153 | return {'id_token': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8'}; 154 | }); 155 | const wrapper = shallow(); 156 | wrapper.setState({authenticated: true}); 157 | const profileButton = wrapper.find('Button').get(1); 158 | await profileButton.props.onPress(); 159 | await waitForState(wrapper, state => state.context !== null); 160 | expect(profileButton.props.title).toBe('Get User From Id Token'); 161 | expect(wrapper.state().context).toContain('User Profile'); 162 | }); 163 | 164 | it('should return user profile information from getUser method' , async () => { 165 | const mockGetUser = require('react-native').NativeModules.OktaSdkBridge.getUser; 166 | mockGetUser.mockResolvedValue({ 'name': 'fake name' }); 167 | const wrapper = shallow(); 168 | wrapper.setState({authenticated: true}); 169 | const profileButton = wrapper.find('Button').get(2); 170 | await profileButton.props.onPress(); 171 | await waitForState(wrapper, state => state.context !== null); 172 | expect(profileButton.props.title).toBe('Get User From Request'); 173 | expect(wrapper.state().context).toContain('User Profile'); 174 | }); 175 | 176 | it('should return user profile information from fetch method' , async () => { 177 | const mockGetAccessToken = require('react-native').NativeModules.OktaSdkBridge.getAccessToken; 178 | mockGetAccessToken.mockImplementation(() => { 179 | return {'access_token': 'dummy_access_token'}; 180 | }); 181 | const wrapper = shallow(); 182 | wrapper.setState({authenticated: true}); 183 | const profileButton = wrapper.find('Button').get(3); 184 | await profileButton.props.onPress(); 185 | await waitForState(wrapper, state => state.context !== null); 186 | expect(profileButton.props.title).toBe('Get User From Access Token'); 187 | expect(wrapper.state().context).toContain('foo'); 188 | }); 189 | 190 | it('should return new accessToken, idToken and refreshToken' , async () => { 191 | const mockRefreshTokens = require('react-native').NativeModules.OktaSdkBridge.refreshTokens; 192 | mockRefreshTokens.mockImplementation(() => { 193 | return {'access_token': 'dummy_accessToken', 194 | 'id_token': 'dummy_idToken', 195 | 'refresh_token': 'dummy_refreshToken'}; 196 | }); 197 | const wrapper = shallow(); 198 | wrapper.setState({authenticated: true}); 199 | const profileButton = wrapper.find('Button').get(4); 200 | await profileButton.props.onPress(); 201 | await waitForState(wrapper, state => state.context !== null); 202 | expect(profileButton.props.title).toBe('Refresh Tokens'); 203 | expect(wrapper.state().context).toContain('Successfully refreshed tokens: '); 204 | }); 205 | }); 206 | -------------------------------------------------------------------------------- /browser-sign-in/test/__snapshots__/App.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`app setup should render correctly 1`] = ` 4 | Array [ 5 | , 8 | 19 | 31 | Okta + React Native 32 | 33 | 42 | 53 | 72 | 79 | 91 | Login 92 | 93 | 94 | 95 | 96 | 97 | 105 | 108 | 109 | , 110 | ] 111 | `; 112 | -------------------------------------------------------------------------------- /browser-sign-in/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": {}, 3 | "extends": "expo/tsconfig.base" 4 | } 5 | -------------------------------------------------------------------------------- /custom-sign-in/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ignorePatterns: [ 3 | 'node_modules/', 4 | 'dist/', 5 | 'metro.config.js', 6 | '*.e2e.js', 7 | ], 8 | extends: ['eslint:recommended', 'plugin:react/recommended'], 9 | rules: { 10 | 'jest/no-disabled-tests': 'warn', 11 | 'jest/no-focused-tests': 'error', 12 | 'jest/no-identical-title': 'error', 13 | 'jest/prefer-to-have-length': 'warn', 14 | 'jest/valid-expect': 'error', 15 | semi: ['error', 'always'], 16 | indent: ['error', 2], 17 | 'no-var': 0, 18 | 'prefer-rest-params': 0, 19 | 'prefer-spread': 0, 20 | 'prefer-const': 0, 21 | 'node/no-unpublished-require': 0, 22 | 'node/no-unpublished-import': 0, 23 | camelcase: 2, 24 | complexity: [2, 7], 25 | curly: 2, 26 | 'dot-notation': 0, 27 | 'guard-for-in': 2, 28 | 'new-cap': [2, { properties: false }], 29 | 'no-caller': 2, 30 | 'no-empty': 2, 31 | 'no-eval': 2, 32 | 'no-implied-eval': 2, 33 | 'no-multi-str': 0, 34 | 'no-new': 2, 35 | 'no-plusplus': 0, 36 | 'no-undef': 2, 37 | 'no-unused-expressions': [ 38 | 2, 39 | { allowShortCircuit: true, allowTernary: true }, 40 | ], 41 | 'no-unused-vars': ['warn', { argsIgnorePattern: '^_' }], 42 | 'max-depth': [2, 3], 43 | 'max-len': [2, 150], 44 | 'max-params': [2, 5], 45 | 'max-statements': [2, 25], 46 | quotes: [2, 'single', { allowTemplateLiterals: true }], 47 | strict: 0, 48 | 'wrap-iife': [2, 'any'], 49 | 'no-console': 'off', 50 | }, 51 | globals: { 52 | fetch: false, 53 | }, 54 | overrides: [ 55 | { 56 | // ES6 processed by Babel 57 | files: ['*.js'], 58 | plugins: ['jest', 'react'], 59 | parser: '@babel/eslint-parser', 60 | parserOptions: { 61 | ecmaFeatures: { 62 | jsx: true, 63 | }, 64 | ecmaVersion: 2020, 65 | sourceType: 'module', 66 | }, 67 | env: { 68 | es6: true, 69 | node: true, 70 | }, 71 | rules: { 72 | 'node/no-unsupported-features/es-syntax': 0, 73 | 'node/no-unsupported-features/node-builtins': 0, 74 | }, 75 | }, 76 | { 77 | // Jest specs 78 | files: ['*.test.js'], 79 | plugins: ['node', 'jest'], 80 | env: { 81 | jest: true, 82 | }, 83 | }, 84 | ], 85 | }; 86 | -------------------------------------------------------------------------------- /custom-sign-in/.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | -------------------------------------------------------------------------------- /custom-sign-in/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Debug iOS", 6 | "request": "launch", 7 | "type": "reactnative", 8 | "cwd": "${workspaceFolder}", 9 | "platform": "ios" 10 | }, 11 | { 12 | "type": "node", 13 | "name": "Run Tests", 14 | "request": "launch", 15 | "program": "${workspaceFolder}/node_modules/jest/bin/jest", 16 | "args": [ 17 | "--runInBand" 18 | ], 19 | "cwd": "${workspaceFolder}", 20 | "console": "integratedTerminal", 21 | "internalConsoleOptions": "neverOpen", 22 | "disableOptimisticBPs": true 23 | }, 24 | { 25 | "name": "Run iOS", 26 | "request": "launch", 27 | "type": "reactnative", 28 | "cwd": "${workspaceFolder}", 29 | "enableDebug": false, 30 | "platform": "ios" 31 | }, 32 | { 33 | "name": "Run Android", 34 | "request": "launch", 35 | "type": "reactnative", 36 | "cwd": "${workspaceFolder}", 37 | "enableDebug": false, 38 | "platform": "android" 39 | }, 40 | { 41 | "name": "Attach to packager", 42 | "request": "attach", 43 | "type": "reactnative", 44 | "cwd": "${workspaceFolder}" 45 | } 46 | ] 47 | } -------------------------------------------------------------------------------- /custom-sign-in/App.js: -------------------------------------------------------------------------------- 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 'react-native-gesture-handler'; 14 | import React from 'react'; 15 | import { SafeAreaView } from 'react-native'; 16 | import { isAuthenticated } from '@okta/okta-react-native'; 17 | import { NavigationContainer } from '@react-navigation/native'; 18 | import { createStackNavigator } from '@react-navigation/stack'; 19 | import LoginScreen from './app/LoginScreen.js'; 20 | import ProfileScreen from './app/ProfileScreen.js'; 21 | import { createConfig } from '@okta/okta-react-native'; 22 | import configFile from './samples.config'; 23 | import Spinner from 'react-native-loading-spinner-overlay'; 24 | 25 | const Stack = createStackNavigator(); 26 | 27 | export default class App extends React.Component { 28 | 29 | constructor() { 30 | super(); 31 | 32 | this.state = { 33 | progress: true, 34 | authenticated: false, 35 | }; 36 | 37 | this.checkAuthentication = this.checkAuthentication.bind(this); 38 | } 39 | 40 | async checkAuthentication() { 41 | const result = await isAuthenticated(); 42 | 43 | this.setState({ 44 | authenticated: result.authenticated, 45 | progress: false 46 | }); 47 | } 48 | 49 | async componentDidMount() { 50 | await createConfig({ 51 | clientId: configFile.oidc.clientId, 52 | redirectUri: configFile.oidc.redirectUri, 53 | endSessionRedirectUri: configFile.oidc.endSessionRedirectUri, 54 | discoveryUri: configFile.oidc.discoveryUri, 55 | scopes: configFile.oidc.scopes, 56 | requireHardwareBackedKeyStore: 57 | configFile.oidc.requireHardwareBackedKeyStore, 58 | }); 59 | 60 | 61 | await this.checkAuthentication(); 62 | } 63 | 64 | render() { 65 | if (this.state.progress) { 66 | return ( 67 | 68 | 69 | 70 | ); 71 | } 72 | 73 | return ( 74 | 75 | 76 | 81 | 86 | 87 | 88 | ); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /custom-sign-in/README.md: -------------------------------------------------------------------------------- 1 | # Okta React Native Custom Sign In Example 2 | 3 | This example shows you how to use the [Okta React Native SDK](https://github.com/okta/okta-react-native) to adopt Okta Authentication flow in your app. 4 | 5 | ## Clone repo 6 | To run this application, you first need to clone this repo and then enter into this directory: 7 | 8 | ```bash 9 | git clone git@github.com:okta/samples-js-react-native.git 10 | cd samples-js-react-native/custom-sign-in 11 | ``` 12 | 13 | ## Install dependencies 14 | 15 | ### Install JS dependencies 16 | Install dependencies based on package-lock.json 17 | ```bash 18 | npm ci 19 | ``` 20 | 21 | ### Install CocoaPods dependencies 22 | CocoaPods dependencies are needed for ios development 23 | ```bash 24 | cd ios && pod install && cd .. 25 | ``` 26 | 27 | ## Run sample 28 | 29 | Start app server: 30 | ```bash 31 | npm start 32 | ``` 33 | 34 | Launch an Android Emulator or iOS Simulator, then 35 | ```bash 36 | # Android 37 | npm run android 38 | 39 | # iOS 40 | npm run ios 41 | ``` 42 | 43 | ## Using This Example 44 | 45 | Enter your credentials and tap the **Login** button. You can login with the same account that you created when signing up for your Developer Org, or you can use a known username and password from your Okta Directory. 46 | 47 | After you complete the login flow, you will be able to see the details of user's account. Tap **Get Access Token** button to excahnge session token to access token via OIDC SDK. 48 | -------------------------------------------------------------------------------- /custom-sign-in/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 | -------------------------------------------------------------------------------- /custom-sign-in/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.application" 2 | apply plugin: "org.jetbrains.kotlin.android" 3 | apply plugin: "com.facebook.react" 4 | 5 | def projectRoot = rootDir.getAbsoluteFile().getParentFile().getAbsolutePath() 6 | 7 | /** 8 | * This is the configuration block to customize your React Native Android app. 9 | * By default you don't need to apply any configuration, just uncomment the lines you need. 10 | */ 11 | react { 12 | entryFile = file(["node", "-e", "require('expo/scripts/resolveAppEntry')", projectRoot, "android", "absolute"].execute(null, rootDir).text.trim()) 13 | reactNativeDir = new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim()).getParentFile().getAbsoluteFile() 14 | hermesCommand = new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim()).getParentFile().getAbsolutePath() + "/sdks/hermesc/%OS-BIN%/hermesc" 15 | codegenDir = new File(["node", "--print", "require.resolve('@react-native/codegen/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim()).getParentFile().getAbsoluteFile() 16 | 17 | // Use Expo CLI to bundle the app, this ensures the Metro config 18 | // works correctly with Expo projects. 19 | cliFile = new File(["node", "--print", "require.resolve('@expo/cli', { paths: [require.resolve('expo/package.json')] })"].execute(null, rootDir).text.trim()) 20 | bundleCommand = "export:embed" 21 | 22 | /* Folders */ 23 | // The root of your project, i.e. where "package.json" lives. Default is '../..' 24 | // root = file("../../") 25 | // The folder where the react-native NPM package is. Default is ../../node_modules/react-native 26 | // reactNativeDir = file("../../node_modules/react-native") 27 | // The folder where the react-native Codegen package is. Default is ../../node_modules/@react-native/codegen 28 | // codegenDir = file("../../node_modules/@react-native/codegen") 29 | 30 | /* Variants */ 31 | // The list of variants to that are debuggable. For those we're going to 32 | // skip the bundling of the JS bundle and the assets. By default is just 'debug'. 33 | // If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants. 34 | // debuggableVariants = ["liteDebug", "prodDebug"] 35 | 36 | /* Bundling */ 37 | // A list containing the node command and its flags. Default is just 'node'. 38 | // nodeExecutableAndArgs = ["node"] 39 | 40 | // 41 | // The path to the CLI configuration file. Default is empty. 42 | // bundleConfig = file(../rn-cli.config.js) 43 | // 44 | // The name of the generated asset file containing your JS bundle 45 | // bundleAssetName = "MyApplication.android.bundle" 46 | // 47 | // The entry file for bundle generation. Default is 'index.android.js' or 'index.js' 48 | // entryFile = file("../js/MyApplication.android.js") 49 | // 50 | // A list of extra flags to pass to the 'bundle' commands. 51 | // See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle 52 | // extraPackagerArgs = [] 53 | 54 | /* Hermes Commands */ 55 | // The hermes compiler command to run. By default it is 'hermesc' 56 | // hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc" 57 | // 58 | // The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map" 59 | // hermesFlags = ["-O", "-output-source-map"] 60 | 61 | /* Autolinking */ 62 | autolinkLibrariesWithApp() 63 | } 64 | 65 | /** 66 | * Set this to true to Run Proguard on Release builds to minify the Java bytecode. 67 | */ 68 | def enableProguardInReleaseBuilds = (findProperty('android.enableProguardInReleaseBuilds') ?: false).toBoolean() 69 | 70 | /** 71 | * The preferred build flavor of JavaScriptCore (JSC) 72 | * 73 | * For example, to use the international variant, you can use: 74 | * `def jscFlavor = 'org.webkit:android-jsc-intl:+'` 75 | * 76 | * The international variant includes ICU i18n library and necessary data 77 | * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that 78 | * give correct results when using with locales other than en-US. Note that 79 | * this variant is about 6MiB larger per architecture than default. 80 | */ 81 | def jscFlavor = 'org.webkit:android-jsc:+' 82 | 83 | android { 84 | ndkVersion rootProject.ext.ndkVersion 85 | 86 | buildToolsVersion rootProject.ext.buildToolsVersion 87 | compileSdk rootProject.ext.compileSdkVersion 88 | 89 | namespace 'com.customsignin' 90 | defaultConfig { 91 | applicationId 'com.customsignin' 92 | minSdkVersion rootProject.ext.minSdkVersion 93 | targetSdkVersion rootProject.ext.targetSdkVersion 94 | versionCode 1 95 | versionName "1.0.0" 96 | 97 | manifestPlaceholders = [ 98 | appAuthRedirectScheme: 'customUriScheme' 99 | ] 100 | } 101 | signingConfigs { 102 | debug { 103 | storeFile file('debug.keystore') 104 | storePassword 'android' 105 | keyAlias 'androiddebugkey' 106 | keyPassword 'android' 107 | } 108 | } 109 | buildTypes { 110 | debug { 111 | signingConfig signingConfigs.debug 112 | } 113 | release { 114 | // Caution! In production, you need to generate your own keystore file. 115 | // see https://reactnative.dev/docs/signed-apk-android. 116 | signingConfig signingConfigs.debug 117 | shrinkResources (findProperty('android.enableShrinkResourcesInReleaseBuilds')?.toBoolean() ?: false) 118 | minifyEnabled enableProguardInReleaseBuilds 119 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 120 | crunchPngs (findProperty('android.enablePngCrunchInReleaseBuilds')?.toBoolean() ?: true) 121 | } 122 | } 123 | packagingOptions { 124 | jniLibs { 125 | useLegacyPackaging (findProperty('expo.useLegacyPackaging')?.toBoolean() ?: false) 126 | } 127 | } 128 | androidResources { 129 | ignoreAssetsPattern '!.svn:!.git:!.ds_store:!*.scc:!CVS:!thumbs.db:!picasa.ini:!*~' 130 | } 131 | } 132 | 133 | // Apply static values from `gradle.properties` to the `android.packagingOptions` 134 | // Accepts values in comma delimited lists, example: 135 | // android.packagingOptions.pickFirsts=/LICENSE,**/picasa.ini 136 | ["pickFirsts", "excludes", "merges", "doNotStrip"].each { prop -> 137 | // Split option: 'foo,bar' -> ['foo', 'bar'] 138 | def options = (findProperty("android.packagingOptions.$prop") ?: "").split(","); 139 | // Trim all elements in place. 140 | for (i in 0.. 0) { 145 | println "android.packagingOptions.$prop += $options ($options.length)" 146 | // Ex: android.packagingOptions.pickFirsts += '**/SCCS/**' 147 | options.each { 148 | android.packagingOptions[prop] += it 149 | } 150 | } 151 | } 152 | 153 | dependencies { 154 | // The version of react-native is set by the React Native Gradle Plugin 155 | implementation("com.facebook.react:react-android") 156 | 157 | def isGifEnabled = (findProperty('expo.gif.enabled') ?: "") == "true"; 158 | def isWebpEnabled = (findProperty('expo.webp.enabled') ?: "") == "true"; 159 | def isWebpAnimatedEnabled = (findProperty('expo.webp.animated') ?: "") == "true"; 160 | 161 | if (isGifEnabled) { 162 | // For animated gif support 163 | implementation("com.facebook.fresco:animated-gif:${reactAndroidLibs.versions.fresco.get()}") 164 | } 165 | 166 | if (isWebpEnabled) { 167 | // For webp support 168 | implementation("com.facebook.fresco:webpsupport:${reactAndroidLibs.versions.fresco.get()}") 169 | if (isWebpAnimatedEnabled) { 170 | // Animated webp support 171 | implementation("com.facebook.fresco:animated-webp:${reactAndroidLibs.versions.fresco.get()}") 172 | } 173 | } 174 | 175 | if (hermesEnabled.toBoolean()) { 176 | implementation("com.facebook.react:hermes-android") 177 | } else { 178 | implementation jscFlavor 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /custom-sign-in/android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/custom-sign-in/android/app/debug.keystore -------------------------------------------------------------------------------- /custom-sign-in/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 | -------------------------------------------------------------------------------- /custom-sign-in/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /custom-sign-in/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 | -------------------------------------------------------------------------------- /custom-sign-in/android/app/src/main/java/com/customsignin/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.customsignin 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 | -------------------------------------------------------------------------------- /custom-sign-in/android/app/src/main/java/com/customsignin/MainApplication.kt: -------------------------------------------------------------------------------- 1 | package com.customsignin 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 | -------------------------------------------------------------------------------- /custom-sign-in/android/app/src/main/res/drawable-hdpi/splashscreen_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/custom-sign-in/android/app/src/main/res/drawable-hdpi/splashscreen_logo.png -------------------------------------------------------------------------------- /custom-sign-in/android/app/src/main/res/drawable-mdpi/splashscreen_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/custom-sign-in/android/app/src/main/res/drawable-mdpi/splashscreen_logo.png -------------------------------------------------------------------------------- /custom-sign-in/android/app/src/main/res/drawable-night-hdpi/splashscreen_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/custom-sign-in/android/app/src/main/res/drawable-night-hdpi/splashscreen_logo.png -------------------------------------------------------------------------------- /custom-sign-in/android/app/src/main/res/drawable-night-mdpi/splashscreen_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/custom-sign-in/android/app/src/main/res/drawable-night-mdpi/splashscreen_logo.png -------------------------------------------------------------------------------- /custom-sign-in/android/app/src/main/res/drawable-night-xhdpi/splashscreen_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/custom-sign-in/android/app/src/main/res/drawable-night-xhdpi/splashscreen_logo.png -------------------------------------------------------------------------------- /custom-sign-in/android/app/src/main/res/drawable-night-xxhdpi/splashscreen_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/custom-sign-in/android/app/src/main/res/drawable-night-xxhdpi/splashscreen_logo.png -------------------------------------------------------------------------------- /custom-sign-in/android/app/src/main/res/drawable-night-xxxhdpi/splashscreen_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/custom-sign-in/android/app/src/main/res/drawable-night-xxxhdpi/splashscreen_logo.png -------------------------------------------------------------------------------- /custom-sign-in/android/app/src/main/res/drawable-xhdpi/splashscreen_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/custom-sign-in/android/app/src/main/res/drawable-xhdpi/splashscreen_logo.png -------------------------------------------------------------------------------- /custom-sign-in/android/app/src/main/res/drawable-xxhdpi/splashscreen_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/custom-sign-in/android/app/src/main/res/drawable-xxhdpi/splashscreen_logo.png -------------------------------------------------------------------------------- /custom-sign-in/android/app/src/main/res/drawable-xxxhdpi/splashscreen_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/custom-sign-in/android/app/src/main/res/drawable-xxxhdpi/splashscreen_logo.png -------------------------------------------------------------------------------- /custom-sign-in/android/app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /custom-sign-in/android/app/src/main/res/drawable/rn_edit_text_material.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 22 | 23 | 24 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /custom-sign-in/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/custom-sign-in/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /custom-sign-in/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/custom-sign-in/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /custom-sign-in/android/app/src/main/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/custom-sign-in/android/app/src/main/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /custom-sign-in/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/custom-sign-in/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /custom-sign-in/android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/custom-sign-in/android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /custom-sign-in/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/custom-sign-in/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /custom-sign-in/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/custom-sign-in/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /custom-sign-in/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/custom-sign-in/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /custom-sign-in/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/custom-sign-in/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /custom-sign-in/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/custom-sign-in/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /custom-sign-in/android/app/src/main/res/values-night/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | #000000 3 | -------------------------------------------------------------------------------- /custom-sign-in/android/app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | #ffffff 3 | #ffffff 4 | #023c69 5 | #ffffff 6 | -------------------------------------------------------------------------------- /custom-sign-in/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | CustomSignIn 3 | contain 4 | false 5 | -------------------------------------------------------------------------------- /custom-sign-in/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 14 | 19 | -------------------------------------------------------------------------------- /custom-sign-in/android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | ext { 5 | buildToolsVersion = findProperty('android.buildToolsVersion') ?: '35.0.0' 6 | minSdkVersion = Integer.parseInt(findProperty('android.minSdkVersion') ?: '24') 7 | compileSdkVersion = Integer.parseInt(findProperty('android.compileSdkVersion') ?: '35') 8 | targetSdkVersion = Integer.parseInt(findProperty('android.targetSdkVersion') ?: '34') 9 | kotlinVersion = findProperty('android.kotlinVersion') ?: '1.9.24' 10 | 11 | ndkVersion = "26.1.10909125" 12 | } 13 | repositories { 14 | google() 15 | mavenCentral() 16 | } 17 | dependencies { 18 | classpath('com.android.tools.build:gradle') 19 | classpath('com.facebook.react:react-native-gradle-plugin') 20 | classpath('org.jetbrains.kotlin:kotlin-gradle-plugin') 21 | } 22 | } 23 | 24 | apply plugin: "com.facebook.react.rootproject" 25 | 26 | allprojects { 27 | repositories { 28 | maven { 29 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 30 | url(new File(['node', '--print', "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim(), '../android')) 31 | } 32 | maven { 33 | // Android JSC is installed from npm 34 | url(new File(['node', '--print', "require.resolve('jsc-android/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim(), '../dist')) 35 | } 36 | 37 | google() 38 | mavenCentral() 39 | maven { url 'https://www.jitpack.io' } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /custom-sign-in/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=-Xmx8192m -XX:MaxMetaspaceSize=2048m 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 | -------------------------------------------------------------------------------- /custom-sign-in/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/okta/samples-js-react-native/4f418821d2ac82f22f7873674fc6ee2909497a28/custom-sign-in/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /custom-sign-in/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 | -------------------------------------------------------------------------------- /custom-sign-in/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 | -------------------------------------------------------------------------------- /custom-sign-in/android/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | includeBuild(new File(["node", "--print", "require.resolve('@react-native/gradle-plugin/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 = 'CustomSignIn' 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 | -------------------------------------------------------------------------------- /custom-sign-in/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "CustomSignIn", 4 | "displayName": "CustomSignIn", 5 | "version": "1.0.0", 6 | "assetBundlePatterns": [ 7 | "**/*" 8 | ], 9 | "icon": "./app_logo.png", 10 | "android": { 11 | "package": "com.customsignin" 12 | }, 13 | "ios": { 14 | "bundleIdentifier": "com.customsignin" 15 | }, 16 | "plugins": [ 17 | [ 18 | "expo-splash-screen", 19 | { 20 | "backgroundColor": "#ffffff", 21 | "image": "./app_logo.png", 22 | "dark": { 23 | "image": "./app_logo.png", 24 | "backgroundColor": "#000000" 25 | }, 26 | "imageWidth": 200 27 | } 28 | ] 29 | ] 30 | }, 31 | "name": "CustomSignIn" 32 | } 33 | -------------------------------------------------------------------------------- /custom-sign-in/app/LoginScreen.js: -------------------------------------------------------------------------------- 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 React from 'react'; 14 | import { 15 | SafeAreaView, 16 | Button, 17 | StyleSheet, 18 | Text, 19 | View, 20 | StatusBar, 21 | TextInput, 22 | } from 'react-native'; 23 | import { signIn } from '@okta/okta-react-native'; 24 | import Spinner from 'react-native-loading-spinner-overlay'; 25 | import Error from './components/Error'; 26 | 27 | export default class LoginScreen extends React.Component { 28 | constructor(props) { 29 | super(props); 30 | 31 | this.state = { 32 | progress: false, 33 | username: '', 34 | password: '', 35 | error: '', 36 | }; 37 | 38 | this.login = this.login.bind(this); 39 | this.reset = this.reset.bind(this); 40 | } 41 | 42 | reset() { 43 | this.setState({ 44 | progress: false, 45 | username: '', 46 | password: '', 47 | error: '' 48 | }); 49 | } 50 | 51 | login() { 52 | if (this.state.progress == true) { 53 | return; 54 | } 55 | 56 | this.setState({ progress: true }); 57 | 58 | const { username, password } = this.state; 59 | const { navigation } = this.props; 60 | 61 | signIn({ username, password }) 62 | .then(_token => { 63 | this.setState({ 64 | progress: false, 65 | username: '', 66 | password: '', 67 | error: '' 68 | }, () => navigation.navigate('Profile')); 69 | }) 70 | .catch(error => { 71 | this.setState({ 72 | progress: false, 73 | username: '', 74 | password: '', 75 | error: error.message 76 | }); 77 | }); 78 | } 79 | 80 | render() { 81 | return ( 82 | <> 83 | 84 | 85 | 91 | Native Sign-In 92 | 93 | 94 | 95 | this.setState({ username: username })} 100 | testID="usernameTextInput" 101 | /> 102 | this.setState({ password: password })} 108 | testID="passwordTextInput" 109 | /> 110 | 111 |