Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions FronteggRN.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,16 @@ Pod::Spec.new do |s|
s.source = { :git => "https://github.com/frontegg/frontegg-react-native.git", :tag => "#{s.version}" }

s.source_files = "ios/**/*.{h,m,mm,swift}"
s.exclude_files = "ios/Package.swift"

# Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0.
# See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79.
# FronteggSwift via SPM — linked in post_integrate by ios/frontegg_spm.rb (see docs/setup.md).

if respond_to?(:install_modules_dependencies, true)
install_modules_dependencies(s)
s.dependency "FronteggSwift", "1.3.10"
else
s.dependency "React-Core"
s.dependency "FronteggSwift", "1.3.10"

# Don't install the dependencies when we run `pod install` in the old architecture.
if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then
Expand Down
27 changes: 27 additions & 0 deletions android/src/main/java/com/frontegg/reactnative/FronteggRNModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import com.frontegg.android.AdminPortalActivity
import com.frontegg.android.fronteggAuth
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.disposables.Disposable
import kotlin.time.DurationUnit
import kotlin.time.toDuration


class FronteggRNModule(val reactContext: ReactApplicationContext) :
Expand Down Expand Up @@ -158,6 +160,31 @@ class FronteggRNModule(val reactContext: ReactApplicationContext) :
}
}

@ReactMethod
fun isSteppedUp(maxAgeSeconds: Double, promise: Promise) {
val maxAge =
if (maxAgeSeconds < 0) null else maxAgeSeconds.toDuration(DurationUnit.SECONDS)
promise.resolve(auth.isSteppedUp(maxAge))
}

@ReactMethod
fun stepUp(maxAgeSeconds: Double, promise: Promise) {
val activity = currentActivity
if (activity == null) {
promise.reject("NO_ACTIVITY", "Current activity is null")
return
}
val maxAge =
if (maxAgeSeconds < 0) null else maxAgeSeconds.toDuration(DurationUnit.SECONDS)
auth.stepUp(activity, maxAge) { error ->
if (error != null) {
promise.reject("STEP_UP_ERROR", error.message, error)
} else {
promise.resolve(null)
}
}
}

