@dblackdev/bvndle-sso-react-native
v1.2.0
Published
A reusable React Native component for Bvndle SSO authentication.
Maintainers
Readme
@dblackdev/bvndle-sso-react-native
A high-security, production-ready React Native SDK for Bvndle Single Sign-On (SSO) authentication.
Features
- 🍏 Apple App Store Compliant by Default: Uses native
ASWebAuthenticationSession/SFSafariViewControlleron iOS and Chrome Custom Tabs on Android with visible address bars and SSL certificates (satisfying Apple Guideline 4.0). - 🔄 Automatic Token Exchange: Intercepts OAuth authorization codes and exchanges them internally for an
ssoAccessTokenbefore returning to your app. - 🛡️ VAPT & Security Hardened: Built-in OAuth CSRF
stateparameter validation, strict origin whitelisting, dangerous scheme interception (javascript:,data:), and HTTPS enforcement. - 🌐 Flexible Presentation Modes: Native system browser sheet by default (
authMode="browser"), with an embedded WebView modal mode (authMode="webview") when required. - ⚡ Programmatic & Component APIs: Use the declarative
<BvndleAuthModal />component or the one-linesignInWithBvndle()async function. - 🔗 Server-Driven Redirects: Automatically captures dashboard-configured redirects via deep link listeners (
Linking), makingredirectUrloptional in client configs.
Installation
npm install @dblackdev/bvndle-sso-react-native
# or
yarn add @dblackdev/bvndle-sso-react-nativePeer Dependencies
Install the peer dependencies based on the authentication mode you plan to use:
# Recommended for Apple App Store Review Guideline 4.0 compliance (Default "browser" mode)
npm install react-native-inappbrowser-reborn
# or
yarn add react-native-inappbrowser-reborn
# Required if using the embedded WebView modal ("webview" mode)
npm install react-native-webview
# or
yarn add react-native-webviewNative In-App Browser Setup (react-native-inappbrowser-reborn)
The package uses react-native-inappbrowser-reborn to provide a secure, native browser authentication experience (ASWebAuthenticationSession / SFSafariViewController on iOS and Chrome Custom Tabs on Android).
iOS Installation: After installing the package, link the native pods:
cd ios && pod install && cd .. # or npx pod-installiOS Deep Link Configuration (
Info.plist): If you use custom URL schemes for your callback (e.g.com.yourapp://auth), ensure your scheme is registered underCFBundleURLTypesinios/<YourApp>/Info.plist:<key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleTypeRole</key> <string>Editor</string> <key>CFBundleURLName</key> <string>com.yourapp</string> <key>CFBundleURLSchemes</key> <array> <string>com.yourapp</string> </array> </dict> </array>Android Deep Link Configuration (
AndroidManifest.xml): For custom scheme callbacks, add an<intent-filter>inside yourMainActivityinandroid/app/src/main/AndroidManifest.xml:<intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="com.yourapp" /> </intent-filter>
[!NOTE] Graceful Fallback: If
react-native-inappbrowser-rebornis not installed or unavailable in the host project, the SDK automatically falls back to the embeddedreact-native-webviewmodal without throwing native errors.
Documentation
- Official Bvndle SSO Guide: Bvndle SSO Get Started for Mobile
- Architecture & Developer Guide: See ARCHITECTURE.md for sequence diagrams, security invariants, and directory structure.
Quick Start
1. Declarative Modal Component (BvndleAuthModal)
import React, { useState } from "react";
import { Button, StyleSheet, View, Text } from "react-native";
import { BvndleAuthModal } from "@dblackdev/bvndle-sso-react-native";
export const LoginScreen = () => {
const [isVisible, setIsVisible] = useState(false);
const [accessToken, setAccessToken] = useState<string | null>(null);
return (
<View style={styles.container}>
<Button title="Sign in with Bvndle" onPress={() => setIsVisible(true)} />
{accessToken ? <Text>Logged in! Token: {accessToken}</Text> : null}
<BvndleAuthModal
visible={isVisible}
authMode="browser" // Default: Native Safari / Custom Tabs (Apple compliant)
onClose={() => setIsVisible(false)}
onSuccess={(ssoAccessToken) => {
console.log("SSO Access Token:", ssoAccessToken);
setAccessToken(ssoAccessToken);
setIsVisible(false);
}}
onError={(errorMessage) => {
console.error("Authentication Error:", errorMessage);
setIsVisible(false);
}}
config={{
url: "YOUR_SSO_URL",
clientId: "YOUR_CLIENT_ID",
ssoTokenUrl: "YOUR_SSO_TOKEN_URL",
redirectUrl: "com.yourapp://auth", // Optional if configured on Bvndle dashboard
loadingMessage: "Completing sign in...",
debug: false,
}}
/>
</View>
);
};
const styles = StyleSheet.create({
container: { flex: 1, justifyContent: "center", alignItems: "center" },
});2. Programmatic Sign-In Function (signInWithBvndle)
If you prefer calling an async function directly from an event handler without rendering a modal component:
import { signInWithBvndle } from "@dblackdev/bvndle-sso-react-native";
const handleSignIn = async () => {
try {
const ssoAccessToken = await signInWithBvndle({
url: "YOUR_SSO_URL",
clientId: "YOUR_CLIENT_ID",
ssoTokenUrl: "YOUR_SSO_TOKEN_URL",
redirectUrl: "com.yourapp://auth", // Optional if configured on Bvndle dashboard
});
console.log("Retrieved token:", ssoAccessToken);
// Send ssoAccessToken to your backend server or store session securely
} catch (error) {
console.error("Sign-in cancelled or failed:", error.message);
}
};Authentication Modes (authMode)
| Mode | Technology | Description | Recommended For |
| --------------------------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- |
| "browser" (Default) | ASWebAuthenticationSession (iOS) / Chrome Custom Tabs (Android) | Displays the native system browser sheet with visible URL address bar and SSL certificate status. Supports Apple Passkeys, iCloud Keychain autofill, and automatic deep link closing. | Production apps & Apple App Store compliance (Guideline 4.0) |
| "webview" | react-native-webview | Displays an in-app embedded modal WebView with custom header and loading overlay. | Custom embedded UI requirements or kiosk environments |
Callback Redirection (redirectUrl)
- Configured
redirectUrl: Provide a custom scheme (e.g.,com.yourapp://auth) or Universal Link (e.g.,https://yourapp.com/auth) when you want strict client-side validation against that exact callback identity. - Server-Driven Redirects (Omitted
redirectUrl): If your redirect URI is only configured on the Bvndle dashboard, you can omitredirectUrlfromconfig. The SDK listens for incoming deep links via React NativeLinkingand captures the authorization code automatically.
Props Reference (BvndleAuthProps)
| Prop | Type | Default | Description |
| -------------- | ---------------------------------- | ------------ | -------------------------------------------------------------------------------------------------- |
| visible | boolean | Required | Controls the visibility of the authentication modal. |
| authMode | BvndleAuthMode | "browser" | Presentation mode ("browser" uses native Safari/Custom Tabs; "webview" uses embedded WebView). |
| onClose | () => void | Required | Callback invoked when the authentication flow is dismissed or closed. |
| onSuccess | (ssoAccessToken: string) => void | Required | Callback invoked with the validated access token upon successful sign-in. |
| onError | (message: string) => void | Required | Callback invoked with a descriptive error message upon failure or cancellation. |
| config | BvndleConfig | Required | Configuration object containing endpoints, client credentials, and display options. |
| renderHeader | () => React.ReactNode | undefined | Optional custom header component to render above the WebView (in authMode="webview"). |
Configuration Reference (BvndleConfig)
| Property | Type | Default | Description |
| ------------------------ | --------------------------------- | ------------------ | ----------------------------------------------------------------------------------------------------- |
| url | string | Required | Base URL for Bvndle SSO portal (e.g., "YOUR_SSO_URL"). Must use HTTPS in production. |
| clientId | string | Required | Registered Client Application ID issued by Bvndle. |
| ssoTokenUrl | string | Required | Backend endpoint used to exchange authorization code for SSO token (e.g., "YOUR_SSO_TOKEN_URL"). |
| redirectUrl | string | undefined | Optional expected callback URL. If omitted, accepts dashboard-configured callbacks. |
| scope | string | "profile" | Requested OAuth scopes (e.g., "profile", "profile email"). |
| state | string | Auto-generated | Optional custom CSRF state nonce. If omitted, a cryptographic random nonce is generated. |
| authMode | BvndleAuthMode | "browser" | Default authentication presentation mode ("browser" or "webview"). |
| preferEphemeralSession | boolean | false | When in browser mode on iOS, requests an ephemeral session (private browsing without shared cookies). |
| loadingMessage | string | "Please wait..." | Message shown below the activity spinner during token exchange. |
| loaderColor | string | "#0000ff" | Custom hex/rgb color applied to the activity loader. |
| loaderSize | BvndleLoaderSize | "large" | Custom size of the activity loader ("small" or "large"). |
| allowInsecureHttp | boolean | false | Allows cleartext http:// for local testing against localhost or 10.0.2.2. |
| debug | boolean | false | Enables diagnostic console logging. |
| logger | (entry: BvndleLogEntry) => void | undefined | Custom structured telemetry handler (for Sentry, Datadog, etc.). |
TypeScript Support & Exported Types
The package is written in TypeScript and provides complete, first-class type definitions for all options and parameters:
import type {
BvndleConfig,
BvndleAuthProps,
BvndleAuthMode, // "browser" | "webview"
AuthMode, // Alias for BvndleAuthMode
BvndleLoaderSize, // "small" | "large"
LoaderSize, // Alias for BvndleLoaderSize
BvndleLogEntry, // Structured log object emitted to custom loggers
BvndleLogLevel, // "debug" | "info" | "warn" | "error"
SignInWithBvndleOptions,
} from "@dblackdev/bvndle-sso-react-native";Usage Example with Strongly-Typed Props:
import type { BvndleConfig, BvndleAuthMode } from "@dblackdev/bvndle-sso-react-native";
interface CustomButtonProps {
authMode?: BvndleAuthMode; // Strongly typed as "browser" | "webview"
}
export const CustomLoginButton = ({ authMode = "browser" }: CustomButtonProps) => {
const config: BvndleConfig = {
url: "YOUR_SSO_URL",
clientId: "YOUR_CLIENT_ID",
ssoTokenUrl: "YOUR_SSO_TOKEN_URL",
authMode, // Type-safe
};
// ...
};Apple App Store Review Guidelines Guide (4.0 & 4.8)
When submitting an app using Bvndle SSO to Apple App Review, you may encounter review feedback regarding Guideline 4.0 (browser presentation) or Guideline 4.8 (Sign in with Apple requirements). Here is how each is handled:
1. Guideline 4.0: URL Bar & SSL Certificate Inspection (Resolved by SDK)
If Apple App Review requests that your app display the URL address bar and SSL certificate during web login, this SDK resolves that requirement out of the box.
- SDK Solution: The default
authMode="browser"uses nativeASWebAuthenticationSession/SFSafariViewControlleron iOS, ensuring users can visually inspect the domain name, address bar, and SSL/TLS certificate padlock.
Template Reply to Apple Reviewers for Guideline 4.0:
"In this build, we updated our authentication flow to use
ASWebAuthenticationSession/SFSafariViewControllervia the native system browser sheet. Users can now view the domain address bar, inspect the SSL certificate, and complete sign-in securely in full compliance with App Store Review Guideline 4.0."
2. Guideline 4.8: "Sign in with Apple" & Third-Party Login Rules
Apple Review Guideline 4.8 states that apps offering third-party or social login services (like Google, Facebook, etc.) must also provide Sign in with Apple as an equivalent option on the login screen.
When Apple reviewers see a "Sign in with Bvndle" button on a public consumer app, they may classify Bvndle as a third-party login service and request that Sign in with Apple also be offered.
Path A: For Public Consumer Apps (Adding Sign in with Apple)
If your app is a public consumer app and Bvndle is offered as a third-party login option:
- Apple requires adding Sign in with Apple alongside your other sign-in buttons.
- Install
@invertase/react-native-apple-authenticationin your host mobile app:npm install @invertase/react-native-apple-authentication cd ios && pod install && cd .. - Render the native Apple Sign-In button on your login screen alongside the "Sign in with Bvndle" button.
Path B: Claiming an Official Apple Exemption (No Code Changes Needed)
Apple explicitly waives the "Sign in with Apple" requirement if your app qualifies under one of the official exemptions:
Exemption 1: Bvndle is Your Company's First-Party Unified Account System
If Bvndle is owned by your organization or is your company's proprietary first-party account system:
Template Reply to Apple Review in App Store Connect: "Dear App Review Team,
Thank you for your feedback regarding Guideline 4.8. We would like to clarify that Bvndle is our company's proprietary first-party account system and identity provider, not a third-party social login service.
Per App Store Review Guideline 4.8, apps that exclusively use their own company's account setup and sign-in system are exempt from the Sign in with Apple requirement: 'Sign in with Apple is not required if: Your app exclusively uses your company’s own account setup and sign-in systems.'
Bvndle SSO serves as our internal proprietary account manager for authenticating users into our platform. Therefore, our app falls under this explicit exemption. Please let us know if you require any additional details regarding our account infrastructure."
Exemption 2: Enterprise or Business Organization SSO (B2B)
If your app is an enterprise or business app where users sign in with corporate credentials:
Template Reply to Apple Review in App Store Connect: "Dear App Review Team,
Thank you for the review. Our application is a business/enterprise solution that requires users to authenticate with their existing enterprise organization account managed via Bvndle SSO.
Per Guideline 4.8, enterprise and business accounts are explicitly exempt: 'Sign in with Apple is not required if: Your app is an education, enterprise, or business app that requires the user to sign in with an existing education or enterprise account.'
Because access is restricted to authorized enterprise users with existing Bvndle credentials, Sign in with Apple is not applicable to our business authentication model."
Security
OAuth CSRF state Parameter: A unique cryptographic state nonce is generated for every session and validated on redirect (RFC 6749 / RFC 6819).
- Origin Whitelisting: The WebView restricts navigations strictly to
https://*and approved schemes. - Dangerous Scheme Blocking: Intercepts and drops unsafe URI schemes (
javascript:,data:,file:,vbscript:). - HTTPS Enforcement: Production SSO endpoints must use
https://. - Credential Redaction in Logs: URLs logged via
debugorloggerhave authorization codes, tokens, and query strings redacted.
Building & Validating
# Run test suite (Node test runner)
npm test
# Run clean compile and test validation
npm run validate
# Check package tarball before publish
npm run pack:checkLicense
ISC
