react-native-capture-protection

repository·main·Indexed 43 days ago

https://github.com/wn-na/react-native-capture-protection

A React Native library for version 2.4.1 that prevents and detects screen captures, screenshots, and app switcher previews on iOS and Android. It provides a unified API via CaptureProtection.prevent() and allow(), along with the useCaptureProtection and useCaptureDetection hooks. Fully compatible with React Native CLI and Expo (via Custom Dev Client), featuring a built-in Expo Config Plugin for Android configuration.

Tokens
6.7K
Snippets
29
Records
30
Agent score
55%

What's inside react-native-capture-protection

  1. Install react-native-capture-protection

    main

    Install the library using your preferred package manager.

    Note for older projects: If you are using React Native < 0.70, it is recommended to use v1.9.17 for stability. The latest v2.x versions may not be compatible.

    Note for Expo users: This library contains native code and requires a Custom Dev Client. It will not work with Expo Go.

    # npm
    npm install react-native-capture-protection
    
    # yarn
    yarn add react-native-capture-protection
    
    # Expo (Dev Client only)
    npx expo install react-native-capture-protection
  2. Migrate from v1.x to v2.x

    main

    When upgrading react-native-capture-protection from version 1.x to 2.x, you must account for breaking changes in the hook return values, method signatures, and event handling. The API has moved from specific method names (e.g., preventScreenRecord) to a unified prevent() and allow() pattern using an options object.

    # Update the package to the latest version
    npm install react-native-capture-protection@latest
    # or
    yarn add react-native-capture-protection@latest
  3. Enable Capture Detection on Android < 14 (Optional)

    main

    On Android 10-13, capture prevention and permission are supported by default. To enable capture detection (which uses the READ_MEDIA_IMAGES permission to check for screenshot files), you must use the callbackTiramisu configuration.

    Play Store Requirement: If publishing to the Play Store, you must declare the usage of READ_MEDIA_IMAGES as follows: Used by the application to detect screenshots, by checking for screenshot files in the user’s media storage.

    ### React Native CLI
    Add to `android/app/build.gradle`:
    ```gradle
    defaultConfig {
        ...
        missingDimensionStrategy "react-native-capture-protection", "callbackTiramisu"
    }

    Expo (Dev Client only)

    Add to app.json:

    {
      "plugins": [
        ...,
        [
          "react-native-capture-protection",
          {
            "captureType": "callbackTiramisu"
          }
        ]
      ]
    }
  4. Integrate with Jest

    main

    To test components using this library, you must mock the module using the provided mock file.

    ### 1. Update jest.config.js
    ```javascript
    module.exports = {
      setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
    };

    2. Create jest.setup.js

    jest.mock('react-native-capture-protection', () =>
      require('react-native-capture-protection/jest/capture-protection-mock')
    );

    3. Overriding the mock in tests

    import { CaptureProtection } from "react-native-capture-protection/jest/capture-protection-mock";
    
    test("prevent is called", async () => {
        await CaptureProtection.prevent();
        expect(CaptureProtection.prevent).toHaveBeenCalled();
    });
  5. Configure Android (Required)

    main

    Android requires specific configuration in your build files to enable capture prevention and detection. The configuration depends on whether you are using React Native CLI or Expo.

    ### React Native CLI
    Add to `android/app/build.gradle`:
    ```gradle
    defaultConfig {
        ...
        missingDimensionStrategy "react-native-capture-protection", "base"
    }

    Expo (Dev Client only)

    Add to app.json:

    {
      "plugins": [
        ...,
        [
          "react-native-capture-protection",
          {
            "captureType": "base"
          }
        ]
      ]
    }
  6. Use the Expo Config Plugin for react-native-capture-protection

    main

    To use react-native-capture-protection in an Expo project, you can use its built-in Config Plugin. This plugin automates the required Android configuration by adding the necessary missingDimensionStrategy to your app/build.gradle file.

    When using the plugin, you can optionally provide a captureType property to determine which dimension strategy is applied:

    • If captureType is set to 'base', it uses: missingDimensionStrategy "react-native-capture-protection", "base".
    • For any other value (or if omitted), it uses: missingDimensionStrategy "react-native-capture-protection", "callbackTiramisu".

    Note: This plugin is intended for use with Expo Dev Clients.

    // In your app.config.js or app.json
    {
      "expo": {
        "plugins": [
          [
            "react-native-capture-protection",
            {
              "captureType": "base"
            }
          ]
        ]
      }
    }
  7. Prevent screen visibility in Android App Switcher

    main

    On Android, you can prevent sensitive content from being visible in the App Switcher (the multitasking/recent apps view) by toggling protection based on the application's focus state.

    By listening to AppState changes, you can call CaptureProtection.prevent() when the app loses focus (blur) and CaptureProtection.allow() when the app regains focus (focus). This ensures that when a user is switching apps, the preview of your application is protected/obscured.

    useEffect(() => {
      const appStateFocusSub = AppState.addEventListener('focus', () => {
        CaptureProtection.allow();
      });
      const appStateBlurSub = AppState.addEventListener('blur', () => {
        CaptureProtection.prevent();
      });
    
      return () => {
        appStateFocusSub.remove();
        appStateBlurSub.remove();
      };
    }, []);
  8. Customize iOS protection screens with IOSProtectionScreenOption

    main

    On iOS, when preventing screen recording or app switching, you can provide a custom visual experience using IOSProtectionScreenOption. You can either provide a single image or a custom text-based screen with hex color formatting.

    type IOSProtectionCustomScreenOption = {
      text: string; // Text to display
      textColor?: `#${string}`; // Text color in hex format, default is Black
      backgroundColor?: `#${string}`; // Background color in hex format, default is White
    };
    
    type IOSProtectionScreenOption =
      | { 
          image: NodeRequire; // Image to display
        }
      | IOSProtectionCustomScreenOption;
  9. Use the unified prevent() and allow() API

    main

    The v2.x API replaces specific method names with a unified prevent() and allow() interface that accepts an options object. This allows for more granular control over screen recording and app switcher protection.

    // Screen Recording Protection
    CaptureProtection.prevent({ record: true });
    CaptureProtection.allow({ record: true });
    
    // Screen Recording with Text Overlay
    CaptureProtection.prevent({ record: { text: "test" } });
    
    // Screen Recording with Image Overlay
    CaptureProtection.prevent({ record: { image: require("...") } });
    
    // App Switcher (Background) Protection
    CaptureProtection.prevent({ appSwitcher: true });
    CaptureProtection.allow({ appSwitcher: true });
  10. Check CaptureProtectionModuleStatus

    main

    The CaptureProtectionModuleStatus interface represents the current protection state for the three main categories: screenshots, screen recording, and the app switcher.

    interface CaptureProtectionModuleStatus {
      screenshot: boolean; // Screenshot protection status
      record: boolean; // Screen recording protection status
      appSwitcher: boolean; // App switcher protection status
    }