UNPKG

expo-app-integrity

Version:
101 lines 7.07 kB
/** * @description * iOS Only. Check if the device supports iOS AppAttest. * * Attestation support is handled via an extensive system of exceptions after the service is requested. Running this function on Android will throw an error. Wrap in a platform check if you need to support both platforms. * * `AppIntegrity.isSupported()` is only exposed on iOS, but `expo-app-integrity` recommends not to use the API at all, in spite of Apple's recommendations. Apple includes the API so as not to * penalize users if AppAttest isn't supported on the device they're using. `AppIntegrity.isSupported()` is included in this API so that you can adopt Apple's recommended approach in your Expo * app if you so choose, but you'll need to have a strategy in place to determine the outcomes of unattested requests. * * Apple's recommendation for checking for AppAttest support: https://developer.apple.com/documentation/devicecheck/establishing_your_app_s_integrity#3576028 * * Why you might not want to follow Apple's recommendation: https://swiftrocks.com/app-attest-apple-protect-ios-jailbreak * * Android has no such API, so you'll need to wrap this call in a check for an `'ios'` `Platform.OS`. On Android, whether the functionality is supported can be gleaned from simply trying to make * the request.`try` `AppIntegrity.attestKey` and handle API availability errors based on Google's recommendations for any error message you receive (i.e., project configuration errors, exponential * backoff)." **/ export declare const isSupported: () => boolean; /** * * @param challenge * @param cloudProjectNumber * @returns string | never * * @description * This is generally the only function from the module that you'll need to get an app integrity attestation from AppAttest / Google Play Integrity API. * * On iOS, this function: * * 1) Generates a key if one doesn't exist and store its identifier in secure storage as exposed in peer-dependency `expo-secure-store`. It will use the identifier * from the secure store if this function was already called on the user's device. * * 2) Calls `DCAppAttestService.attestKey` with your persisted key identifier and server-generated challenge to get an attestation from Apple servers. This action IS * subject to Apple's rate limiting, so you'll need to prepare your app with any / all of the following measures. * * - you should implement exponential backoff for failed attestation requests * - Onboard Users Gradually: if you already have a large user base, you'll need to incrementally introduce your attestation feature to subsets of your user base * - you may need to implement decision logic that is less stringent than simply rejecting unattested requests, and progressively tighten requirements if unattested traffic increases * * On Android, this function calls `GooglePlayIntegrity.requestIntegrityToken` with your server-generated challenge and project's Google Cloud Project Number to get an attestation from * Google Play servers. * * BOTH iOS and Android APIs are subject to rate limiting, so you'll need to prepare your app with any / all of the following measures: * - you should implement exponential backoff for failed attestation requests * - Onboard Users Gradually: if you already have a large user base, you'll need to incrementally introduce your attestation feature to subsets of your user base * - you may need to implement decision logic that is less stringent than simply rejecting unattested requests, and progressively tighten requirements if unattested traffic increases * * See Apple's documentation on preparing to use AppAttest for more information: https://developer.apple.com/documentation/devicecheck/preparing_to_use_the_app_attest_service * See Google's overview on using the Play Integrity API: https://developer.android.com/google/play/integrity/overview * * @throws * On iOS: * This function can throw errors that extend the `DCError` struct: * - `'INVALID_KEY'`: The key identifier is incorrect or was not provided. This is likely to be an issue with an implementation detail of `expo-app-integrity`, so file an issue on the repo if you encounter this error. * - `'INVALID_INPUT'`: An error code that indicates when your app provides data that isn't formatted correctly. Ensure that you're passing a valid challenge string. * - `'SERVER_UNAVAILABLE'`: An error that indicates a failed attempt to contact the App Attest service during an attestation. Possible resolutions include: * - implementing exponential backoff for failed attestation requests, * - reduce the possbility of rate-limiting by onboarding users gradually onto App Attest if you have a large user base * - ensure that your users have reliable Internet connectivity with modules like `expo-network` or `react-native-netinfo` * - `'FEATURE_UNSUPPORTED'`: An error that indicates that the device does not support App Attest, such as MacOS. This can be mitigated by using `AppIntegrity.isSupported()` (iOS only) to check for App Attest support before calling this function. * - `'UNKNOWN_SYSTEM_FAILURE'`: A failure has occurred, such as the failure to generate a token. This is likely analogous to a 500 error on Apple's servers, and should be handled by implementing exponential backoff. * * `expo-app-integrity` also may throw its own `'UNHANDLED_EXCEPTION'` with the original error message if it does not match any of the above error codes. * * `DCError` struct documentation: https://developer.apple.com/documentation/devicecheck/dcerror * * On Android: * This function can throw errors that extend the `IntegrityServiceException` class: * * `IntegrityServiceException` class documentation: https://developer.android.com/google/play/integrity/reference/com/google/android/play/core/integrity/IntegrityServiceException */ export declare function attestKey( /** * A crytographically random value generated on your server, * and associated with your user object for server-side * comparison after Apple signs the request */ challenge: string, /** * Android only (required). The Google Cloud Project Number * associated with your app. You can find this by: * 1) Going to the Google Developer Console (https://console.developers.google.com), * 2) selecting your project in the dropdown on the top left (generally this reads "Google Play Console Developer" for Android apps), * 3) selecting the kebab menu at top-right (three vertical dots), * 4) and selecting "Project Settings" */ cloudProjectNumber?: number): Promise<string | never>; export declare function generateAssertion( /** The key identifier assigned in Integrity#generateKey */ keyIdentifier: string, /** * A crytographically random value generated on your server, * and associated with your user object for server-side * comparison after Apple signs the request */ challenge: string, /** The request JSON for Apple to sign */ requestJSON: Record<string | number | symbol, unknown>): Promise<string | never>; export * from './errors'; //# sourceMappingURL=index.d.ts.map