├── .eslintrc.js ├── .gitattributes ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── Bug Report.yml │ ├── Feature Request.yml │ └── config.yml ├── PULL_REQUEST_TEMPLATE.md ├── actions │ ├── get-prerelease │ │ └── action.yml │ ├── get-release-notes │ │ └── action.yml │ ├── get-version │ │ └── action.yml │ ├── npm-publish │ │ └── action.yml │ ├── release-create │ │ └── action.yml │ └── tag-exists │ │ └── action.yml ├── dependabot.yml ├── stale.yml └── workflows │ ├── main.yml │ ├── npm-release.yml │ ├── release.yml │ ├── semgrep.yml │ └── snyk.yml ├── .gitignore ├── .npmignore ├── .prettierrc.js ├── .semgrepignore ├── .shiprc ├── .snyk ├── .version ├── .watchmanconfig ├── A0Auth0.podspec ├── CHANGELOG.md ├── EXAMPLES.md ├── FAQ.md ├── LICENSE ├── MIGRATION_GUIDE.md ├── README.md ├── android ├── build.gradle └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── auth0 │ └── react │ ├── A0Auth0Module.java │ ├── A0Auth0Package.java │ ├── CredentialsParser.java │ └── LocalAuthenticationOptionsParser.java ├── app.plugin.js ├── assets ├── android-app-link.png └── ios-sso-alert.png ├── babel.config.js ├── codecov.yml ├── docs ├── .nojekyll ├── assets │ ├── hierarchy.js │ ├── highlight.css │ ├── icons.js │ ├── icons.svg │ ├── main.js │ ├── navigation.js │ ├── search.js │ └── style.css ├── classes │ ├── TimeoutError.html │ ├── Types.Auth.html │ ├── Types.BaseError.html │ ├── Types.CredentialsManager.html │ ├── Types.Users.html │ ├── Types.WebAuth.html │ └── default.html ├── enums │ ├── LocalAuthenticationLevel.html │ ├── LocalAuthenticationStrategy.html │ └── SafariViewControllerPresentationStyle.html ├── functions │ ├── Auth0Provider.html │ └── useAuth0.html ├── hierarchy.html ├── index.html ├── interfaces │ ├── Auth0Options.html │ ├── AuthorizeUrlOptions.html │ ├── ClearSessionOptions.html │ ├── ClearSessionParameters.html │ ├── CreateUserOptions.html │ ├── ExchangeNativeSocialOptions.html │ ├── ExchangeOptions.html │ ├── GetUserOptions.html │ ├── LocalAuthenticationOptions.html │ ├── LoginWithEmailOptions.html │ ├── LoginWithOOBOptions.html │ ├── LoginWithOTPOptions.html │ ├── LoginWithRecoveryCodeOptions.html │ ├── LoginWithSMSOptions.html │ ├── LogoutUrlOptions.html │ ├── MultifactorChallengeOptions.html │ ├── PasswordRealmOptions.html │ ├── PasswordlessWithEmailOptions.html │ ├── PasswordlessWithSMSOptions.html │ ├── PatchUserOptions.html │ ├── RefreshTokenOptions.html │ ├── ResetPasswordOptions.html │ ├── RevokeOptions.html │ ├── Types.Auth0ContextInterface.html │ ├── Types.AuthState.html │ ├── UserInfoOptions.html │ ├── WebAuthorizeOptions.html │ └── WebAuthorizeParameters.html ├── media │ ├── FAQ.md │ ├── android-app-link.png │ └── ios-sso-alert.png ├── modules.html ├── modules │ └── Types.html └── types │ ├── Credentials.html │ ├── MultifactorChallengeOOBResponse.html │ ├── MultifactorChallengeOOBWithBindingResponse.html │ ├── MultifactorChallengeOTPResponse.html │ ├── MultifactorChallengeResponse.html │ ├── Types.Auth0Response.html │ ├── Types.Telemetry.html │ └── User.html ├── example ├── .bundle │ └── config ├── .gitignore ├── .node-version ├── .watchmanconfig ├── Gemfile ├── README.md ├── android │ ├── app │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src │ │ │ ├── debug │ │ │ ├── AndroidManifest.xml │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── auth0example │ │ │ │ └── ReactNativeFlipper.java │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── auth0example │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ └── MainApplication.kt │ │ │ └── res │ │ │ │ ├── drawable │ │ │ │ └── rn_edit_text_material.xml │ │ │ │ ├── mipmap-hdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ └── values │ │ │ │ ├── strings.xml │ │ │ │ └── styles.xml │ │ │ └── release │ │ │ └── java │ │ │ └── com │ │ │ └── auth0example │ │ │ └── ReactNativeFlipper.java │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle ├── app.json ├── babel.config.js ├── index.js ├── ios │ ├── .xcode.env │ ├── AppDelegate.swift │ ├── Auth0Example-Bridging-Header.h │ ├── Auth0Example.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Auth0Example.xcscheme │ ├── Auth0Example.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── Auth0Example │ │ ├── AppDelegate.swift │ │ ├── Images.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ └── Contents.json │ │ ├── Info.plist │ │ ├── LaunchScreen.storyboard │ │ ├── PrivacyInfo.xcprivacy │ │ └── main.m │ ├── Auth0ExampleTests │ │ ├── Auth0ExampleTests.m │ │ └── Info.plist │ ├── File.swift │ ├── Podfile │ └── Podfile.lock ├── metro.config.js ├── package-lock.json ├── package.json ├── react-native.config.js └── src │ ├── App.tsx │ └── auth0-configuration.js ├── ios ├── A0Auth0-Bridging-Header.h ├── A0Auth0.h ├── A0Auth0.m ├── A0Auth0.xcodeproj │ └── project.pbxproj ├── A0Auth0.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── NativeBridge.swift ├── jest.environment.js ├── opslevel.yml ├── package-lock.json ├── package.json ├── scripts └── jsdocs.js ├── src ├── auth │ ├── __tests__ │ │ ├── __snapshots__ │ │ │ └── index.spec.js.snap │ │ └── index.spec.js │ ├── auth0Error.ts │ ├── authError.ts │ └── index.ts ├── auth0.ts ├── credentials-manager │ ├── __tests__ │ │ └── credentials-manager.spec.js │ ├── credentialsManagerError.ts │ ├── index.ts │ ├── localAuthenticationLevel.ts │ ├── localAuthenticationOptions.ts │ └── localAuthenticationStrategy.ts ├── hooks │ ├── __tests__ │ │ └── use-auth0.spec.jsx │ ├── auth0-context.ts │ ├── auth0-provider.tsx │ ├── reducer.ts │ └── use-auth0.ts ├── index.ts ├── internal-types.ts ├── jwt │ └── utils.ts ├── management │ ├── __tests__ │ │ ├── __snapshots__ │ │ │ └── users.spec.js.snap │ │ └── users.spec.js │ ├── error.ts │ └── users.ts ├── networking │ ├── __tests__ │ │ ├── __snapshots__ │ │ │ └── index.spec.js.snap │ │ ├── index.spec.js │ │ └── telemetry.spec.js │ ├── index.ts │ └── telemetry.ts ├── plugin │ ├── __tests__ │ │ ├── __snapshots__ │ │ │ └── withAuth0-test.ts.snap │ │ ├── fixtures │ │ │ ├── appdelegate-withlinking.ts │ │ │ ├── appdelegate-withoutlinking.ts │ │ │ └── buildgradle.ts │ │ └── withAuth0-test.ts │ ├── generateCode.ts │ └── withAuth0.ts ├── types.ts ├── utils │ ├── __tests__ │ │ ├── __snapshots__ │ │ │ ├── timestampConversion.spec.js.snap │ │ │ └── whitelist.spec.js.snap │ │ ├── addDefaultLocalAuthOptions.spec.js │ │ ├── timestampConversion.spec.js │ │ ├── userConversion.spec.js │ │ └── whitelist.spec.js │ ├── addDefaultLocalAuthOptions.ts │ ├── baseError.ts │ ├── camel.ts │ ├── deepEqual.ts │ ├── fetchWithTimeout.ts │ ├── nativeHelper.ts │ ├── timestampConversion.ts │ ├── userConversion.ts │ └── whitelist.ts └── webauth │ ├── __mocks__ │ ├── auth0.js │ └── react-native.js │ ├── __tests__ │ ├── __snapshots__ │ │ ├── agent.spec.js.snap │ │ └── webauth.spec.js.snap │ ├── agent.spec.js │ └── webauth.spec.js │ ├── agent.ts │ └── index.ts ├── tsconfig.build.json ├── tsconfig.json └── typedoc.json /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: '@react-native-community', 4 | }; -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @auth0/project-dx-sdks-engineer-codeowner 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Bug Report.yml: -------------------------------------------------------------------------------- 1 | name: 🐞 Report a bug 2 | description: Have you found a bug or issue? Create a bug report for this library 3 | labels: ['bug'] 4 | 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: | 9 | **Please do not report security vulnerabilities here**. The [Responsible Disclosure Program](https://auth0.com/responsible-disclosure-policy) details the procedure for disclosing security issues. 10 | 11 | - type: checkboxes 12 | id: checklist 13 | attributes: 14 | label: Checklist 15 | options: 16 | - label: The issue can be reproduced in the [react-native-auth0 sample app](https://github.com/auth0-samples/auth0-react-native-sample) (or N/A). 17 | required: true 18 | - label: I have looked into the [Readme](https://github.com/auth0/react-native-auth0#readme), [Examples](https://github.com/auth0/react-native-auth0/blob/master/EXAMPLES.md), and [FAQ](https://github.com/auth0/react-native-auth0/blob/master/FAQ.md) and have not found a suitable solution or answer. 19 | required: true 20 | - label: I have looked into the [API documentation](https://auth0.github.io/react-native-auth0/) and have not found a suitable solution or answer. 21 | required: true 22 | - label: I have searched the [issues](https://github.com/auth0/react-native-auth0/issues) and have not found a suitable solution or answer. 23 | required: true 24 | - label: I have searched the [Auth0 Community](https://community.auth0.com) forums and have not found a suitable solution or answer. 25 | required: true 26 | - label: I agree to the terms within the [Auth0 Code of Conduct](https://github.com/auth0/open-source-template/blob/master/CODE-OF-CONDUCT.md). 27 | required: true 28 | 29 | - type: textarea 30 | id: description 31 | attributes: 32 | label: Description 33 | description: Provide a clear and concise description of the issue, including what you expected to happen. 34 | validations: 35 | required: true 36 | 37 | - type: textarea 38 | id: reproduction 39 | attributes: 40 | label: Reproduction 41 | description: Detail the steps taken to reproduce this error, and whether this issue can be reproduced consistently or if it is intermittent. 42 | placeholder: | 43 | 1. Step 1... 44 | 2. Step 2... 45 | 3. ... 46 | validations: 47 | required: true 48 | 49 | - type: textarea 50 | id: additional-context 51 | attributes: 52 | label: Additional context 53 | description: Other libraries that might be involved, or any other relevant information you think would be useful. 54 | validations: 55 | required: false 56 | 57 | - type: input 58 | id: environment-version 59 | attributes: 60 | label: react-native-auth0 version 61 | validations: 62 | required: true 63 | 64 | - type: input 65 | id: environment-react-native-version 66 | attributes: 67 | label: React Native version 68 | validations: 69 | required: true 70 | 71 | - type: input 72 | id: environment-expo-version 73 | attributes: 74 | label: Expo version 75 | validations: 76 | required: false 77 | 78 | - type: dropdown 79 | id: environment-platform 80 | attributes: 81 | label: Platform 82 | multiple: true 83 | options: 84 | - Android 85 | - iOS 86 | validations: 87 | required: true 88 | 89 | - type: input 90 | id: environment-platform-version 91 | attributes: 92 | label: Platform version(s) 93 | validations: 94 | required: true 95 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Feature Request.yml: -------------------------------------------------------------------------------- 1 | name: 🧩 Feature request 2 | description: Suggest an idea or a feature for this library 3 | labels: ['feature request'] 4 | 5 | body: 6 | - type: checkboxes 7 | id: checklist 8 | attributes: 9 | label: Checklist 10 | options: 11 | - label: I have looked into the [Readme](https://github.com/auth0/react-native-auth0#readme), [Examples](https://github.com/auth0/react-native-auth0/blob/master/EXAMPLES.md), and [FAQ](https://github.com/auth0/react-native-auth0/blob/master/FAQ.md) and have not found a suitable solution or answer. 12 | required: true 13 | - label: I have looked into the [API documentation](https://auth0.github.io/react-native-auth0/) and have not found a suitable solution or answer. 14 | required: true 15 | - label: I have searched the [issues](https://github.com/auth0/react-native-auth0/issues) and have not found a suitable solution or answer. 16 | required: true 17 | - label: I have searched the [Auth0 Community](https://community.auth0.com) forums and have not found a suitable solution or answer. 18 | required: true 19 | - label: I agree to the terms within the [Auth0 Code of Conduct](https://github.com/auth0/open-source-template/blob/master/CODE-OF-CONDUCT.md). 20 | required: true 21 | 22 | - type: textarea 23 | id: description 24 | attributes: 25 | label: Describe the problem you'd like to have solved 26 | description: A clear and concise description of what the problem is. 27 | placeholder: I'm always frustrated when... 28 | validations: 29 | required: true 30 | 31 | - type: textarea 32 | id: ideal-solution 33 | attributes: 34 | label: Describe the ideal solution 35 | description: A clear and concise description of what you want to happen. 36 | validations: 37 | required: true 38 | 39 | - type: textarea 40 | id: alternatives-and-workarounds 41 | attributes: 42 | label: Alternatives and current workarounds 43 | description: A clear and concise description of any alternatives you've considered or any workarounds that are currently in place. 44 | validations: 45 | required: false 46 | 47 | - type: textarea 48 | id: additional-context 49 | attributes: 50 | label: Additional context 51 | description: Add any other context or screenshots about the feature request here. 52 | validations: 53 | required: false 54 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Auth0 Community 4 | url: https://community.auth0.com 5 | about: Discuss this SDK in the Auth0 Community forums 6 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### Changes 2 | 3 | Please describe both what is changing and why this is important. Include: 4 | 5 | - Endpoints added, deleted, deprecated, or changed 6 | - Classes and methods added, deleted, deprecated, or changed 7 | - Screenshots of new or changed UI, if applicable 8 | - A summary of usage if this is a new feature or change to a public API (this should also be added to relevant documentation once released) 9 | 10 | ### References 11 | 12 | Please include relevant links supporting this change such as a: 13 | 14 | - support ticket 15 | - community post 16 | - StackOverflow post 17 | - support forum thread 18 | 19 | Please note any links that are not publicly accessible. 20 | 21 | ### Testing 22 | 23 | Please describe how this can be tested by reviewers. Be specific about anything not tested and reasons why. If this library has unit and/or integration testing, tests should be added for new functionality and existing tests should complete without errors. 24 | 25 | - [ ] This change adds unit test coverage 26 | - [ ] This change has been tested on the latest version of the platform/language or why not 27 | 28 | ### Checklist 29 | 30 | - [ ] I have read the [Auth0 general contribution guidelines](https://github.com/auth0/open-source-template/blob/master/GENERAL-CONTRIBUTING.md) 31 | - [ ] All existing and new tests complete without errors 32 | - [ ] All active GitHub checks have passed 33 | -------------------------------------------------------------------------------- /.github/actions/get-prerelease/action.yml: -------------------------------------------------------------------------------- 1 | name: Return a boolean indicating if the version contains prerelease identifiers 2 | 3 | # 4 | # Returns a simple true/false boolean indicating whether the version indicates it's a prerelease or not. 5 | # 6 | # TODO: Remove once the common repo is public. 7 | # 8 | 9 | inputs: 10 | version: 11 | required: true 12 | 13 | outputs: 14 | prerelease: 15 | value: ${{ steps.get_prerelease.outputs.PRERELEASE }} 16 | 17 | runs: 18 | using: composite 19 | 20 | steps: 21 | - id: get_prerelease 22 | shell: bash 23 | run: | 24 | if [[ "${VERSION}" == *"beta"* || "${VERSION}" == *"alpha"* ]]; then 25 | echo "PRERELEASE=true" >> $GITHUB_OUTPUT 26 | else 27 | echo "PRERELEASE=false" >> $GITHUB_OUTPUT 28 | fi 29 | env: 30 | VERSION: ${{ inputs.version }} -------------------------------------------------------------------------------- /.github/actions/get-release-notes/action.yml: -------------------------------------------------------------------------------- 1 | name: Return the release notes extracted from the body of the PR associated with the release. 2 | 3 | # 4 | # Returns the release notes from the content of a pull request linked to a release branch. It expects the branch name to be in the format release/vX.Y.Z, release/X.Y.Z, release/vX.Y.Z-beta.N. etc. 5 | # 6 | # TODO: Remove once the common repo is public. 7 | # 8 | inputs: 9 | version: 10 | required: true 11 | repo_name: 12 | required: false 13 | repo_owner: 14 | required: true 15 | token: 16 | required: true 17 | 18 | outputs: 19 | release-notes: 20 | value: ${{ steps.get_release_notes.outputs.RELEASE_NOTES }} 21 | 22 | runs: 23 | using: composite 24 | 25 | steps: 26 | - uses: actions/github-script@v7 27 | id: get_release_notes 28 | with: 29 | result-encoding: string 30 | script: | 31 | const { data: pulls } = await github.rest.pulls.list({ 32 | owner: process.env.REPO_OWNER, 33 | repo: process.env.REPO_NAME, 34 | state: 'all', 35 | head: `${process.env.REPO_OWNER}:release/${process.env.VERSION}`, 36 | }); 37 | core.setOutput('RELEASE_NOTES', pulls[0].body); 38 | env: 39 | GITHUB_TOKEN: ${{ inputs.token }} 40 | REPO_OWNER: ${{ inputs.repo_owner }} 41 | REPO_NAME: ${{ inputs.repo_name }} 42 | VERSION: ${{ inputs.version }} 43 | -------------------------------------------------------------------------------- /.github/actions/get-version/action.yml: -------------------------------------------------------------------------------- 1 | name: Return the version extracted from the branch name 2 | 3 | # 4 | # Returns the version from the .version file. 5 | # 6 | # TODO: Remove once the common repo is public. 7 | # 8 | 9 | outputs: 10 | version: 11 | value: ${{ steps.get_version.outputs.VERSION }} 12 | 13 | runs: 14 | using: composite 15 | 16 | steps: 17 | - id: get_version 18 | shell: bash 19 | run: | 20 | VERSION=$(head -1 .version) 21 | echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT 22 | -------------------------------------------------------------------------------- /.github/actions/npm-publish/action.yml: -------------------------------------------------------------------------------- 1 | name: Publish release to npm 2 | 3 | inputs: 4 | node-version: 5 | required: true 6 | npm-token: 7 | required: true 8 | version: 9 | required: true 10 | require-build: 11 | default: true 12 | release-directory: 13 | default: './' 14 | 15 | runs: 16 | using: composite 17 | 18 | steps: 19 | - name: Checkout code 20 | uses: actions/checkout@v4 21 | 22 | - name: Setup Node 23 | uses: actions/setup-node@v4 24 | with: 25 | node-version: ${{ inputs.node-version }} 26 | cache: 'npm' 27 | registry-url: 'https://registry.npmjs.org' 28 | 29 | - name: Install dependencies 30 | shell: bash 31 | run: npm ci --include=dev 32 | 33 | - name: Build package 34 | if: inputs.require-build == 'true' 35 | shell: bash 36 | run: npm run build 37 | 38 | - name: Publish release to NPM 39 | shell: bash 40 | working-directory: ${{ inputs.release-directory }} 41 | run: | 42 | if [[ "${VERSION}" == *"beta"* ]]; then 43 | TAG="beta" 44 | elif [[ "${VERSION}" == *"alpha"* ]]; then 45 | TAG="alpha" 46 | else 47 | TAG="latest" 48 | fi 49 | npm publish --provenance --tag $TAG 50 | env: 51 | NODE_AUTH_TOKEN: ${{ inputs.npm-token }} 52 | VERSION: ${{ inputs.version }} 53 | -------------------------------------------------------------------------------- /.github/actions/release-create/action.yml: -------------------------------------------------------------------------------- 1 | name: Create a GitHub release 2 | 3 | # 4 | # Creates a GitHub release with the given version. 5 | # 6 | # TODO: Remove once the common repo is public. 7 | # 8 | 9 | inputs: 10 | token: 11 | required: true 12 | files: 13 | required: false 14 | name: 15 | required: true 16 | body: 17 | required: true 18 | tag: 19 | required: true 20 | commit: 21 | required: true 22 | draft: 23 | default: false 24 | required: false 25 | prerelease: 26 | default: false 27 | required: false 28 | fail_on_unmatched_files: 29 | default: true 30 | required: false 31 | 32 | runs: 33 | using: composite 34 | 35 | steps: 36 | - uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 37 | with: 38 | body: ${{ inputs.body }} 39 | name: ${{ inputs.name }} 40 | tag_name: ${{ inputs.tag }} 41 | target_commitish: ${{ inputs.commit }} 42 | draft: ${{ inputs.draft }} 43 | prerelease: ${{ inputs.prerelease }} 44 | fail_on_unmatched_files: ${{ inputs.fail_on_unmatched_files }} 45 | files: ${{ inputs.files }} 46 | env: 47 | GITHUB_TOKEN: ${{ inputs.token }} -------------------------------------------------------------------------------- /.github/actions/tag-exists/action.yml: -------------------------------------------------------------------------------- 1 | name: Return a boolean indicating if a tag already exists for the repository 2 | 3 | # 4 | # Returns a simple true/false boolean indicating whether the tag exists or not. 5 | # 6 | # TODO: Remove once the common repo is public. 7 | # 8 | 9 | inputs: 10 | token: 11 | required: true 12 | tag: 13 | required: true 14 | 15 | outputs: 16 | exists: 17 | description: 'Whether the tag exists or not' 18 | value: ${{ steps.tag-exists.outputs.EXISTS }} 19 | 20 | runs: 21 | using: composite 22 | 23 | steps: 24 | - id: tag-exists 25 | shell: bash 26 | run: | 27 | GET_API_URL="https://api.github.com/repos/${GITHUB_REPOSITORY}/git/ref/tags/${TAG_NAME}" 28 | http_status_code=$(curl -LI $GET_API_URL -o /dev/null -w '%{http_code}\n' -s -H "Authorization: token ${GITHUB_TOKEN}") 29 | if [ "$http_status_code" -ne "404" ] ; then 30 | echo "EXISTS=true" >> $GITHUB_OUTPUT 31 | else 32 | echo "EXISTS=false" >> $GITHUB_OUTPUT 33 | fi 34 | env: 35 | TAG_NAME: ${{ inputs.tag }} 36 | GITHUB_TOKEN: ${{ inputs.token }} 37 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | updates: 4 | - package-ecosystem: github-actions 5 | directory: / 6 | schedule: 7 | interval: daily 8 | - package-ecosystem: "npm" 9 | directory: "/" 10 | schedule: 11 | interval: "daily" 12 | ignore: 13 | - dependency-name: "*" 14 | update-types: ["version-update:semver-major"] 15 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Configuration for probot-stale - https://github.com/probot/stale 2 | 3 | # Number of days of inactivity before an Issue or Pull Request becomes stale 4 | daysUntilStale: 90 5 | 6 | # Number of days of inactivity before an Issue or Pull Request with the stale label is closed. 7 | daysUntilClose: 7 8 | 9 | # Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable 10 | exemptLabels: [] 11 | 12 | # Set to true to ignore issues with an assignee (defaults to false) 13 | exemptAssignees: true 14 | 15 | # Label to use when marking as stale 16 | staleLabel: closed:stale 17 | 18 | # Comment to post when marking as stale. Set to `false` to disable 19 | markComment: > 20 | This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you have not received a response for our team (apologies for the delay) and this is still a blocker, please reply with additional information or just a ping. Thank you for your contribution! 🙇‍♂️ -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | pull_request: 5 | types: 6 | - opened 7 | - synchronize 8 | 9 | permissions: {} 10 | 11 | concurrency: 12 | group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} 13 | cancel-in-progress: ${{ github.ref != 'refs/heads/master' }} 14 | 15 | jobs: 16 | test: 17 | name: Run JS tests 18 | runs-on: ubuntu-latest 19 | 20 | env: 21 | node: 'lts/*' 22 | 23 | steps: 24 | - name: Checkout 25 | uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 26 | 27 | - name: Setup Node.js 28 | uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 29 | with: 30 | node-version: ${{ env.node }} 31 | cache: 'npm' 32 | 33 | - name: Install dependencies 34 | run: npm ci 35 | 36 | - name: Run tests 37 | run: npm run test:ci 38 | 39 | - name: Upload coverage report 40 | uses: codecov/codecov-action@ad3126e916f78f00edff4ed0317cf185271ccc2d 41 | with: 42 | directory: coverage 43 | -------------------------------------------------------------------------------- /.github/workflows/npm-release.yml: -------------------------------------------------------------------------------- 1 | name: Create npm and GitHub Release 2 | 3 | on: 4 | workflow_call: 5 | inputs: 6 | node-version: 7 | required: true 8 | type: string 9 | require-build: 10 | default: true 11 | type: string 12 | release-directory: 13 | default: './' 14 | type: string 15 | secrets: 16 | github-token: 17 | required: true 18 | npm-token: 19 | required: true 20 | 21 | jobs: 22 | release: 23 | if: github.event_name == 'workflow_dispatch' || (github.event_name == 'pull_request' && github.event.pull_request.merged && startsWith(github.event.pull_request.head.ref, 'release/')) 24 | runs-on: ubuntu-latest 25 | environment: release 26 | 27 | steps: 28 | # Checkout the code 29 | - uses: actions/checkout@v4 30 | with: 31 | fetch-depth: 0 32 | 33 | # Get the version from the branch name 34 | - id: get_version 35 | uses: ./.github/actions/get-version 36 | 37 | # Get the prerelease flag from the branch name 38 | - id: get_prerelease 39 | uses: ./.github/actions/get-prerelease 40 | with: 41 | version: ${{ steps.get_version.outputs.version }} 42 | 43 | # Get the release notes 44 | - id: get_release_notes 45 | uses: ./.github/actions/get-release-notes 46 | with: 47 | token: ${{ secrets.github-token }} 48 | version: ${{ steps.get_version.outputs.version }} 49 | repo_owner: ${{ github.repository_owner }} 50 | repo_name: ${{ github.event.repository.name }} 51 | 52 | # Check if the tag already exists 53 | - id: tag_exists 54 | uses: ./.github/actions/tag-exists 55 | with: 56 | tag: ${{ steps.get_version.outputs.version }} 57 | token: ${{ secrets.github-token }} 58 | 59 | # If the tag already exists, exit with an error 60 | - if: steps.tag_exists.outputs.exists == 'true' 61 | run: exit 1 62 | 63 | # Publish the release to our package manager 64 | - uses: ./.github/actions/npm-publish 65 | with: 66 | node-version: ${{ inputs.node-version }} 67 | require-build: ${{ inputs.require-build }} 68 | version: ${{ steps.get_version.outputs.version }} 69 | npm-token: ${{ secrets.npm-token }} 70 | release-directory: ${{ inputs.release-directory }} 71 | 72 | # Create a release for the tag 73 | - uses: ./.github/actions/release-create 74 | with: 75 | token: ${{ secrets.github-token }} 76 | name: ${{ steps.get_version.outputs.version }} 77 | body: ${{ steps.get_release_notes.outputs.release-notes }} 78 | tag: ${{ steps.get_version.outputs.version }} 79 | commit: ${{ github.sha }} 80 | prerelease: ${{ steps.get_prerelease.outputs.prerelease }} 81 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Create npm and GitHub Release 2 | 3 | on: 4 | pull_request: 5 | types: 6 | - closed 7 | workflow_dispatch: 8 | 9 | permissions: 10 | contents: write 11 | id-token: write # For publishing to npm using --provenance 12 | 13 | ### TODO: Replace instances of './.github/workflows/' w/ `auth0/dx-sdk-actions/workflows/` and append `@latest` after the common `dx-sdk-actions` repo is made public. 14 | ### TODO: Also remove `get-prerelease`, `get-release-notes`, `get-version`, `npm-publish`, `release-create`, and `tag-exists` actions from this repo's .github/actions folder once the repo is public. 15 | ### TODO: Also remove `npm-release` workflow from this repo's .github/workflows folder once the repo is public. 16 | 17 | jobs: 18 | release: 19 | uses: ./.github/workflows/npm-release.yml 20 | with: 21 | node-version: 20 22 | require-build: false 23 | secrets: 24 | npm-token: ${{ secrets.NPM_TOKEN }} 25 | github-token: ${{ secrets.GITHUB_TOKEN }} 26 | -------------------------------------------------------------------------------- /.github/workflows/semgrep.yml: -------------------------------------------------------------------------------- 1 | name: Semgrep 2 | 3 | on: 4 | merge_group: 5 | pull_request: 6 | types: 7 | - opened 8 | - synchronize 9 | push: 10 | branches: 11 | - master 12 | schedule: 13 | - cron: '30 0 1,15 * *' 14 | 15 | permissions: 16 | contents: read 17 | 18 | concurrency: 19 | group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} 20 | cancel-in-progress: ${{ github.ref != 'refs/heads/master' }} 21 | 22 | jobs: 23 | run: 24 | name: Check for Vulnerabilities 25 | runs-on: ubuntu-latest 26 | 27 | container: 28 | image: returntocorp/semgrep 29 | 30 | steps: 31 | - if: github.actor == 'dependabot[bot]' || github.event_name == 'merge_group' 32 | run: exit 0 # Skip unnecessary test runs for dependabot and merge queues. Artifically flag as successful, as this is a required check for branch protection. 33 | 34 | - uses: actions/checkout@v4 35 | with: 36 | ref: ${{ github.event.pull_request.head.sha || github.ref }} 37 | 38 | - run: semgrep ci 39 | env: 40 | SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }} 41 | -------------------------------------------------------------------------------- /.github/workflows/snyk.yml: -------------------------------------------------------------------------------- 1 | name: Snyk 2 | 3 | on: 4 | merge_group: 5 | workflow_dispatch: 6 | pull_request: 7 | types: 8 | - opened 9 | - synchronize 10 | push: 11 | branches: 12 | - master 13 | schedule: 14 | - cron: '30 0 1,15 * *' 15 | 16 | permissions: 17 | contents: read 18 | 19 | concurrency: 20 | group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} 21 | cancel-in-progress: ${{ github.ref != 'refs/heads/master' }} 22 | 23 | jobs: 24 | check: 25 | name: Check for Vulnerabilities 26 | runs-on: ubuntu-latest 27 | 28 | steps: 29 | - if: github.actor == 'dependabot[bot]' || github.event_name == 'merge_group' 30 | run: exit 0 # Skip unnecessary test runs for dependabot and merge queues. Artifically flag as successful, as this is a required check for branch protection. 31 | 32 | - uses: actions/checkout@v4 33 | with: 34 | ref: ${{ github.event.pull_request.head.sha || github.ref }} 35 | 36 | - run: npm install -g snyk 37 | 38 | - run: snyk test 39 | env: 40 | SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # XDE 6 | .expo/ 7 | 8 | # VSCode 9 | .vscode/ 10 | jsconfig.json 11 | 12 | # Xcode 13 | # 14 | build/ 15 | *.pbxuser 16 | !default.pbxuser 17 | *.mode1v3 18 | !default.mode1v3 19 | *.mode2v3 20 | !default.mode2v3 21 | *.perspectivev3 22 | !default.perspectivev3 23 | xcuserdata 24 | *.xccheckout 25 | *.moved-aside 26 | DerivedData 27 | *.hmap 28 | *.ipa 29 | *.xcuserstate 30 | project.xcworkspace 31 | 32 | # Android/IJ 33 | # 34 | .classpath 35 | .cxx 36 | .gradle 37 | .idea 38 | .project 39 | .settings 40 | local.properties 41 | android.iml 42 | 43 | # Cocoapods 44 | # 45 | example/ios/Pods 46 | 47 | # Ruby 48 | example/vendor/ 49 | 50 | # node.js 51 | # 52 | node_modules/ 53 | npm-debug.log 54 | yarn-debug.log 55 | yarn-error.log 56 | 57 | # BUCK 58 | buck-out/ 59 | \.buckd/ 60 | android/app/libs 61 | android/keystores/debug.keystore 62 | 63 | # Expo 64 | .expo/ 65 | 66 | # Turborepo 67 | .turbo/ 68 | 69 | # generated by bob 70 | lib/ 71 | 72 | # Other 73 | dist/ 74 | out/ 75 | coverage/ -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/auth0/react-native-auth0/96db5d5d9bb2d0dd1a9fdfd38478c86aef48fcd4/.npmignore -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | bracketSpacing: false, 3 | jsxBracketSameLine: true, 4 | singleQuote: true, 5 | trailingComma: 'all', 6 | }; -------------------------------------------------------------------------------- /.semgrepignore: -------------------------------------------------------------------------------- 1 | docs/ 2 | src/auth/__tests__ 3 | src/credentials-manager/__tests__ 4 | src/hooks/__tests__ 5 | src/jwt/__tests__ 6 | src/management/__tests__ 7 | src/networking/__tests__ 8 | src/utils/__tests__ 9 | src/webauth/__mocks__ 10 | src/webauth/__tests__ 11 | -------------------------------------------------------------------------------- /.shiprc: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "src/networking/telemetry.ts": [], 4 | ".version": [] 5 | }, 6 | "postbump": "node scripts/jsdocs.js" 7 | } 8 | -------------------------------------------------------------------------------- /.snyk: -------------------------------------------------------------------------------- 1 | # Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities. 2 | version: v1.25.0 3 | # ignores vulnerabilities until expiry date; change duration by modifying expiry date 4 | ignore: 5 | SNYK-JS-INFLIGHT-6095116: 6 | - '*': 7 | reason: No fix available 8 | expires: 2025-05-12T09:15:05.191Z 9 | created: 2025-02-02T05:47:18.380Z 10 | SNYK-JS-BABELHELPERS-9397697: 11 | - '*': 12 | reason: This issue is temporarily ignored while we evaluate alternative dependencies or wait for an update from Expo/Metro. 13 | expires: 2025-05-12T09:15:05.191Z 14 | created: 2025-03-12T09:15:05.191Z 15 | SNYK-JS-IMAGESIZE-9634164: 16 | - '*': 17 | reason: This issue is temporarily ignored untill there is a new release of react native fixed this issue. 18 | expires: 2025-05-12T09:15:05.191Z 19 | created: 2025-04-07T09:15:05.191Z 20 | snyk:lic:npm:lightningcss-win32-x64-msvc:MPL-2.0: 21 | - '*': 22 | reason: This issue is temporarily ignored while we evaluate alternative dependencies or wait for an update from Expo/Metro. 23 | expires: 2025-05-12T09:15:05.191Z 24 | created: 2025-03-12T09:15:05.191Z 25 | snyk:lic:npm:lightningcss-linux-x64-musl:MPL-2.0: 26 | - '*': 27 | reason: This issue is temporarily ignored while we evaluate alternative dependencies or wait for an update from Expo/Metro. 28 | expires: 2025-05-12T09:15:05.191Z 29 | created: 2025-03-12T09:15:05.191Z 30 | snyk:lic:npm:lightningcss-linux-x64-gnu:MPL-2.0: 31 | - '*': 32 | reason: This issue is temporarily ignored while we evaluate alternative dependencies or wait for an update from Expo/Metro. 33 | expires: 2025-05-12T09:15:05.191Z 34 | created: 2025-03-12T09:15:05.191Z 35 | snyk:lic:npm:lightningcss-linux-arm64-musl:MPL-2.0: 36 | - '*': 37 | reason: This issue is temporarily ignored while we evaluate alternative dependencies or wait for an update from Expo/Metro. 38 | expires: 2025-05-12T09:15:05.191Z 39 | created: 2025-03-12T09:15:05.191Z 40 | snyk:lic:npm:lightningcss-linux-arm64-gnu:MPL-2.0: 41 | - '*': 42 | reason: This issue is temporarily ignored while we evaluate alternative dependencies or wait for an update from Expo/Metro. 43 | expires: 2025-05-12T09:15:05.191Z 44 | created: 2025-03-12T09:15:05.191Z 45 | snyk:lic:npm:lightningcss-linux-arm-gnueabihf:MPL-2.0: 46 | - '*': 47 | reason: This issue is temporarily ignored while we evaluate alternative dependencies or wait for an update from Expo/Metro. 48 | expires: 2025-05-12T09:15:05.191Z 49 | created: 2025-03-12T09:15:05.191Z 50 | snyk:lic:npm:lightningcss-freebsd-x64:MPL-2.0: 51 | - '*': 52 | reason: This issue is temporarily ignored while we evaluate alternative dependencies or wait for an update from Expo/Metro. 53 | expires: 2025-05-12T09:15:05.191Z 54 | created: 2025-03-12T09:15:05.191Z 55 | snyk:lic:npm:lightningcss-darwin-x64:MPL-2.0: 56 | - '*': 57 | reason: This issue is temporarily ignored while we evaluate alternative dependencies or wait for an update from Expo/Metro. 58 | expires: 2025-05-12T09:15:05.191Z 59 | created: 2025-03-12T09:15:05.191Z 60 | snyk:lic:npm:lightningcss-darwin-arm64:MPL-2.0: 61 | - '*': 62 | reason: This issue is temporarily ignored while we evaluate alternative dependencies or wait for an update from Expo/Metro. 63 | expires: 2025-05-12T09:15:05.191Z 64 | created: 2025-03-12T09:15:05.191Z 65 | snyk:lic:npm:lightningcss:MPL-2.0: 66 | - '*': 67 | reason: This issue is temporarily ignored while we evaluate alternative dependencies or wait for an update from Expo/Metro. 68 | expires: 2025-05-12T09:15:05.191Z 69 | created: 2025-03-12T09:15:05.191Z 70 | snyk:lic:npm:lightningcss-win32-arm64-msvc:MPL-2.0: 71 | - '*': 72 | reason: This issue is temporarily ignored while we evaluate alternative dependencies or wait for an update from Expo/Metro. 73 | expires: 2025-05-12T09:15:05.191Z 74 | created: 2025-03-12T09:15:05.191Z 75 | patch: {} 76 | -------------------------------------------------------------------------------- /.version: -------------------------------------------------------------------------------- 1 | v4.6.0 -------------------------------------------------------------------------------- /.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /A0Auth0.podspec: -------------------------------------------------------------------------------- 1 | require 'json' 2 | 3 | package = JSON.parse(File.read(File.join(__dir__, 'package.json'))) 4 | 5 | Pod::Spec.new do |s| 6 | s.name = 'A0Auth0' 7 | s.version = package['version'] 8 | s.summary = package['description'] 9 | s.homepage = package['repository']['baseUrl'] 10 | s.license = package['license'] 11 | s.authors = package['author'] 12 | s.platforms = { :ios => '13.0' } 13 | s.source = { :git => 'https://github.com/auth0/react-native-auth0.git', :tag => "v#{s.version}" } 14 | 15 | s.source_files = 'ios/**/*.{h,m,mm,swift}' 16 | s.pod_target_xcconfig = { 'HEADER_SEARCH_PATHS' => "'${PODS_CONFIGURATION_BUILD_DIR}/#{s.name}/#{s.name}.framework/Headers'" } 17 | s.requires_arc = true 18 | 19 | s.dependency 'React-Core' 20 | s.dependency 'Auth0', '2.10' 21 | s.dependency 'JWTDecode', '3.2.0' 22 | s.dependency 'SimpleKeychain', '1.2.0' 23 | end 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2019 Auth0, Inc. (http://auth0.com) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /MIGRATION_GUIDE.md: -------------------------------------------------------------------------------- 1 | # Migration Guide 2 | 3 | ## Upgrading from v3 -> v4 4 | 5 | - **If your project is built with Expo:** 6 | - Run `npx expo prebuild --clean` to ensure the intent-filters in `android` & custom scheme's in iOS are propertly setup. Please note that any manual changes to Android or iOS folders will be lost when this command is executed. 7 | 8 | ### Breaking Changes: 9 | 10 | - `requireLocalAuthentication` method is no longer available as part of the `CredentialsManager` class or the `useAuth0` Hook from v4 of the SDK. Refer below sections on how to enable authentication before obtaining credentials now. 11 | 12 | ### Changes: 13 | 14 | - Updated the `Auth0` class constructor to accept a new parameter, `LocalAuthenticationOptions`, for enabling authentication before obtaining credentials as shown below: 15 | 16 | ``` 17 | const localAuthOptions: LocalAuthenticationOptions = { 18 | title: 'Authenticate to retreive your credentials', 19 | subtitle: 'Please authenticate to continue', 20 | description: 'We need to authenticate you to retrieve your credentials', 21 | cancelTitle: 'Cancel', 22 | evaluationPolicy: LocalAuthenticationStrategy.deviceOwnerWithBiometrics, 23 | fallbackTitle: 'Use Passcode', 24 | authenticationLevel: LocalAuthenticationLevel.strong, 25 | deviceCredentialFallback: true, 26 | } 27 | const auth0 = new Auth0({ domain: config.domain, clientId: config.clientId, localAuthenticationOptions: localAuthOptions }); 28 | ``` 29 | 30 | Modified the `Auth0Provider` to accept `LocalAuthenticationOptions` as a parameter to enable authentication before obtaining credentials. 31 | 32 | ``` 33 | const localAuthOptions: LocalAuthenticationOptions = { 34 | title: 'Authenticate to retreive your credentials', 35 | subtitle: 'Please authenticate to continue', 36 | description: 'We need to authenticate you to retrieve your credentials', 37 | cancelTitle: 'Cancel', 38 | evaluationPolicy: LocalAuthenticationStrategy.deviceOwnerWithBiometrics, 39 | fallbackTitle: 'Use Passcode', 40 | authenticationLevel: LocalAuthenticationLevel.strong, 41 | deviceCredentialFallback: true, 42 | }; 43 | 44 | const App = () => { 45 | return ( 46 | 51 | {/* YOUR APP */} 52 | 53 | ); 54 | }; 55 | 56 | export default App; 57 | ``` 58 | 59 | ## Upgrading from v2 -> v3 60 | 61 | ### Improvements and changes 62 | 63 | - Web Auth will now have default scope of 'openid profile email', so these scopes can be removed if you're explicitly specifying them 64 | - Minimum supported version for iOS is bumped to 13 65 | - Minimum supported version for Expo is bumped to 48 66 | - Revoke Token and Change Password now return `void` instead of an empty object 67 | 68 | ### Breaking changes 69 | 70 | - The properties inside the `user` object will now be camelCase instead of snake_case 71 | - Removed the `type` property returned in the `Credentials` object in Android. Use `tokenType` instead. 72 | - `Credentials` object in iOS will return `expiresAt` instead of `expiresIn` 73 | - `expiresIn` value will now return `expiresAt` value which is a UNIX timestamp of the expiration time. 74 | - `max_age` parameter is changed to `maxAge` in `WebAuth.authorize()` 75 | - `skipLegacyListener` has been removed in `authorize` and `clearSession` 76 | - `customScheme` is now part of `ClearSessionOptions` instead of `ClearSessionParameters` in `clearSession` 77 | - iOS minimum deployment target is now 13. This can be migrated by adding `platform :ios '13.0'` to the ios/Podfile file 78 | - Additional or custom parameters to be sent in `authorize` method should now be sent as `additionalParameters`. This includes when sending `prompt` parameter. 79 | - Error codes are now platform specific. For example - When user cancels authentication, Android error code is `a0.session.user_cancelled` and iOS error code is `USER_CANCELLED` 80 | 81 | ### Callback URL migration 82 | 83 | We are migrating the callback URL we use for the SDK to below. 84 | 85 | **Old** 86 | 87 | ``` 88 | iOS: {PRODUCT_BUNDLE_IDENTIFIER}://{DOMAIN}/ios/{PRODUCT_BUNDLE_IDENTIFIER}/callback 89 | Android: {YOUR_APP_PACKAGE_NAME}://{DOMAIN}/android/{YOUR_APP_PACKAGE_NAME}/callback 90 | ``` 91 | 92 | **New** 93 | 94 | Notice the new `.auth0` suffix after the bundle identifier / package name: 95 | 96 | ``` 97 | iOS: {PRODUCT_BUNDLE_IDENTIFIER}.auth0://{DOMAIN}/ios/{PRODUCT_BUNDLE_IDENTIFIER}/callback 98 | Android: {YOUR_APP_PACKAGE_NAME}.auth0://{DOMAIN}/android/{YOUR_APP_PACKAGE_NAME}/callback 99 | ``` 100 | 101 | Choose one of the following migration paths depending on your application: 102 | 103 | - **If your project is built with Expo:** 104 | - To keep things as it is, no changes are required 105 | - To migrate to new non-custom scheme flow: 106 | - Remove custom scheme in app.json and `authorize()`. 107 | - Run `npx expo prebuild --clean` (any manual changes to Android or iOS folders will be lost) 108 | - Add the new callback URL to Auth0 dashboard 109 | - **If your project is built with Non Expo:** 110 | 111 | - To keep things as it is, set `useLegacyCallbackUrl` to true in `authorize` and `clearSession` 112 | - To migrate to new non-custom scheme flow, add the new callback URL to Auth0 dashboard 113 | - Change the manifest placeholders in your app's build.gradle file (typically at android/app/build.gradle): 114 | 115 | **Old** 116 | 117 | ``` 118 | android { 119 | defaultConfig { 120 | manifestPlaceholders = [auth0Domain: "YOUR_AUTH0_DOMAIN", auth0Scheme: "${applicationId}"] 121 | } 122 | ... 123 | } 124 | ``` 125 | 126 | **New** 127 | 128 | Notice the new `.auth0` suffix in auth0Scheme: 129 | 130 | ``` 131 | android { 132 | defaultConfig { 133 | manifestPlaceholders = [auth0Domain: "YOUR_AUTH0_DOMAIN", auth0Scheme: "${applicationId}.auth0"] 134 | } 135 | ... 136 | } 137 | ``` 138 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.safeExtGet = {prop, fallback -> 3 | rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback 4 | } 5 | repositories { 6 | google() 7 | mavenCentral() 8 | } 9 | 10 | dependencies { 11 | // Matches recent template from React Native (0.67) 12 | // https://github.com/facebook/react-native/blob/0.67-stable/template/android/build.gradle#L16 13 | classpath("com.android.tools.build:gradle:${safeExtGet('gradlePluginVersion', '4.2.2')}") 14 | } 15 | } 16 | 17 | apply plugin: 'com.android.library' 18 | apply plugin: 'maven-publish' 19 | 20 | // Matches values in recent template from React Native 0.62 21 | // https://github.com/facebook/react-native/blob/0.62-stable/template/android/build.gradle#L5-L8 22 | def DEFAULT_COMPILE_SDK_VERSION = 34 23 | def DEFAULT_BUILD_TOOLS_VERSION = "28.0.3" 24 | def DEFAULT_MIN_SDK_VERSION = 16 25 | def DEFAULT_TARGET_SDK_VERSION = 34 26 | 27 | android { 28 | compileSdkVersion safeExtGet('compileSdkVersion', DEFAULT_COMPILE_SDK_VERSION) 29 | buildToolsVersion safeExtGet('buildToolsVersion', DEFAULT_BUILD_TOOLS_VERSION) 30 | namespace 'com.auth0.react' 31 | 32 | defaultConfig { 33 | minSdkVersion safeExtGet('minSdkVersion', DEFAULT_MIN_SDK_VERSION) 34 | targetSdkVersion safeExtGet('targetSdkVersion', DEFAULT_TARGET_SDK_VERSION) 35 | versionCode 1 36 | versionName "1.0" 37 | } 38 | lintOptions { 39 | abortOnError false 40 | } 41 | compileOptions { 42 | sourceCompatibility JavaVersion.VERSION_1_8 43 | targetCompatibility JavaVersion.VERSION_1_8 44 | } 45 | } 46 | 47 | repositories { 48 | maven { 49 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 50 | // Matches recent template from React Native 0.62 51 | // https://github.com/facebook/react-native/blob/0.62-stable/template/android/build.gradle#L27 52 | url "$projectDir/../node_modules/react-native/android" 53 | } 54 | mavenCentral() 55 | } 56 | 57 | dependencies { 58 | implementation "com.facebook.react:react-native:${safeExtGet('reactnativeVersion', '+')}" 59 | implementation "androidx.browser:browser:1.2.0" 60 | implementation 'com.auth0.android:auth0:3.2.1' 61 | } 62 | 63 | def configureReactNativePom(def pom) { 64 | def packageJson = new groovy.json.JsonSlurper().parseText(file('../package.json').text) 65 | 66 | pom.project { 67 | name packageJson.title 68 | artifactId packageJson.name 69 | version = packageJson.version 70 | group = "com.auth0.react" 71 | description packageJson.description 72 | url packageJson.repository.baseUrl 73 | 74 | licenses { 75 | license { 76 | name packageJson.license 77 | url packageJson.repository.baseUrl + '/blob/master/' + packageJson.licenseFilename 78 | distribution 'repo' 79 | } 80 | } 81 | 82 | developers { 83 | developer { 84 | id packageJson.author.username 85 | name packageJson.author.name 86 | } 87 | } 88 | } 89 | } 90 | 91 | afterEvaluate { project -> 92 | 93 | task androidJavadoc(type: Javadoc) { 94 | source = android.sourceSets.main.java.srcDirs 95 | classpath += files(android.bootClasspath) 96 | include '**/*.java' 97 | } 98 | 99 | task androidJavadocJar(type: Jar, dependsOn: androidJavadoc) { 100 | archiveClassifier = 'javadoc' 101 | from androidJavadoc.destinationDir 102 | } 103 | 104 | task androidSourcesJar(type: Jar) { 105 | archiveClassifier = 'sources' 106 | from android.sourceSets.main.java.srcDirs 107 | include '**/*.java' 108 | } 109 | 110 | android.libraryVariants.all { variant -> 111 | def name = variant.name.capitalize() 112 | def javaCompileTask = variant.javaCompileProvider.get() 113 | 114 | task "jar${name}"(type: Jar, dependsOn: javaCompileTask) { 115 | from javaCompileTask.destinationDir 116 | } 117 | } 118 | 119 | artifacts { 120 | archives androidSourcesJar 121 | archives androidJavadocJar 122 | } 123 | 124 | publishing { 125 | publications { 126 | maven(MavenPublication) { 127 | artifact androidSourcesJar 128 | } 129 | } 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/src/main/java/com/auth0/react/A0Auth0Package.java: -------------------------------------------------------------------------------- 1 | package com.auth0.react; 2 | 3 | import java.util.Arrays; 4 | import java.util.Collections; 5 | import java.util.List; 6 | 7 | import com.facebook.react.ReactPackage; 8 | import com.facebook.react.bridge.NativeModule; 9 | import com.facebook.react.bridge.ReactApplicationContext; 10 | import com.facebook.react.uimanager.ViewManager; 11 | 12 | public class A0Auth0Package implements ReactPackage { 13 | @Override 14 | public List createNativeModules(ReactApplicationContext reactContext) { 15 | return Arrays.asList(new A0Auth0Module(reactContext)); 16 | } 17 | 18 | @Override 19 | public List createViewManagers(ReactApplicationContext reactContext) { 20 | return Collections.emptyList(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /android/src/main/java/com/auth0/react/CredentialsParser.java: -------------------------------------------------------------------------------- 1 | package com.auth0.react; 2 | 3 | import com.auth0.android.authentication.storage.CredentialsManagerException; 4 | import com.auth0.android.result.Credentials; 5 | import com.facebook.react.bridge.ReadableMap; 6 | import com.facebook.react.bridge.WritableNativeMap; 7 | 8 | import java.text.ParseException; 9 | import java.text.SimpleDateFormat; 10 | import java.util.Date; 11 | import java.util.Locale; 12 | 13 | public class CredentialsParser { 14 | 15 | private static final String ACCESS_TOKEN_KEY = "accessToken"; 16 | private static final String ID_TOKEN_KEY = "idToken"; 17 | private static final String EXPIRES_AT_KEY = "expiresAt"; 18 | private static final String SCOPE = "scope"; 19 | private static final String REFRESH_TOKEN_KEY = "refreshToken"; 20 | private static final String TOKEN_TYPE_KEY = "tokenType"; 21 | private static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"; 22 | 23 | public static ReadableMap toMap(Credentials credentials) { 24 | WritableNativeMap map = new WritableNativeMap(); 25 | map.putString(ACCESS_TOKEN_KEY, credentials.getAccessToken()); 26 | map.putDouble(EXPIRES_AT_KEY, credentials.getExpiresAt().getTime() / 1000); 27 | map.putString(ID_TOKEN_KEY, credentials.getIdToken()); 28 | map.putString(SCOPE, credentials.getScope()); 29 | map.putString(REFRESH_TOKEN_KEY, credentials.getRefreshToken()); 30 | map.putString(TOKEN_TYPE_KEY, credentials.getType()); 31 | return map; 32 | } 33 | 34 | public static Credentials fromMap(ReadableMap map) { 35 | String idToken = map.getString(ID_TOKEN_KEY); 36 | String accessToken = map.getString(ACCESS_TOKEN_KEY); 37 | String tokenType = map.getString(TOKEN_TYPE_KEY); 38 | String refreshToken = map.getString(REFRESH_TOKEN_KEY); 39 | String scope = map.getString(SCOPE); 40 | Double expiresAtUnix = map.getDouble(EXPIRES_AT_KEY); 41 | Date expiresAt = new Date(expiresAtUnix.longValue() * 1000); 42 | return new Credentials( 43 | idToken, 44 | accessToken, 45 | tokenType, 46 | refreshToken, 47 | expiresAt, 48 | scope 49 | ); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /android/src/main/java/com/auth0/react/LocalAuthenticationOptionsParser.java: -------------------------------------------------------------------------------- 1 | package com.auth0.react; 2 | 3 | import com.auth0.android.authentication.storage.AuthenticationLevel; 4 | import com.auth0.android.authentication.storage.LocalAuthenticationOptions; 5 | import com.facebook.react.bridge.ReadableMap; 6 | 7 | public class LocalAuthenticationOptionsParser { 8 | private static final String TITLE_KEY = "title"; 9 | private static final String SUBTITLE_KEY = "subtitle"; 10 | private static final String DESCRIPTION_KEY = "description"; 11 | private static final String CANCEL_TITLE_KEY = "cancel"; 12 | private static final String AUTHENTICATION_LEVEL_KEY = "authenticationLevel"; 13 | private static final String DEVICE_CREDENTIAL_FALLBACK_KEY = "deviceCredentialFallback"; 14 | 15 | 16 | public static LocalAuthenticationOptions fromMap(ReadableMap map) { 17 | String title = map.getString(TITLE_KEY); 18 | if (title == null) { 19 | throw new IllegalArgumentException("LocalAuthenticationOptionsParser: fromMap: The 'title' field is required"); 20 | } 21 | String subtitle = map.getString(SUBTITLE_KEY); 22 | String description = map.getString(DESCRIPTION_KEY); 23 | String cancelTitle = map.getString(CANCEL_TITLE_KEY); 24 | 25 | boolean deviceCredentialFallback = map.getBoolean(DEVICE_CREDENTIAL_FALLBACK_KEY); 26 | LocalAuthenticationOptions.Builder builder = new LocalAuthenticationOptions.Builder() 27 | .setTitle(title) 28 | .setSubTitle(subtitle) 29 | .setDescription(description) 30 | .setDeviceCredentialFallback(deviceCredentialFallback); 31 | 32 | if (!map.hasKey(AUTHENTICATION_LEVEL_KEY)) { 33 | builder.setAuthenticationLevel(AuthenticationLevel.STRONG); 34 | } else { 35 | AuthenticationLevel level = getAuthenticationLevelFromInt(map.getInt(AUTHENTICATION_LEVEL_KEY)); 36 | builder.setAuthenticationLevel(level); 37 | } 38 | if (cancelTitle != null) { 39 | builder.setNegativeButtonText(cancelTitle); 40 | } 41 | return builder.build(); 42 | } 43 | 44 | static AuthenticationLevel getAuthenticationLevelFromInt(int level) { 45 | switch (level) { 46 | case 0: 47 | return AuthenticationLevel.STRONG; 48 | case 1: 49 | return AuthenticationLevel.WEAK; 50 | default: 51 | return AuthenticationLevel.DEVICE_CREDENTIAL; 52 | } 53 | } 54 | } 55 | 56 | -------------------------------------------------------------------------------- /app.plugin.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./lib/commonjs/plugin/withAuth0'); 2 | -------------------------------------------------------------------------------- /assets/android-app-link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/auth0/react-native-auth0/96db5d5d9bb2d0dd1a9fdfd38478c86aef48fcd4/assets/android-app-link.png -------------------------------------------------------------------------------- /assets/ios-sso-alert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/auth0/react-native-auth0/96db5d5d9bb2d0dd1a9fdfd38478c86aef48fcd4/assets/ios-sso-alert.png -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:metro-react-native-babel-preset'], 3 | sourceMaps: true, 4 | }; 5 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | coverage: 2 | precision: 2 3 | round: down 4 | range: '70...100' 5 | ignore: 6 | - 'src/networking/telemetry.ts' 7 | status: 8 | project: 9 | default: 10 | enabled: true 11 | target: auto 12 | threshold: 1% 13 | if_no_uploads: error 14 | patch: 15 | default: 16 | enabled: true 17 | target: 80% 18 | threshold: 30% 19 | if_no_uploads: error 20 | changes: 21 | default: 22 | enabled: true 23 | if_no_uploads: error 24 | comment: false 25 | -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- 1 | TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. -------------------------------------------------------------------------------- /docs/assets/hierarchy.js: -------------------------------------------------------------------------------- 1 | window.hierarchyData = 2 | 'eJyNj8FqwzAQRP9lzkraCNexdGtLDz23N+ODsDdYRJaKtIaW4H8vrrFxQkNyWtid4b09IYbACbrMVCbkXlUCkQ6OarbBJ+gTpFTj8KYjaHzajkLPbzGGCIGj9Q30ThYCfXTQqJ1JidLDOrdtuXMQ0w0anJrNWNxMi0FA7teMF5PoNuDni9J2id5gCNStdU0kD11KqaoRWuQr6HPP7eNr8Ezf/O6Z4sHUtAjIp3wWsPNxdvi3edVnqY9/Zyq7UPhgw/dj/9J3oM7fL/JqGIZf7LeoRQ=='; 3 | -------------------------------------------------------------------------------- /docs/assets/highlight.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --light-hl-0: #000000; 3 | --dark-hl-0: #c8c8c8; 4 | --light-hl-1: #000000; 5 | --dark-hl-1: #d4d4d4; 6 | --light-hl-2: #001080; 7 | --dark-hl-2: #9cdcfe; 8 | --light-hl-3: #a31515; 9 | --dark-hl-3: #ce9178; 10 | --light-hl-4: #0451a5; 11 | --dark-hl-4: #9cdcfe; 12 | --light-hl-5: #cd3131; 13 | --dark-hl-5: #f44747; 14 | --light-hl-6: #af00db; 15 | --dark-hl-6: #c586c0; 16 | --light-hl-7: #0000ff; 17 | --dark-hl-7: #569cd6; 18 | --light-hl-8: #0070c1; 19 | --dark-hl-8: #4fc1ff; 20 | --light-hl-9: #008000; 21 | --dark-hl-9: #6a9955; 22 | --light-hl-10: #795e26; 23 | --dark-hl-10: #dcdcaa; 24 | --light-hl-11: #267f99; 25 | --dark-hl-11: #4ec9b0; 26 | --light-code-background: #ffffff; 27 | --dark-code-background: #1e1e1e; 28 | } 29 | 30 | @media (prefers-color-scheme: light) { 31 | :root { 32 | --hl-0: var(--light-hl-0); 33 | --hl-1: var(--light-hl-1); 34 | --hl-2: var(--light-hl-2); 35 | --hl-3: var(--light-hl-3); 36 | --hl-4: var(--light-hl-4); 37 | --hl-5: var(--light-hl-5); 38 | --hl-6: var(--light-hl-6); 39 | --hl-7: var(--light-hl-7); 40 | --hl-8: var(--light-hl-8); 41 | --hl-9: var(--light-hl-9); 42 | --hl-10: var(--light-hl-10); 43 | --hl-11: var(--light-hl-11); 44 | --code-background: var(--light-code-background); 45 | } 46 | } 47 | 48 | @media (prefers-color-scheme: dark) { 49 | :root { 50 | --hl-0: var(--dark-hl-0); 51 | --hl-1: var(--dark-hl-1); 52 | --hl-2: var(--dark-hl-2); 53 | --hl-3: var(--dark-hl-3); 54 | --hl-4: var(--dark-hl-4); 55 | --hl-5: var(--dark-hl-5); 56 | --hl-6: var(--dark-hl-6); 57 | --hl-7: var(--dark-hl-7); 58 | --hl-8: var(--dark-hl-8); 59 | --hl-9: var(--dark-hl-9); 60 | --hl-10: var(--dark-hl-10); 61 | --hl-11: var(--dark-hl-11); 62 | --code-background: var(--dark-code-background); 63 | } 64 | } 65 | 66 | :root[data-theme='light'] { 67 | --hl-0: var(--light-hl-0); 68 | --hl-1: var(--light-hl-1); 69 | --hl-2: var(--light-hl-2); 70 | --hl-3: var(--light-hl-3); 71 | --hl-4: var(--light-hl-4); 72 | --hl-5: var(--light-hl-5); 73 | --hl-6: var(--light-hl-6); 74 | --hl-7: var(--light-hl-7); 75 | --hl-8: var(--light-hl-8); 76 | --hl-9: var(--light-hl-9); 77 | --hl-10: var(--light-hl-10); 78 | --hl-11: var(--light-hl-11); 79 | --code-background: var(--light-code-background); 80 | } 81 | 82 | :root[data-theme='dark'] { 83 | --hl-0: var(--dark-hl-0); 84 | --hl-1: var(--dark-hl-1); 85 | --hl-2: var(--dark-hl-2); 86 | --hl-3: var(--dark-hl-3); 87 | --hl-4: var(--dark-hl-4); 88 | --hl-5: var(--dark-hl-5); 89 | --hl-6: var(--dark-hl-6); 90 | --hl-7: var(--dark-hl-7); 91 | --hl-8: var(--dark-hl-8); 92 | --hl-9: var(--dark-hl-9); 93 | --hl-10: var(--dark-hl-10); 94 | --hl-11: var(--dark-hl-11); 95 | --code-background: var(--dark-code-background); 96 | } 97 | 98 | .hl-0 { 99 | color: var(--hl-0); 100 | } 101 | .hl-1 { 102 | color: var(--hl-1); 103 | } 104 | .hl-2 { 105 | color: var(--hl-2); 106 | } 107 | .hl-3 { 108 | color: var(--hl-3); 109 | } 110 | .hl-4 { 111 | color: var(--hl-4); 112 | } 113 | .hl-5 { 114 | color: var(--hl-5); 115 | } 116 | .hl-6 { 117 | color: var(--hl-6); 118 | } 119 | .hl-7 { 120 | color: var(--hl-7); 121 | } 122 | .hl-8 { 123 | color: var(--hl-8); 124 | } 125 | .hl-9 { 126 | color: var(--hl-9); 127 | } 128 | .hl-10 { 129 | color: var(--hl-10); 130 | } 131 | .hl-11 { 132 | color: var(--hl-11); 133 | } 134 | pre, 135 | code { 136 | background: var(--code-background); 137 | } 138 | -------------------------------------------------------------------------------- /docs/assets/navigation.js: -------------------------------------------------------------------------------- 1 | window.navigationData = 2 | 'eJydl11P2zAUhv9LrqvxocFY79YKTUiwVk0ZF4iLQ3LSWDh2ZZ8Uumn/fXLUNh9Njl0uiZ/zvMY5dtznvxHhB0XjaLldo41G0Rooj8ZRodNSoj2rHn/JqZDRKHoTKo3Gl6MoyYVMDapo/HwQ/Cgpr+sTCdYe6t1YW3JxefNvdKidgMVbY7QZEhwAzjI1mKIiAdI+gIIVDuqOSc77aNHYIVU1yFU/4Su3NLthzuDGz6dauT/vFKHJIMHaJ/aPmqt9xHfe4dV1JyAmIJ+0Ynyi8wXatVa2ISNnaE5uj3Rc59+/XVxdNnxLlFggmW2/6zDc73lpmO51AtJlu9eeAAmt7nGDshajKgt7NsS1E254c0wGCFfbAPkeHfbHkIERvwW+u1dqtJRo5gYtKtoZthK7SUFFw5kpZlBKOu7Z3QDXrUtRoC5paDs3Rr09P1u7udrermwCvpbURvzBRyN9vg7HaacSwcRordCK0/Zwodo5GCiQWmfPgLlGWblBIHQHFjvjLsUpbz+SHNQKfwGJDcY6EcCuMsOHxISoA3Q/kXyr0EY4Wc+m5sTDOB+yEupJUH5bgGBXuJcMUs9mkyBxzYVpl/Mw7YEL0i4w0Rs026lO2bbgCoKC4oc4yF9zHq0uyXMWdSFO+FBKEhkkpM00BynRs00YnouZg7Xv2qQSrQ3qQ67glCDP8g/jISELBFmE6JsgL6Yk950tXYgTLjAzaPOlfkP2WOnheK1F2v9zvPcY5MUb/cY2YIvgVG6F7lSmOVmH4XS7i3b1jeeUPVyo1vPF7kc9X+z975TuDbgx5LtF92752WTonu7BP5nmNudEqFSo1YnBPZWfmsNyflJwjX8m7ZSo0BzX7F2fe+arq67Kc6M3Im0KslIlVXuftYC27fprQ1RarNA+x37sqPzlP/gAwEA='; 3 | -------------------------------------------------------------------------------- /docs/media/android-app-link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/auth0/react-native-auth0/96db5d5d9bb2d0dd1a9fdfd38478c86aef48fcd4/docs/media/android-app-link.png -------------------------------------------------------------------------------- /docs/media/ios-sso-alert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/auth0/react-native-auth0/96db5d5d9bb2d0dd1a9fdfd38478c86aef48fcd4/docs/media/ios-sso-alert.png -------------------------------------------------------------------------------- /example/.bundle/config: -------------------------------------------------------------------------------- 1 | BUNDLE_PATH: "vendor/bundle" 2 | BUNDLE_FORCE_RUBY_PLATFORM: 1 3 | -------------------------------------------------------------------------------- /example/.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 | 25 | # Android/IntelliJ 26 | # 27 | build/ 28 | .idea 29 | .gradle 30 | local.properties 31 | *.iml 32 | 33 | # node.js 34 | # 35 | node_modules/ 36 | package-lock.json # include if you are using npm - don't use both yarn and npm 37 | npm-debug.log 38 | yarn-error.log 39 | yarn.lock # include if you are using yarn - don't use both npm and yarn 40 | 41 | # BUCK 42 | buck-out/ 43 | \.buckd/ 44 | *.keystore 45 | 46 | # Fastlane 47 | # 48 | # It is recommended to not store the screenshots in the git repo. Instead, use Fastlane to re-generate the 49 | # screenshots whenever they are needed. 50 | # For more information about the recommended setup visit: 51 | # https://docs.fastlane.tools/best-practices/source-control/ 52 | 53 | */fastlane/report.xml 54 | */fastlane/Preview.html 55 | */fastlane/screenshots 56 | 57 | # Bundle artifact 58 | *.jsbundle -------------------------------------------------------------------------------- /example/.node-version: -------------------------------------------------------------------------------- 1 | 18 2 | -------------------------------------------------------------------------------- /example/.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /example/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version 4 | ruby '>= 2.6.10' 5 | 6 | # Exclude problematic versions of cocoapods and activesupport that causes build failures. 7 | gem 'cocoapods', '>= 1.13', '!= 1.15.0', '!= 1.15.1' 8 | gem 'activesupport', '>= 6.1.7.5', '!= 7.1.0' 9 | gem 'xcodeproj', '< 1.26.0' 10 | gem 'concurrent-ruby', '< 1.3.4' -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | ## Running the Example Application 🏃‍♂️ 2 | 3 | The Example application can be used for development purpose of the SDK. To integrate with Auth0, it is better to use the [Quickstart](https://auth0.com/docs/quickstart/native/react-native/interactive) and [Sample App](https://github.com/auth0-samples/auth0-react-native-sample/tree/master/00-Login-Hooks) applications 4 | 5 | To run the example application inside the repository, follow these steps: 6 | 7 | 1. Open a terminal or command prompt. 8 | 2. Run `npm run bootstrap` to set up the project. 9 | 3. Run `npm run prepare` to build the project. 10 | 4. To run the application: 11 | For Android, run `npm run example:android`. 12 | For iOS, run `npm run example:ios`. 13 | 14 | The application will be built and launched on the specified platform, allowing you to interact with it. 15 | 16 | ### To run on different Auth0 Application 17 | 18 | 1. Change the `clientId` and `domain` value in `example/src/auth0-configuration.js` 19 | 2. For Android, Change the `android:host` values in `example/android/app/src/main/AndroidManifest.xml` 20 | -------------------------------------------------------------------------------- /example/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 | # Add any project specific keep options here: 11 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /example/android/app/src/debug/java/com/auth0example/ReactNativeFlipper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | *

This source code is licensed under the MIT license found in the LICENSE file in the root 5 | * directory of this source tree. 6 | */ 7 | package com.auth0example; 8 | 9 | import android.content.Context; 10 | import com.facebook.flipper.android.AndroidFlipperClient; 11 | import com.facebook.flipper.android.utils.FlipperUtils; 12 | import com.facebook.flipper.core.FlipperClient; 13 | import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin; 14 | import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin; 15 | import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin; 16 | import com.facebook.flipper.plugins.inspector.DescriptorMapping; 17 | import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin; 18 | import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor; 19 | import com.facebook.flipper.plugins.network.NetworkFlipperPlugin; 20 | import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin; 21 | import com.facebook.react.ReactInstanceEventListener; 22 | import com.facebook.react.ReactInstanceManager; 23 | import com.facebook.react.bridge.ReactContext; 24 | import com.facebook.react.modules.network.NetworkingModule; 25 | import okhttp3.OkHttpClient; 26 | 27 | /** 28 | * Class responsible of loading Flipper inside your React Native application. This is the debug 29 | * flavor of it. Here you can add your own plugins and customize the Flipper setup. 30 | */ 31 | public class ReactNativeFlipper { 32 | public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { 33 | if (FlipperUtils.shouldEnableFlipper(context)) { 34 | final FlipperClient client = AndroidFlipperClient.getInstance(context); 35 | 36 | client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults())); 37 | client.addPlugin(new DatabasesFlipperPlugin(context)); 38 | client.addPlugin(new SharedPreferencesFlipperPlugin(context)); 39 | client.addPlugin(CrashReporterPlugin.getInstance()); 40 | 41 | NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin(); 42 | NetworkingModule.setCustomClientBuilder( 43 | new NetworkingModule.CustomClientBuilder() { 44 | @Override 45 | public void apply(OkHttpClient.Builder builder) { 46 | builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin)); 47 | } 48 | }); 49 | client.addPlugin(networkFlipperPlugin); 50 | client.start(); 51 | 52 | // Fresco Plugin needs to ensure that ImagePipelineFactory is initialized 53 | // Hence we run if after all native modules have been initialized 54 | ReactContext reactContext = reactInstanceManager.getCurrentReactContext(); 55 | if (reactContext == null) { 56 | reactInstanceManager.addReactInstanceEventListener( 57 | new ReactInstanceEventListener() { 58 | @Override 59 | public void onReactContextInitialized(ReactContext reactContext) { 60 | reactInstanceManager.removeReactInstanceEventListener(this); 61 | reactContext.runOnNativeModulesQueueThread( 62 | new Runnable() { 63 | @Override 64 | public void run() { 65 | client.addPlugin(new FrescoFlipperPlugin()); 66 | } 67 | }); 68 | } 69 | }); 70 | } else { 71 | client.addPlugin(new FrescoFlipperPlugin()); 72 | } 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 13 | 20 | 21 | 22 | 23 | 24 | 25 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 38 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/auth0example/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.auth0example; 2 | 3 | import com.facebook.react.ReactActivity; 4 | import com.facebook.react.ReactActivityDelegate; 5 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint; 6 | import com.facebook.react.defaults.DefaultReactActivityDelegate; 7 | 8 | public class MainActivity extends ReactActivity { 9 | 10 | /** 11 | * Returns the name of the main component registered from JavaScript. This is used to schedule 12 | * rendering of the component. 13 | */ 14 | @Override 15 | protected String getMainComponentName() { 16 | return "Auth0Example"; 17 | } 18 | 19 | /** 20 | * Returns the instance of the {@link ReactActivityDelegate}. Here we use a util class {@link 21 | * DefaultReactActivityDelegate} which allows you to easily enable Fabric and Concurrent React 22 | * (aka React 18) with two boolean flags. 23 | */ 24 | @Override 25 | protected ReactActivityDelegate createReactActivityDelegate() { 26 | return new DefaultReactActivityDelegate( 27 | this, 28 | getMainComponentName(), 29 | // If you opted-in for the New Architecture, we enable the Fabric Renderer. 30 | DefaultNewArchitectureEntryPoint.getFabricEnabled(), // fabricEnabled 31 | // If you opted-in for the New Architecture, we enable Concurrent React (i.e. React 18). 32 | DefaultNewArchitectureEntryPoint.getConcurrentReactEnabled() // concurrentRootEnabled 33 | ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/auth0example/MainApplication.kt: -------------------------------------------------------------------------------- 1 | package com.auth0example 2 | 3 | import android.app.Application 4 | import android.content.BroadcastReceiver 5 | import android.content.Intent 6 | import android.content.IntentFilter 7 | import android.os.Build 8 | import com.facebook.react.PackageList 9 | import com.facebook.react.ReactApplication 10 | import com.facebook.react.ReactHost 11 | import com.facebook.react.ReactNativeHost 12 | import com.facebook.react.ReactPackage 13 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load 14 | import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost 15 | import com.facebook.react.defaults.DefaultReactNativeHost 16 | import com.facebook.react.soloader.OpenSourceMergedSoMapping 17 | import com.facebook.soloader.SoLoader 18 | 19 | class MainApplication : Application(), ReactApplication { 20 | 21 | override val reactNativeHost: ReactNativeHost = 22 | object : DefaultReactNativeHost(this) { 23 | override fun getPackages(): List = 24 | PackageList(this).packages.apply { 25 | // Packages that cannot be autolinked yet can be added manually here, for example: 26 | // add(MyReactNativePackage()) 27 | } 28 | 29 | override fun getJSMainModuleName(): String = "index" 30 | 31 | override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG 32 | 33 | override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED 34 | override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED 35 | } 36 | 37 | override val reactHost: ReactHost 38 | get() = getDefaultReactHost(applicationContext, reactNativeHost) 39 | 40 | override fun onCreate() { 41 | super.onCreate() 42 | SoLoader.init(this, OpenSourceMergedSoMapping) 43 | if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { 44 | // If you opted-in for the New Architecture, we load the native entry point for this app. 45 | load() 46 | } 47 | } 48 | 49 | override fun registerReceiver(receiver: BroadcastReceiver?, filter: IntentFilter?): Intent? { 50 | return if (Build.VERSION.SDK_INT >= 34 && applicationInfo.targetSdkVersion >= 34) { 51 | super.registerReceiver(receiver, filter, RECEIVER_EXPORTED) 52 | } else { 53 | super.registerReceiver(receiver, filter) 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/rn_edit_text_material.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 21 | 22 | 23 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/auth0/react-native-auth0/96db5d5d9bb2d0dd1a9fdfd38478c86aef48fcd4/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/auth0/react-native-auth0/96db5d5d9bb2d0dd1a9fdfd38478c86aef48fcd4/example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/auth0/react-native-auth0/96db5d5d9bb2d0dd1a9fdfd38478c86aef48fcd4/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/auth0/react-native-auth0/96db5d5d9bb2d0dd1a9fdfd38478c86aef48fcd4/example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/auth0/react-native-auth0/96db5d5d9bb2d0dd1a9fdfd38478c86aef48fcd4/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/auth0/react-native-auth0/96db5d5d9bb2d0dd1a9fdfd38478c86aef48fcd4/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/auth0/react-native-auth0/96db5d5d9bb2d0dd1a9fdfd38478c86aef48fcd4/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/auth0/react-native-auth0/96db5d5d9bb2d0dd1a9fdfd38478c86aef48fcd4/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/auth0/react-native-auth0/96db5d5d9bb2d0dd1a9fdfd38478c86aef48fcd4/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/auth0/react-native-auth0/96db5d5d9bb2d0dd1a9fdfd38478c86aef48fcd4/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Auth0Example 3 | 4 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /example/android/app/src/release/java/com/auth0example/ReactNativeFlipper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | *

