UNPKG

expo-finance-kit

Version:

Native Expo module for Apple FinanceKit - Access financial data from Apple Card and other accounts

191 lines 6.17 kB
/** * Authorization management module for Expo Finance Kit * Handles FinanceKit authorization flows and status management */ import { Platform } from 'react-native'; import ExpoFinanceKit from '../ExpoFinanceKitModule'; import { FinanceKitErrorCode } from '../ExpoFinanceKit.types'; import { createFinanceKitError } from '../utils/errors'; /** * Requests authorization to access financial data * @returns Promise resolving to authorization result */ export async function requestAuthorization() { if (Platform.OS === 'android') { return { granted: false, status: 'unavailable', }; } try { const granted = await ExpoFinanceKit.requestAuthorization(); const status = await ExpoFinanceKit.getAuthorizationStatus(); return { granted, status: status, }; } catch (error) { console.error('Error requesting FinanceKit authorization:', error); return { granted: false, status: 'denied', }; } } /** * Gets current authorization status * @returns Promise resolving to current authorization status */ export async function getAuthorizationStatus() { if (Platform.OS === 'android') { return 'unavailable'; } try { const status = await ExpoFinanceKit.getAuthorizationStatus(); return status; } catch (error) { console.error('Error getting authorization status:', error); return 'unavailable'; } } /** * Checks if FinanceKit is available on the device * @returns Boolean indicating availability */ export function isFinanceKitAvailable() { if (Platform.OS === 'android') { return false; } return ExpoFinanceKit.isAvailable || false; } /** * Ensures user has authorized access before proceeding * @param requestIfNeeded - Whether to request authorization if not determined * @returns Promise resolving to boolean indicating authorization status */ export async function ensureAuthorized(requestIfNeeded = true) { const status = await getAuthorizationStatus(); if (status === 'authorized') { return true; } if (status === 'notDetermined' && requestIfNeeded) { const { granted } = await requestAuthorization(); return granted; } return false; } /** * Authorization status change listener manager */ class AuthorizationListener { listeners = new Map(); /** * Adds a listener for authorization status changes * @param callback - Function to call when status changes * @returns Function to remove the listener */ addStatusChangeListener(callback) { const listenerId = Math.random().toString(36).substring(2, 11); const listener = (payload) => { callback({ ...payload, timestamp: payload.timestamp || Date.now(), }); }; this.listeners.set(listenerId, listener); if (ExpoFinanceKit.addListener) { ExpoFinanceKit.addListener('onAuthorizationStatusChanged', listener); } return () => { this.removeListener(listenerId); }; } /** * Removes a specific listener * @param listenerId - ID of the listener to remove */ removeListener(listenerId) { const listener = this.listeners.get(listenerId); if (listener && ExpoFinanceKit.removeListener) { ExpoFinanceKit.removeListener('onAuthorizationStatusChanged', listener); this.listeners.delete(listenerId); } } /** * Removes all authorization listeners */ removeAllListeners() { if (ExpoFinanceKit.removeAllListeners) { ExpoFinanceKit.removeAllListeners('onAuthorizationStatusChanged'); } this.listeners.clear(); } } export const authorizationListener = new AuthorizationListener(); /** * Waits for authorization with timeout * @param timeoutMs - Maximum time to wait in milliseconds * @returns Promise resolving to authorization result */ export async function waitForAuthorization(timeoutMs = 30000) { return new Promise((resolve, reject) => { const timeout = setTimeout(() => { removeListener(); reject(createFinanceKitError(FinanceKitErrorCode.Unknown, 'Authorization timeout')); }, timeoutMs); const removeListener = authorizationListener.addStatusChangeListener((payload) => { if (payload.status !== 'notDetermined') { clearTimeout(timeout); removeListener(); resolve({ granted: payload.status === 'authorized', status: payload.status, }); } }); // Check current status immediately getAuthorizationStatus().then(status => { if (status !== 'notDetermined') { clearTimeout(timeout); removeListener(); resolve({ granted: status === 'authorized', status, }); } }); }); } /** * Gets human-readable description for authorization status * @param status - Authorization status * @returns Human-readable description */ export function getAuthorizationStatusDescription(status) { switch (status) { case 'authorized': return 'Access to financial data has been granted'; case 'denied': return 'Access to financial data has been denied'; case 'notDetermined': return 'Authorization has not been requested yet'; case 'unavailable': return 'FinanceKit is not available on this device'; default: return 'Unknown authorization status'; } } /** * Checks if authorization can be requested * @returns Promise resolving to boolean */ export async function canRequestAuthorization() { if (!isFinanceKitAvailable()) { return false; } const status = await getAuthorizationStatus(); return status === 'notDetermined'; } //# sourceMappingURL=authorization.js.map