Skip to content

Commit ee3ae8e

Browse files
Merge pull request #78 from frontegg/feature/open-admin-portal-bump-versions
2 parents 9554807 + 6b21ae5 commit ee3ae8e

14 files changed

Lines changed: 169 additions & 8 deletions

File tree

FronteggRN.podspec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ Pod::Spec.new do |s|
2020
# See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79.
2121
if respond_to?(:install_modules_dependencies, true)
2222
install_modules_dependencies(s)
23-
s.dependency "FronteggSwift", "1.2.76"
23+
s.dependency "FronteggSwift", "1.3.10"
2424
else
2525
s.dependency "React-Core"
26-
s.dependency "FronteggSwift", "1.2.76"
26+
s.dependency "FronteggSwift", "1.3.10"
2727

2828
# Don't install the dependencies when we run `pod install` in the old architecture.
2929
if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then

android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ dependencies {
8080
implementation "androidx.browser:browser:1.8.0"
8181
implementation 'io.reactivex.rxjava3:rxkotlin:3.0.1'
8282
implementation 'com.google.code.gson:gson:2.10.1'
83-
implementation 'com.frontegg.sdk:android:1.3.18'
83+
implementation 'com.frontegg.sdk:android:1.3.34'
8484
}
8585

8686
if (isNewArchitectureEnabled()) {

android/src/main/java/com/frontegg/reactnative/FronteggRNModule.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import com.facebook.react.bridge.ReactMethod
1010
import com.facebook.react.bridge.WritableMap
1111
import com.facebook.react.common.LifecycleState
1212
import com.facebook.react.modules.core.DeviceEventManagerModule
13+
import com.frontegg.android.AdminPortalActivity
1314
import com.frontegg.android.fronteggAuth
1415
import io.reactivex.rxjava3.core.Observable
1516
import io.reactivex.rxjava3.disposables.Disposable
@@ -189,6 +190,18 @@ class FronteggRNModule(val reactContext: ReactApplicationContext) :
189190
}
190191
}
191192

193+
@ReactMethod
194+
fun openAdminPortal(promise: Promise) {
195+
val activity = currentActivity
196+
if (activity == null) {
197+
promise.reject("NO_ACTIVITY", "Cannot open Admin Portal without an active Activity")
198+
return
199+
}
200+
201+
AdminPortalActivity.open(activity)
202+
promise.resolve(null)
203+
}
204+
192205
override fun getConstants(): MutableMap<String, Any?> = fronteggConstants.toMap()
193206

