expo-ii-integration
v0.1.24
Published
Expo library to enable smartphone native applications to invoke Internet Identity through a web application
Maintainers
Readme
expo-ii-integration
This library enables Expo applications (both web and native) to authenticate with Internet Identity through a web application bridge. It provides a seamless integration between Expo applications and Internet Identity authentication, with different authentication flows for web and native platforms.
Security Overview
The library implements security measures to protect against:
- Delegation Theft: Prevents malicious applications from intercepting the delegation chain
- Cross-App Delegation Misuse: Ensures delegations are only used by your legitimate app
- Phishing Attacks: Protects against malicious apps intercepting authentication callbacks
Features
- Seamless Internet Identity authentication in Expo apps
- Platform-specific authentication flows:
- Web: Modal-based authentication using iframe messaging
- Native: Browser-based authentication using Expo WebBrowser
- Secure key and delegation chain management
- Automatic path restoration after authentication
- Error handling and state management
- Support for multiple deep link paths
Installation
npm install expo-ii-integrationPeer Dependencies
{
"@dfinity/agent",
"@dfinity/identity",
"canister-manager",
"expo-crypto-universal",
"expo-icp-app-connect",
"expo-icp-app-connect-helpers",
"expo-icp-frontend-helpers",
"expo-linking",
"expo-router",
"expo-storage-universal",
"expo-web-browser",
"react",
"react-native"
}Usage
Basic Setup
- Wrap your app with the
IIIntegrationProvider:
import * as Linking from 'expo-linking';
import { Platform } from 'react-native';
import { IIIntegrationProvider, useIIIntegration } from 'expo-ii-integration';
import { buildAppConnectionURL } from 'expo-icp-app-connect-helpers';
import { getDeepLinkType } from 'expo-icp-frontend-helpers';
import {
LOCAL_IP_ADDRESS,
DFX_NETWORK,
CANISTER_ID_II_INTEGRATION,
CANISTER_ID_FRONTEND,
} from '@/constants';
import { cryptoModule } from '@/crypto';
function App() {
const isWeb = Platform.OS === 'web';
const secureStorage = isWeb
? new WebSecureStorage()
: new NativeSecureStorage();
const regularStorage = isWeb
? new WebRegularStorage()
: new NativeRegularStorage();
const deepLink = Linking.createURL('/');
const iiIntegrationUrl = buildAppConnectionURL({
dfxNetwork: DFX_NETWORK,
localIPAddress: LOCAL_IP_ADDRESS,
targetCanisterId: CANISTER_ID_II_INTEGRATION,
});
const deepLinkType = getDeepLinkType({
deepLink,
frontendCanisterId: CANISTER_ID_FRONTEND,
easDeepLinkType: process.env.EXPO_PUBLIC_EAS_DEEP_LINK_TYPE,
});
const iiIntegration = useIIIntegration({
iiIntegrationUrl,
deepLinkType,
secureStorage,
regularStorage,
cryptoModule,
});
return (
<IIIntegrationProvider value={iiIntegration}>
{/* Your app components */}
</IIIntegrationProvider>
);
}Using the Authentication Context
import { useIIIntegrationContext } from 'expo-ii-integration';
function AuthButton() {
const {
login,
logout,
isAuthenticated,
isAuthReady,
getIdentity,
authError,
clearAuthError,
} = useIIIntegrationContext();
if (!isAuthReady) return null;
return (
<Button
onPress={isAuthenticated ? logout : login}
title={isAuthenticated ? 'Logout' : 'Login with Internet Identity'}
/>
);
}API Reference
useIIIntegration Hook
type UseIIIntegrationParams = {
iiIntegrationUrl: string; // The II integration URL
deepLinkType: DeepLinkType; // The deep link type ('modern', 'icp', 'dev-server', 'expo-go', 'legacy')
secureStorage: Storage; // Secure storage for sensitive data
regularStorage: Storage; // Regular storage for non-sensitive data
cryptoModule: CryptoModule; // Crypto module for session ID generation
};
type IIIntegrationType = {
isAuthReady: boolean; // Whether the authentication system is ready
isAuthenticated: boolean; // Whether the user is authenticated
getIdentity: () => Promise<Identity | undefined>; // Get the current identity
login: (loginOuterParams?: LoginOuterParams) => Promise<void>; // Login function
logout: () => Promise<void>; // Logout function
authError: unknown | undefined; // Any authentication error
clearAuthError: () => void; // Clear the authentication error
};Contributing
Contributions are welcome! Please read our contributing guidelines for details.
License
MIT License