This source code is licensed under the MIT license found in the LICENSE file in the root 5 | * directory of this source tree. 6 | */ 7 | package com.auth0example; 8 | 9 | import android.content.Context; 10 | import com.facebook.react.ReactInstanceManager; 11 | 12 | /** 13 | * Class responsible of loading Flipper inside your React Native application. This is the release 14 | * flavor of it so it's empty as we don't want to load Flipper. 15 | */ 16 | public class ReactNativeFlipper { 17 | public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { 18 | // Do nothing as we don't want to initialize Flipper on Release. 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /example/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 = "35.0.0" 6 | minSdkVersion = 24 7 | compileSdkVersion = 35 8 | targetSdkVersion = 34 9 | ndkVersion = "27.1.12297006" 10 | kotlinVersion = "2.0.21" 11 | } 12 | repositories { 13 | google() 14 | mavenCentral() 15 | } 16 | dependencies { 17 | classpath("com.android.tools.build:gradle:7.3.1") 18 | classpath("com.facebook.react:react-native-gradle-plugin") 19 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx512m -XX:MaxMetaspaceSize=256m 13 | org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | # AndroidX package structure to make it clearer which packages are bundled with the 21 | # Android operating system, and which are packaged with your app's APK 22 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 23 | android.useAndroidX=true 24 | # Automatically convert third-party libraries to use AndroidX 25 | android.enableJetifier=true 26 | 27 | # Version of flipper SDK to use with React Native 28 | FLIPPER_VERSION=0.125.0 29 | 30 | # Use this property to specify which architecture you want to build. 31 | # You can also override it from the CLI using 32 | # ./gradlew -PreactNativeArchitectures=x86_64 33 | reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64 34 | 35 | # Use this property to enable support to the new architecture. 36 | # This will allow you to use TurboModules and the Fabric render in 37 | # your application. You should enable this flag either if you want 38 | # to write custom TurboModules/Fabric components OR use libraries that 39 | # are providing them. 40 | newArchEnabled=true 41 | 42 | # Use this property to enable or disable the Hermes JS engine. 43 | # If set to false, you will be using JSC instead. 44 | hermesEnabled=true 45 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/auth0/react-native-auth0/96db5d5d9bb2d0dd1a9fdfd38478c86aef48fcd4/example/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /example/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 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /example/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 | set APP_BASE_NAME=%~n0 32 | set APP_HOME=%DIRNAME% 33 | 34 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 35 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 36 | 37 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 38 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 39 | 40 | @rem Find java.exe 41 | if defined JAVA_HOME goto findJavaFromJavaHome 42 | 43 | set JAVA_EXE=java.exe 44 | %JAVA_EXE% -version >NUL 2>&1 45 | if "%ERRORLEVEL%" == "0" goto execute 46 | 47 | echo. 48 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 49 | echo. 50 | echo Please set the JAVA_HOME variable in your environment to match the 51 | echo location of your Java installation. 52 | 53 | goto fail 54 | 55 | :findJavaFromJavaHome 56 | set JAVA_HOME=%JAVA_HOME:"=% 57 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 58 | 59 | if exist "%JAVA_EXE%" goto execute 60 | 61 | echo. 62 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 63 | echo. 64 | echo Please set the JAVA_HOME variable in your environment to match the 65 | echo location of your Java installation. 66 | 67 | goto fail 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | 75 | @rem Execute Gradle 76 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 77 | 78 | :end 79 | @rem End local scope for the variables with windows NT shell 80 | if "%ERRORLEVEL%"=="0" goto mainEnd 81 | 82 | :fail 83 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 84 | rem the _cmd.exe /c_ return code! 85 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 86 | exit /b 1 87 | 88 | :mainEnd 89 | if "%OS%"=="Windows_NT" endlocal 90 | 91 | :omega 92 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { includeBuild("../node_modules/@react-native/gradle-plugin") } 2 | plugins { id("com.facebook.react.settings") } 3 | extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() } 4 | rootProject.name = 'Auth0Example' 5 | include ':app' 6 | includeBuild('../node_modules/@react-native/gradle-plugin') 7 | -------------------------------------------------------------------------------- /example/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Auth0Example", 3 | "displayName": "Auth0Example" 4 | } 5 | -------------------------------------------------------------------------------- /example/babel.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const { getConfig } = require('react-native-builder-bob/babel-config'); 3 | const pkg = require('../package.json'); 4 | 5 | const root = path.resolve(__dirname, '..'); 6 | 7 | module.exports = getConfig( 8 | { 9 | presets: ['module:@react-native/babel-preset'], 10 | }, 11 | { root, pkg } 12 | ); 13 | -------------------------------------------------------------------------------- /example/index.js: -------------------------------------------------------------------------------- 1 | import { AppRegistry } from 'react-native'; 2 | import App from './src/App'; 3 | import { name as appName } from './app.json'; 4 | 5 | AppRegistry.registerComponent(appName, () => App); 6 | -------------------------------------------------------------------------------- /example/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 | -------------------------------------------------------------------------------- /example/ios/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import React 3 | import React_RCTAppDelegate 4 | import ReactAppDependencyProvider 5 | 6 | @main 7 | class AppDelegate: RCTAppDelegate { 8 | override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { 9 | self.moduleName = "Auth0Example" 10 | self.dependencyProvider = RCTAppDependencyProvider() 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 | override func sourceURL(for bridge: RCTBridge) -> URL? { 20 | self.bundleURL() 21 | } 22 | 23 | override func bundleURL() -> URL? { 24 | #if DEBUG 25 | RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index") 26 | #else 27 | Bundle.main.url(forResource: "main", withExtension: "jsbundle") 28 | #endif 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /example/ios/Auth0Example-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 | -------------------------------------------------------------------------------- /example/ios/Auth0Example.xcodeproj/xcshareddata/xcschemes/Auth0Example.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 | -------------------------------------------------------------------------------- /example/ios/Auth0Example.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/Auth0Example.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Auth0Example/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import React 3 | import React_RCTAppDelegate 4 | import ReactAppDependencyProvider 5 | 6 | @main 7 | class AppDelegate: RCTAppDelegate { 8 | override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { 9 | self.moduleName = "Auth0Example" 10 | self.dependencyProvider = RCTAppDependencyProvider() 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 | override func sourceURL(for bridge: RCTBridge) -> URL? { 20 | self.bundleURL() 21 | } 22 | 23 | override func bundleURL() -> URL? { 24 | #if DEBUG 25 | RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index") 26 | #else 27 | Bundle.main.url(forResource: "main", withExtension: "jsbundle") 28 | #endif 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /example/ios/Auth0Example/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "idiom": "iphone", 5 | "scale": "2x", 6 | "size": "20x20" 7 | }, 8 | { 9 | "idiom": "iphone", 10 | "scale": "3x", 11 | "size": "20x20" 12 | }, 13 | { 14 | "idiom": "iphone", 15 | "scale": "2x", 16 | "size": "29x29" 17 | }, 18 | { 19 | "idiom": "iphone", 20 | "scale": "3x", 21 | "size": "29x29" 22 | }, 23 | { 24 | "idiom": "iphone", 25 | "scale": "2x", 26 | "size": "40x40" 27 | }, 28 | { 29 | "idiom": "iphone", 30 | "scale": "3x", 31 | "size": "40x40" 32 | }, 33 | { 34 | "idiom": "iphone", 35 | "scale": "2x", 36 | "size": "60x60" 37 | }, 38 | { 39 | "idiom": "iphone", 40 | "scale": "3x", 41 | "size": "60x60" 42 | }, 43 | { 44 | "idiom": "ios-marketing", 45 | "scale": "1x", 46 | "size": "1024x1024" 47 | } 48 | ], 49 | "info": { 50 | "author": "xcode", 51 | "version": 1 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /example/ios/Auth0Example/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info": { 3 | "version": 1, 4 | "author": "xcode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /example/ios/Auth0Example/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSFaceIDUsageDescription 6 | Authenticate to retrieve Credentials 7 | CFBundleDevelopmentRegion 8 | en 9 | CFBundleDisplayName 10 | Auth0Example 11 | CFBundleExecutable 12 | $(EXECUTABLE_NAME) 13 | CFBundleIdentifier 14 | $(PRODUCT_BUNDLE_IDENTIFIER) 15 | CFBundleURLTypes 16 | 17 | 18 | CFBundleTypeRole 19 | None 20 | CFBundleURLName 21 | auth0 22 | CFBundleURLSchemes 23 | 24 | $(PRODUCT_BUNDLE_IDENTIFIER).auth0 25 | 26 | 27 | 28 | CFBundleInfoDictionaryVersion 29 | 6.0 30 | CFBundleName 31 | $(PRODUCT_NAME) 32 | CFBundlePackageType 33 | APPL 34 | CFBundleShortVersionString 35 | $(MARKETING_VERSION) 36 | CFBundleSignature 37 | ???? 38 | CFBundleVersion 39 | $(CURRENT_PROJECT_VERSION) 40 | LSRequiresIPhoneOS 41 | 42 | NSAppTransportSecurity 43 | 44 | NSExceptionDomains 45 | 46 | localhost 47 | 48 | NSExceptionAllowsInsecureHTTPLoads 49 | 50 | 51 | 52 | 53 | NSLocationWhenInUseUsageDescription 54 | 55 | UILaunchStoryboardName 56 | LaunchScreen 57 | UIRequiredDeviceCapabilities 58 | 59 | armv7 60 | 61 | UISupportedInterfaceOrientations 62 | 63 | UIInterfaceOrientationPortrait 64 | UIInterfaceOrientationLandscapeLeft 65 | UIInterfaceOrientationLandscapeRight 66 | 67 | UIViewControllerBasedStatusBarAppearance 68 | 69 | 70 | -------------------------------------------------------------------------------- /example/ios/Auth0Example/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 24 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /example/ios/Auth0Example/PrivacyInfo.xcprivacy: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSPrivacyAccessedAPITypes 6 | 7 | 8 | NSPrivacyAccessedAPIType 9 | NSPrivacyAccessedAPICategoryFileTimestamp 10 | NSPrivacyAccessedAPITypeReasons 11 | 12 | C617.1 13 | 14 | 15 | 16 | NSPrivacyAccessedAPIType 17 | NSPrivacyAccessedAPICategoryUserDefaults 18 | NSPrivacyAccessedAPITypeReasons 19 | 20 | CA92.1 21 | 22 | 23 | 24 | NSPrivacyAccessedAPIType 25 | NSPrivacyAccessedAPICategorySystemBootTime 26 | NSPrivacyAccessedAPITypeReasons 27 | 28 | 35F9.1 29 | 30 | 31 | 32 | NSPrivacyCollectedDataTypes 33 | 34 | NSPrivacyTracking 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /example/ios/Auth0Example/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | @autoreleasepool { 8 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 9 | } 10 | } -------------------------------------------------------------------------------- /example/ios/Auth0ExampleTests/Auth0ExampleTests.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | #import 5 | #import 6 | 7 | #define TIMEOUT_SECONDS 600 8 | #define TEXT_TO_LOOK_FOR @"Welcome to React" 9 | 10 | @interface Auth0ExampleTests : XCTestCase 11 | 12 | @end 13 | 14 | @implementation Auth0ExampleTests 15 | 16 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL (^)(UIView *view))test 17 | { 18 | if (test(view)) { 19 | return YES; 20 | } 21 | for (UIView *subview in [view subviews]) { 22 | if ([self findSubviewInView:subview matching:test]) { 23 | return YES; 24 | } 25 | } 26 | return NO; 27 | } 28 | 29 | - (void)testRendersWelcomeScreen 30 | { 31 | UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController]; 32 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; 33 | BOOL foundElement = NO; 34 | 35 | __block NSString *redboxError = nil; 36 | #ifdef DEBUG 37 | RCTSetLogFunction( 38 | ^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) { 39 | if (level >= RCTLogLevelError) { 40 | redboxError = message; 41 | } 42 | }); 43 | #endif 44 | 45 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { 46 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 47 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 48 | 49 | foundElement = [self findSubviewInView:vc.view 50 | matching:^BOOL(UIView *view) { 51 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { 52 | return YES; 53 | } 54 | return NO; 55 | }]; 56 | } 57 | 58 | #ifdef DEBUG 59 | RCTSetLogFunction(RCTDefaultLogFunction); 60 | #endif 61 | 62 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); 63 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); 64 | } 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /example/ios/Auth0ExampleTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /example/ios/File.swift: -------------------------------------------------------------------------------- 1 | // 2 | // File.swift 3 | // Auth0Example 4 | // 5 | 6 | import Foundation 7 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | def find_and_replace_boost_url 2 | pod_spec = "../node_modules/react-native/third-party-podspecs/boost.podspec" 3 | puts "Debug: Starting boost URL replacement" 4 | if File.exist?(pod_spec) 5 | puts "Debug: Found boost.podspec" 6 | spec_content = File.read(pod_spec) 7 | spec_content.gsub!( 8 | 'https://boostorg.jfrog.io/artifactory/main/release/1.76.0/source/boost_1_76_0.tar.bz2', 9 | 'https://archives.boost.io/release/1.76.0/source/boost_1_76_0.tar.bz2' 10 | ) 11 | File.write(pod_spec, spec_content) 12 | puts "Debug: Updated boost.podspec" 13 | end 14 | end 15 | 16 | # Let the magic happen! 17 | find_and_replace_boost_url 18 | 19 | require_relative '../node_modules/react-native/scripts/react_native_pods' 20 | require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' 21 | 22 | platform :ios, '16.0' 23 | prepare_react_native_project! 24 | 25 | linkage = ENV['USE_FRAMEWORKS'] 26 | if linkage != nil 27 | Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green 28 | use_frameworks! :linkage => linkage.to_sym 29 | end 30 | 31 | target 'Auth0Example' do 32 | config = use_native_modules! 33 | 34 | # Flags change depending on the env values. 35 | flags = get_default_flags() 36 | 37 | use_react_native!( 38 | :path => config[:reactNativePath], 39 | # Hermes is now enabled by default. Disable by setting this flag to false. 40 | # Upcoming versions of React Native may rely on get_default_flags(), but 41 | # we make it explicit here to aid in the React Native upgrade process. 42 | :hermes_enabled => flags[:hermes_enabled], 43 | :fabric_enabled => flags[:fabric_enabled], 44 | # An absolute path to your application root. 45 | :app_path => "#{Pod::Config.instance.installation_root}/.." 46 | ) 47 | 48 | post_install do |installer| 49 | react_native_post_install( 50 | installer, 51 | # Set `mac_catalyst_enabled` to `true` in order to apply patches 52 | # necessary for Mac Catalyst builds 53 | :mac_catalyst_enabled => false 54 | ) 55 | 56 | installer.pods_project.targets.each do |target| 57 | target.build_configurations.each do |config| 58 | config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= ['$(inherited)', '_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION'] 59 | end 60 | end 61 | end 62 | end 63 | -------------------------------------------------------------------------------- /example/metro.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const { getDefaultConfig } = require('@react-native/metro-config'); 3 | const { getConfig } = require('react-native-builder-bob/metro-config'); 4 | const pkg = require('../package.json'); 5 | 6 | const root = path.resolve(__dirname, '..'); 7 | 8 | /** 9 | * Metro configuration 10 | * https://facebook.github.io/metro/docs/configuration 11 | * 12 | * @type {import('metro-config').MetroConfig} 13 | */ 14 | module.exports = getConfig(getDefaultConfig(__dirname), { 15 | root, 16 | pkg, 17 | project: __dirname, 18 | }); 19 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Auth0Example", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "android": "react-native run-android", 7 | "ios": "react-native run-ios", 8 | "start": "react-native start", 9 | "pods": "pod-install --quiet", 10 | "postinstall": "npm run pods" 11 | }, 12 | "dependencies": { 13 | "@react-navigation/native": "^7.1.8", 14 | "@react-navigation/native-stack": "7.3.10", 15 | "react": "18.3.1", 16 | "react-native": "0.77.0", 17 | "react-native-paper": "^3.9.0", 18 | "react-native-safe-area-context": "^5.4.0", 19 | "react-native-screens": "4.9.2" 20 | }, 21 | "devDependencies": { 22 | "@babel/core": "^7.26.10", 23 | "@babel/preset-env": "^7.26.9", 24 | "@babel/runtime": "^7.27.0", 25 | "@react-native-community/cli": "15.0.1", 26 | "@react-native-community/cli-platform-android": "15.0.1", 27 | "@react-native-community/cli-platform-ios": "15.0.1", 28 | "@react-native/babel-preset": "0.77.1", 29 | "@react-native/metro-config": "0.77.1" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /example/react-native.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const pak = require('../package.json'); 3 | 4 | module.exports = { 5 | dependencies: { 6 | [pak.name]: { 7 | root: path.join(__dirname, '..'), 8 | }, 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /example/src/App.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Sample React Native App 3 | * https://github.com/facebook/react-native 4 | * 5 | * @format 6 | * @flow strict-local 7 | */ 8 | 9 | import React from 'react'; 10 | import { Alert, Button, StyleSheet, Text, View } from 'react-native'; 11 | import { 12 | useAuth0, 13 | Auth0Provider, 14 | LocalAuthenticationOptions, 15 | LocalAuthenticationLevel, 16 | LocalAuthenticationStrategy, 17 | } from 'react-native-auth0'; 18 | import config from './auth0-configuration'; 19 | import { NavigationProp, NavigationContainer } from '@react-navigation/native'; 20 | import { createNativeStackNavigator } from '@react-navigation/native-stack'; 21 | 22 | const Stack = createNativeStackNavigator(); 23 | 24 | const Home = ({ navigation }: { navigation: NavigationProp }) => { 25 | const { authorize, clearSession, user, getCredentials, error } = useAuth0(); 26 | 27 | const onLogin = async () => { 28 | await authorize(); 29 | const credentials = await getCredentials(undefined, 0, {}); 30 | Alert.alert('AccessToken: ' + credentials?.accessToken); 31 | }; 32 | 33 | const loggedIn = user !== undefined && user !== null; 34 | 35 | const onLogout = async () => { 36 | await clearSession(); 37 | }; 38 | 39 | return ( 40 | 41 | Auth0Sample - Login 42 | {user && You are logged in as {user.name}} 43 | {!user && You are not logged in} 44 |