194207
companion object {

docs/README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,28 @@ For full documentation, visit the Frontegg Developer Portal:
3434

3535
---
3636

37+
## 🔐 Native SDK versions
38+
39+
The React Native wrapper depends on the underlying native SDKs:
40+
41+
- On **Android**, the plugin and example app use `com.frontegg.sdk:android:1.3.34`.
42+
- On **iOS**, the plugin depends on `FronteggSwift` **1.3.10** via CocoaPods.
43+
44+
After upgrading, run `pod install` in your iOS project and rebuild both platforms.
45+
46+
---
47+
48+
## 🔐 Native SDK versions
49+
50+
The React Native wrapper depends on the underlying native SDKs:
51+
52+
- On **Android**, the plugin and example app use `com.frontegg.sdk:android:1.3.34`.
53+
- On **iOS**, the plugin depends on `FronteggSwift` **1.3.10** via CocoaPods.
54+
55+
After upgrading, run `pod install` in your iOS project and rebuild both platforms.
56+
57+
---
58+
3759
## 🧑‍💻 Getting Started with Frontegg
3860

3961
Don't have a Frontegg account yet?

docs/_sidebar.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
- [Setup Guide](setup.md)
44
- [Usage Examples](usage.md)
55
- [Advanced Topics](advanced.md)
6+
- [API Reference](api.md)

docs/advanced.md

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ Passkeys provide a seamless, passwordless login experience using WebAuthn and pl
5353

5454
1. **iOS Version**: Ensure your project targets iOS 15 or later to support the necessary WebAuthn APIs.
5555
2. **Android**: Use Android SDK 26+.
56-
3. **Frontegg SDK Version**: Use Frontegg iOS SDK version 1.2.24 or later.
56+
3. **Frontegg SDK Version**: Use Frontegg iOS SDK version 1.3.10 or later.
5757

5858
#### Android setup
5959

@@ -63,7 +63,7 @@ Passkeys provide a seamless, passwordless login experience using WebAuthn and pl
6363
```groovy
6464
dependencies {
6565
implementation 'androidx.browser:browser:1.8.0'
66-
implementation 'com.frontegg.sdk:android:1.2.30'
66+
implementation 'com.frontegg.sdk:android:1.3.34'
6767
}
6868
```
6969

@@ -131,4 +131,35 @@ async function handleLoginWithPasskeys() {
131131
console.error('Error logging in with Passkeys:', error);
132132
}
133133
}
134-
```
134+
```
135+
136+
## Admin Portal (Beta)
137+
138+
The Admin Portal is a hosted page that lets end users manage their account, profile, sessions, and tenant settings. The React Native SDK exposes `openAdminPortal()` which delegates to the native SDKs:
139+
140+
- **Android** — launches `AdminPortalActivity` (full-screen `WebView`)
141+
- **iOS** — presents `AdminPortalView` as a page sheet (`WKWebView`)
142+
143+
The portal loads `${baseUrl}/oauth/portal?appId=<applicationId>` and shares the SDK session, so authenticated users are not asked to sign in again.
144+
145+
> **Beta.** The API may change in future minor releases. Pin to an exact SDK version when embedding this in a shipping app.
146+
147+
### Multi-app prerequisite
148+
149+
For multi-app workspaces, configure `applicationId` in your native setup (see [Multi-app support](#multi-app-support)). Without `?appId=` the portal renders **"Application not found"** after sign-in.
150+
151+
### Open the portal
152+
153+
```tsx
154+
import { openAdminPortal } from '@frontegg/react-native';
155+
156+
async function handleOpenAdminPortal() {
157+
try {
158+
await openAdminPortal();
159+
} catch (error) {
160+
console.error('Failed to open Admin Portal:', error);
161+
}
162+
}
163+
```
164+
165+
The portal is dismissed when the user swipes down (iOS) or taps the built-in close button. On Android, `window.close()` finishes the activity automatically.

example/android/app/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ android {
125125
dependencies {
126126
// The version of react-native is set by the React Native Gradle Plugin
127127
implementation("com.facebook.react:react-android")
128-
implementation 'com.frontegg.sdk:android:1.3.18'
128+
implementation 'com.frontegg.sdk:android:1.3.34'
129129
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}")
130130
debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
131131
exclude group:'com.squareup.okhttp3', module:'okhttp'

example/src/HomeScreen.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
registerPasskeys,
1313
loginWithPasskeys,
1414
requestAuthorize,
15+
openAdminPortal,
1516
} from '@frontegg/react-native';
1617
import { useState } from 'react';
1718
import type { ITenantsResponse } from '@frontegg/rest-api';
@@ -79,6 +80,23 @@ export default function HomeScreen() {
7980
/>
8081
</View>
8182

83+
{state.isAuthenticated ? (
84+
<View style={styles.listenerButton}>
85+
<FronteggButton
86+
variant="primary"
87+
title="Open Admin Portal"
88+
accessibilityLabel="OpenAdminPortalButton"
89+
onPress={async () => {
90+
try {
91+
await openAdminPortal();
92+
} catch (error) {
93+
console.error('Failed to open Admin Portal:', error);
94+
}
95+
}}
96+
/>
97+
</View>
98+
) : null}
99+
82100
{state.isAuthenticated ? (
83101
<View style={styles.listenerButton}>
84102
<FronteggButton

example/src/components/FronteggButton.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export type FronteggButtonProps = {
1111
variant?: ButtonVariant;
1212
style?: StyleProp<ViewStyle>;
1313
textStyle?: StyleProp<TextStyle>;
14+
accessibilityLabel?: string;
1415
};
1516

1617
const COLORS = {
@@ -29,6 +30,7 @@ export default function FronteggButton({
2930
variant = 'primary',
3031
style,
3132
textStyle,
33+
accessibilityLabel,
3234
}: FronteggButtonProps) {
3335
const isOutline = variant === 'outline';
3436
const isDanger = variant === 'danger';
@@ -56,6 +58,7 @@ export default function FronteggButton({
5658
return (
5759
<Pressable
5860
accessibilityRole="button"
61+
accessibilityLabel={accessibilityLabel}
5962
disabled={disabled}
6063
onPress={onPress}
6164
style={({ pressed }) => [

ios/FronteggRN.m

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,8 @@ @interface RCT_EXTERN_MODULE(FronteggRN, RCTEventEmitter)
4444
resolver: (RCTPromiseResolveBlock)resolve
4545
rejecter: (RCTPromiseRejectBlock)reject
4646
)
47+
RCT_EXTERN_METHOD(
48+
openAdminPortal: (RCTPromiseResolveBlock)resolve
49+
rejecter: (RCTPromiseRejectBlock)reject
50+
)
4751
@end

0 commit comments

Comments
 (0)