apache / cordova-ios

Apache Cordova iOS
https://cordova.apache.org/
Apache License 2.0
2.15k stars 986 forks source link

feat: add privacy-manifest config support #1406

Closed knaito-asial closed 2 months ago

knaito-asial commented 2 months ago

Platforms affected

ios

Motivation and Context

To support setting ios privacy manifest according to config.xml setting.

Description

Introducing tag in config.xml ios platform directive.

If user add following directive in config.xml (platform ios)

<privacy-manifest>
    <key>NSPrivacyTracking</key>
    <true/>
    <key>NSPrivacyCollectedDataTypes</key>
    <array/>
    <key>NSPrivacyAccessedAPITypes</key>
    <array/>
    <key>NSPrivacyTrackingDomains</key>
    <array/>
</privacy-manifest>

the ios project PrivacyManifest.xcprivacy is updated as config.xml. If user does not set <privacy-manifest> tag in config.xml, the cordova template default PrivacyManifest.xcprivacy is used.

Note: This <privacy-manifest> tag overrides whole PrivacyManifest.xcprivacy file in project each time user execute cordova prepare.

Testing

I locally checked this feature with sample project. I locally exec npm run coverage.

Checklist

breautek commented 2 months ago

If user does not set tag in config.xml, the cordova template default PrivacyManifest.xcprivacy is used.

Note: This tag overrides whole PrivacyManifest.xcprivacy file in project each time user execute cordova prepare.

How does this work with plugins? Can a plugin use <privacy-manifest-ios> within the plugin.xml or will the application's config.xml overwrite plugin entries?

I don't want to introduce scope creep but I just want to make sure this was thought about. I think it would be ideal for plugins to be able to declare their privacy entries and the results will get merged into one file for the application. Otherwise it will be a painful process for plugin authors to document and hope end users follows instructions to add the necessary privacy entries.

erisu commented 2 months ago

How does this work with plugins? Can a plugin use <privacy-manifest-ios> within the plugin.xml or will the application's config.xml overwrite plugin entries?

The PR will solely focus on adding the minimum support for the privacy-manifest tag to the config.xml for app developers.

We aim to ensure that both Config.xml (for App Developers) and Plugin.xml (for Plugin Developers) support this tag and are completed and released before Apple's Privacy Manifest requirement takes effect. However, in the event that we are unable to complete the support for plugin.xml, at least the support for config.xml will be completed and merged with this PR.

I don't want to introduce scope creep but I just want to make sure this was thought about. I think it would be ideal for plugins to be able to declare their privacy entries and the results will get merged into one file for the application. Otherwise it will be a painful process for plugin authors to document and hope end users follows instructions to add the necessary privacy entries.

As you mentioned, we're aiming to keep the scope specific for this PR. However, the ultimate goal aligns with your idea of gathering all privacy-manifest tag values and merging them into one file for the application.

codecov-commenter commented 2 months ago

Codecov Report

Attention: Patch coverage is 96.15385% with 1 lines in your changes are missing coverage. Please review.

Project coverage is 78.50%. Comparing base (af6335e) to head (e655949).

Files Patch % Lines
lib/prepare.js 95.65% 1 Missing :warning:
Additional details and impacted files ```diff @@ Coverage Diff @@ ## master #1406 +/- ## ========================================== + Coverage 78.24% 78.50% +0.25% ========================================== Files 15 16 +1 Lines 1788 1814 +26 ========================================== + Hits 1399 1424 +25 - Misses 389 390 +1 ```

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

erisu commented 2 months ago

I tested the following steps:

% cordova create cordovaTest com.erisu.cordovaTest cordovaTest && $_
% cordova platform add ../../cordova-ios-7.1.0-dev.tgz
% cordova build ios
% cordova run ios

I confirmed the following were successful:

I confirmed that the PrivacyInfo manifest exists in the app's scope, within Xcode.

Default PrivacyInfo Settings:

xcode-privacyinfo