@ReactMethod
fun requestAuthorize(refreshToken: String, deviceTokenCookie: String?, promise: Promise) {
try {
Expand Down
79 changes: 79 additions & 0 deletions docs/setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,85 @@ This section guides you through configuring the Frontegg React Native SDK for bo

## Setup iOS Project

### Integrate FronteggSwift via Swift Package Manager

The iOS native SDK (`FronteggSwift`) is delivered through **Swift Package Manager (SPM)** only. The CocoaPods pod `FronteggSwift` is **not** used (previously pinned at `1.2.76`). React Native still uses CocoaPods for `FronteggRN` and other dependencies; `FronteggSwift` is linked into the `FronteggRN` pod target via SPM after `pod install`.

**Requirements:** Xcode **15+**, iOS deployment target **14.0+**, CocoaPods.

#### 1. Update `ios/Podfile`

Inside your app target (the same block as `use_native_modules!`):

```ruby
target 'YourApp' do
# Required so the FronteggRN pod can import the FronteggSwift SPM product.
use_frameworks! :linkage => :static

config = use_native_modules!
# ... use_react_native! etc.
```

After `post_install` (do **not** put the SPM hook inside `post_install` — CocoaPods would overwrite the patched `Pods` project):

```ruby
post_install do |installer|
react_native_post_install(installer, config[:reactNativePath], :mac_catalyst_enabled => false)
# ...your other post_install hooks...
end

post_integrate do |installer|
require_relative '../node_modules/@frontegg/react-native/ios/frontegg_spm'
FronteggSPM.link_frontegg_rn_pod(installer)
end
end
```

Adjust the `require_relative` path if your `node_modules` layout differs (monorepo, etc.).

#### 2. Install pods

From the `ios` directory:

```bash
cd ios
bundle exec pod install # recommended if you use a Gemfile
```

**React Native 0.72:** if `pod install` fails downloading `boost`, add the boost URL workaround at the top of your `Podfile` (see the [example `ios/Podfile`](https://github.com/frontegg/frontegg-react-native/blob/master/example/ios/Podfile)).

#### 3. Build and run

- Open **`YourApp.xcworkspace`** (not `.xcodeproj`).
- For local development on a **simulator**, prefer:

```bash
cd ..
yarn start # Metro — one terminal
yarn ios --simulator "iPhone 17 Pro Max"
```

If a physical iPhone is connected, React Native may target the device and fail on code signing (`com.your.bundle`). Use `--simulator` or disconnect the device.

The `frontegg_spm` helper pins **FronteggSwift 1.3.10** from `https://github.com/frontegg/frontegg-ios-swift.git`, links it to the **FronteggRN** CocoaPods target, and configures the app Xcode project so SPM resolves without duplicate symbol errors at link time.

> **Embedded mode step-up:** `FronteggSwift` **1.3.10** routes `stepUp()` through the embedded `WKWebView` when `embeddedMode` is enabled (instead of `ASWebAuthenticationSession`), so MFA/step-up reuses the existing web session. Set `<key>embeddedMode</key><true/>` in `Frontegg.plist` if you use the embedded login box.

#### Step-up from JavaScript

```ts
import { isSteppedUp, stepUp } from '@frontegg/react-native';

const maxAgeSeconds = 60;
if (await isSteppedUp(maxAgeSeconds)) {
// already stepped up
} else {
await stepUp(maxAgeSeconds);
}
```

See the [example `HomeScreen`](https://github.com/frontegg/frontegg-react-native/blob/master/example/src/HomeScreen.tsx) for a **Sensitive action** button matching the native iOS SDK demo.

### Create Frontegg.plist

1. Add a new file named `Frontegg.plist` to your root project directory.
Expand Down
3 changes: 3 additions & 0 deletions example/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ GEM
cocoapods-plugins (1.0.0)
nap
cocoapods-search (1.0.1)
cocoapods-spm (0.1.20)
xcodeproj (>= 1.23.0)
cocoapods-trunk (1.6.0)
nap (>= 0.8, < 2.0)
netrc (~> 0.11)
Expand Down Expand Up @@ -92,6 +94,7 @@ PLATFORMS

DEPENDENCIES
cocoapods (~> 1.12)
cocoapods-spm (~> 0.1.20)

RUBY VERSION
ruby 2.6.10p210
Expand Down
70 changes: 14 additions & 56 deletions example/README.md
Original file line number Diff line number Diff line change
@@ -1,74 +1,32 @@
This is a new [**React Native**](https://reactnative.dev) project, bootstrapped using [`@react-native-community/cli`](https://github.com/react-native-community/cli).
# Frontegg React Native — example app

# Getting Started
## Prerequisites

>**Note**: Make sure you have completed the [React Native - Environment Setup](https://reactnative.dev/docs/environment-setup) instructions till "Creating a new application" step, before proceeding.
- [React Native environment](https://reactnative.dev/docs/environment-setup) (Node, Xcode 15+, CocoaPods)
- Configure `ios/Frontegg.plist` with your Frontegg `baseUrl` and `clientId` (see [Setup Guide](../docs/setup.md))

## Step 1: Start the Metro Server
## iOS (SPM + CocoaPods)

First, you will need to start **Metro**, the JavaScript _bundler_ that ships _with_ React Native.

To start Metro, run the following command from the _root_ of your React Native project:
From the **example** directory:

```bash
# using npm
npm start

# OR using Yarn
yarn start
yarn install
cd ios && bundle exec pod install && cd ..
yarn start # terminal 1
yarn ios --simulator "iPhone 17 Pro Max" # terminal 2 — use an available simulator name
```

## Step 2: Start your Application
Open `ios/ReactNativeExample.xcworkspace` in Xcode if you build from the IDE.

Let Metro Bundler run in its _own_ terminal. Open a _new_ terminal from the _root_ of your React Native project. Run the following command to start your _Android_ or _iOS_ app:
> Use `--simulator` when a physical iPhone is connected, otherwise `yarn ios` may try to deploy to the device and fail on provisioning.

### For Android
## Android

```bash
# using npm
npm run android

# OR using Yarn
yarn android
```

### For iOS

```bash
# using npm
npm run ios

# OR using Yarn
yarn ios
```

If everything is set up _correctly_, you should see your new app running in your _Android Emulator_ or _iOS Simulator_ shortly provided you have set up your emulator/simulator correctly.

This is one way to run your app — you can also run it directly from within Android Studio and Xcode respectively.

## Step 3: Modifying your App

Now that you have successfully run the app, let's modify it.

1. Open `App.tsx` in your text editor of choice and edit some lines.
2. For **Android**: Press the <kbd>R</kbd> key twice or select **"Reload"** from the **Developer Menu** (<kbd>Ctrl</kbd> + <kbd>M</kbd> (on Window and Linux) or <kbd>Cmd ⌘</kbd> + <kbd>M</kbd> (on macOS)) to see your changes!

For **iOS**: Hit <kbd>Cmd ⌘</kbd> + <kbd>R</kbd> in your iOS Simulator to reload the app and see your changes!

## Congratulations! :tada:

You've successfully run and modified your React Native App. :partying_face:

### Now what?

- If you want to add this new React Native code to an existing application, check out the [Integration guide](https://reactnative.dev/docs/integration-with-existing-apps).
- If you're curious to learn more about React Native, check out the [Introduction to React Native](https://reactnative.dev/docs/getting-started).

# Troubleshooting

If you can't get this to work, see the [Troubleshooting](https://reactnative.dev/docs/troubleshooting) page.

# Learn More
## More

To learn more about React Native, take a look at the following resources:

Expand Down
23 changes: 23 additions & 0 deletions example/ios/Podfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
# boostorg.jfrog.io often returns a bad tarball; use archives.boost.io (RN 0.72 workaround).
boost_podspec_path = File.expand_path('../node_modules/react-native/third-party-podspecs/boost.podspec', __dir__)
if File.exist?(boost_podspec_path)
boost_podspec = File.read(boost_podspec_path)
unless boost_podspec.include?('archives.boost.io')
File.write(
boost_podspec_path,
boost_podspec.gsub(
'https://boostorg.jfrog.io/artifactory/main/release/1.76.0/source/boost_1_76_0.tar.bz2',
'https://archives.boost.io/release/1.76.0/source/boost_1_76_0.tar.bz2'
)
)
end
end

# Resolve react_native_pods.rb with node to allow for hoisting
require Pod::Executable.execute_command('node', ['-p',
'require.resolve(
Expand Down Expand Up @@ -26,6 +41,9 @@ if linkage != nil
end

target 'ReactNativeExample' do
# Required so FronteggRN (Swift) can import the FronteggSwift SPM product.
use_frameworks! :linkage => :static

config = use_native_modules!

# Flags change depending on the env values.
Expand Down Expand Up @@ -59,4 +77,9 @@ target 'ReactNativeExample' do
)
__apply_Xcode_12_5_M1_post_install_workaround(installer)
end

post_integrate do |installer|
require_relative '../../ios/frontegg_spm'
FronteggSPM.link_frontegg_rn_pod(installer)
end
end
64 changes: 27 additions & 37 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,9 @@ PODS:
- React-jsi (= 0.72.1)
- ReactCommon/turbomodule/core (= 0.72.1)
- fmt (6.2.1)
- FronteggRN (1.2.14):
- FronteggSwift (= 1.2.76)
- FronteggRN (1.2.16):
- RCT-Folly (= 2021.07.22.00)
- React-Core
- FronteggSwift (1.2.76):
- Sentry (~> 8.46.0)
- glog (0.3.5)
- hermes-engine (0.72.1):
- hermes-engine/Pre-built (= 0.72.1)
Expand Down Expand Up @@ -436,9 +433,6 @@ PODS:
- RCT-Folly (= 2021.07.22.00)
- React-Core
- React-RCTImage
- Sentry (8.46.0):
- Sentry/Core (= 8.46.0)
- Sentry/Core (8.46.0)
- SocketRocket (0.6.1)
- Yoga (1.14.0)

Expand Down Expand Up @@ -491,9 +485,7 @@ DEPENDENCIES:
SPEC REPOS:
trunk:
- fmt
- FronteggSwift
- libevent
- Sentry
- SocketRocket

EXTERNAL SOURCES:
Expand Down Expand Up @@ -589,8 +581,7 @@ SPEC CHECKSUMS:
FBLazyVector: 55cd4593d570bd9e5e227488d637ce6a9581ce51
FBReactNativeSpec: 799b0e1a1561699cd0e424e24fe5624da38402f0
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
FronteggRN: 38e704aa6bc3999f1251361e3bd17ff3ee4859b9
FronteggSwift: df127087b79c5fc65240805136f36c7c28d4988d
FronteggRN: ce2450115a3c86ad7dbcd5b991fe1ff2bcab04a7
glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b
hermes-engine: 9df83855a0fd15ef8eb61694652bae636b0c466e
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
Expand All @@ -599,39 +590,38 @@ SPEC CHECKSUMS:
RCTTypeSafety: 75fa444becadf0ebfa0a456b8c64560c7c89c7df
React: 3e5b3962f27b7334eaf5517a35b3434503df35ad
React-callinvoker: c3a225610efe0caadac78da53b6fe78e53eb2b03
React-Codegen: fa4e79f8d56b5aa5f91d45984d21c21b31e211c8
React-Core: cbfc97c3c0061d4fdaca617357086ba1347c730e
React-CoreModules: 0d18899272223a2a038e4c2313a7760ca6b280a7
React-cxxreact: f78070b70980e9e19fb448fec9d49a9181952535
React-debug: 8aa2bd54b0f0011049300ce3339b0e51254ef3b5
React-hermes: c783d9dcf275ec48f97b164824dcdfdda480e6a6
React-jsi: cc0d4c585001fca0979591587e00e6d2a4c13820
React-jsiexecutor: a2b883b0e3fbc606a1e6e97a15059b71d6da1715
React-Codegen: 319a74f758104130092a5984431045056c32fbab
React-Core: 40003a89fd94da98b03c3fad8834871299485cfa
React-CoreModules: 1304c0710deb87054623ccc9c552e23a1fcce219
React-cxxreact: f82f0f1832606fabb9e8c9d61c4230704a3d2d2f
React-debug: 3e34ac6fb438f0e8c05a1678eedd6ebd8928245c
React-hermes: f076cb5f7351d6cc1600125bef3259ea880460fb
React-jsi: 9f381c8594161b2328b93cd3ba5d0bcfcd1e093a
React-jsiexecutor: 184eae1ecdedc7a083194bd9ff809c93f08fd34c
React-jsinspector: d0b5bfd1085599265f4212034321e829bdf83cc0
React-logger: 70abe174614ac3f165e02ab8300fec50d2f9572d
react-native-safe-area-context: 8745463257fac6150abd2281b02de640b3595ec7
React-NativeModulesApple: 3f444b421d3c1e463414cb5aee385c4ffe6bae42
React-logger: b8103c9b04e707b50cdd2b1aeb382483900cbb37
react-native-safe-area-context: 9697629f7b2cda43cf52169bb7e0767d330648c2
React-NativeModulesApple: bdfd86e972ea8103941faab9c7f64ea9be7e2be6
React-perflogger: 3d501f34c8d4b10cb75f348e43591765788525ad
React-RCTActionSheet: f5335572c979198c0c3daff67b07bd1ad8370c1d
React-RCTAnimation: 5d0d31a4f9c49a70f93f32e4da098fb49b5ae0b3
React-RCTAppDelegate: d285573b1d55da98149560f38df549293e4eb20d
React-RCTBlob: f7777ca0bad9e6d98efe921003f9f3cca70730f1
React-RCTImage: e15d22db53406401cdd1407ce51080a66a9c7ed4
React-RCTLinking: 39815800ec79d6fb15e6329244d195ebeabf7541
React-RCTNetwork: 2a6548e13d2577b112d4250ac5be74ae62e1e86b
React-RCTSettings: a76aee44d5398144646be146c334b15c90ad9582
React-RCTAnimation: 897b1170a1e934dee9b7eb7d5582920dea72c1c8
React-RCTAppDelegate: f8dc4f198bb7a7fdc9ccd5a6e246936bbdacbe42
React-RCTBlob: b69213136de8eed26fdf112602e8aaf91923093c
React-RCTImage: 9f2303a18cec1f715a447dca5b82021643661e6b
React-RCTLinking: f88453408f33a99f36bb4f6e11278ffbb81aa45f
React-RCTNetwork: 5ef8d399ad389442404683d2572007ace0e26076
React-RCTSettings: 516d917b059c94f33f85f601974429de7c3d34ca
React-RCTText: afad390f3838f210c2bc9e1a19bb048003b2a771
React-RCTVibration: 29bbaa5c57c02dc036d7e557584b492000b1d3e7
React-RCTVibration: 28cc9ac2c062b515f207a1743f0f27083d62acc5
React-rncore: 50966ce412d63bee9ffe5c98249857c23870a3c4
React-runtimeexecutor: d129f2b53d61298093d7c7d8ebfafa664f911ce6
React-runtimescheduler: c8f959651fd874b93feeb32781b1e402a6801ec2
React-utils: c9e15d684b491d6324b4139790306836f0e8b1d6
ReactCommon: f7d2978a6f8e8552a4908f067e65d4cfda686138
RNScreens: 67dd26e0c1e6df63f4ccaaf281c1ecdd88c995c3
Sentry: da60d980b197a46db0b35ea12cb8f39af48d8854
React-runtimescheduler: 34e27d6db52587cf93e7d9d44d5ff2dc4948243a
React-utils: 4324c58d17bcbcb8c49fe7f8c14b4f61d5dd4a42
ReactCommon: e33f60179aae29423fcf4ea19fdedc038813ea3f
RNScreens: 835807a1f3c74c8ea0d0b9e089bf14333141f17f
SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17
Yoga: 65286bb6a07edce5e4fe8c90774da977ae8fc009

PODFILE CHECKSUM: 010992354d93ba29cfe4cff5fab47f9b2920a2da
PODFILE CHECKSUM: fc09f9972b0d9b6a48315e1f02b457d29013ffd5

COCOAPODS: 1.16.2
COCOAPODS: 1.14.3
Loading
Loading