I added the following configuration snippet to projects config.xml

    <platform name="ios">
        <privacy-manifest>
            <key>NSPrivacyTracking</key>
            <true/>
            <key>NSPrivacyCollectedDataTypes</key>
            <array/>
            <key>NSPrivacyAccessedAPITypes</key>
            <array/>
            <key>NSPrivacyTrackingDomains</key>
            <array/>
        </privacy-manifest>
    </platform>

I prepared the project with the following command:

% cordova prepare

I confirmed within Xcode that the PrivacyInfo manifest content was updated and reflected the change.

Updated PrivacyInfo Settings after Cordova Prepare:

xcode-privacyinfo-after-change

I confirmed the following were successful with the changes in config.xml:

Important Notice

E.g. of the last item:

Settings in config.xml

    <platform name="ios">
        <privacy-manifest>
            <key>NSPrivacyTracking</key>
            <false/>
        </privacy-manifest>
    </platform>

Running: cordova prepare

Generates the following:

xcode-privacyinfo-after-change-with-missing-items

Noticed that the following items are no longer listed: NSPrivacyCollectedDataTypes, NSPrivacyAccessedAPITypes, NSPrivacyTrackingDomains

BenLaKnet commented 1 month ago

When this version could be used or tested?

phyr0s commented 1 month ago

Hello, @erisu When new version 7.1.0 will be released with this change? Thanks

BenLaKnet commented 1 month ago

How to build this version to test ios manifest ?

Jeanlo commented 1 month ago

So, how do you exactly use this feature to comply with Apple guidelines? Because I keep receiving the email, they keep telling me that I need to fill: NSPrivacyAccessedAPICategoryDiskSpace, NSPrivacyAccessedAPICategoryUserDefaults, NSPrivacyAccessedAPICategoryFileTimestamp.

I've set-up those values in my config.xml like this:

<privacy-manifest>
            <key>NSPrivacyAccessedAPITypes</key>
            <array>
                <dict>
                    <key>NSPrivacyAccessedAPITypeReasons</key>
                    <array>
                        <string>7D9E.1</string>
                    </array>
                    <key>NSPrivacyAccessedAPIType</key>
                    <string>NSPrivacyAccessedAPICategoryDiskSpace</string>
                </dict>
                <dict>
                    <key>NSPrivacyAccessedAPIType</key>
                    <string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
                    <key>NSPrivacyAccessedAPITypeReasons</key>
                    <array>
                        <string>C617.1</string>
                    </array>
                </dict>
                <dict>
                    <key>NSPrivacyAccessedAPITypeReasons</key>
                    <array>
                        <string>1C8F.1</string>
                    </array>
                    <key>NSPrivacyAccessedAPIType</key>
                    <string>NSPrivacyAccessedAPICategoryUserDefaults</string>
                </dict>
            </array>
</privacy-manifest>

I have also tried using some of the examples above, and the email keeps telling me the same thing.

BenLaKnet commented 1 month ago

I do not see files generated, but when I uploaded a new version with 7.1.1.nightly-, I did not receive an email.


<platform name="ios">
        <privacy-manifest>
            <key>NSPrivacyAccessedAPITypes</key>
            <array>
                <dict>
                    <key>NSPrivacyAccessedAPIType</key>
                    <string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
                    <key>NSPrivacyAccessedAPITypeReasons</key>
                    <array>
                        <string>C617.1</string>
                    </array>
                </dict>
                <dict>
                    <key>NSPrivacyAccessedAPIType</key>
                    <string>NSPrivacyAccessedAPICategoryDiskSpace</string>
                    <key>NSPrivacyAccessedAPITypeReasons</key>
                    <array>
                        <string>E174.1</string> <!-- autre valeur 85F4.1 -->
                    </array>
                </dict>
                <dict>
                    <key>NSPrivacyAccessedAPIType</key>
                    <string>NSPrivacyAccessedAPICategoryUserDefaults</string>
                    <key>NSPrivacyAccessedAPITypeReasons</key>
                    <array>
                        <string>CA92.1</string>
                    </array>
                </dict>
            </array>
        </privacy-manifest>
    </platform>

Is this possible?