@umutcansu/react-native-pinvault 2.4.2 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +36 -0
- package/README.md +25 -6
- package/RNPinVault.podspec +1 -1
- package/android/build.gradle +1 -1
- package/android/src/main/java/io/github/umutcansu/pinvault/reactnative/PinnedFetch.kt +6 -0
- package/ios/Core/PinnedFetch.swift +5 -0
- package/ios/PinVaultReactNetworking.swift +9 -0
- package/ios/RNPinVaultWebSocketPinning.mm +24 -0
- package/lib/typescript/src/types.d.ts +7 -0
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/plugin/withPinVault.js +168 -1
- package/src/types.ts +7 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,41 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.6.0 — 2026-10-14
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- **iOS WebSockets carry the attestation token.** A `wss` socket to a token
|
|
8
|
+
host of an attesting block now sends `PinVault-Token` (and
|
|
9
|
+
`PinVault-Proof` with `proofOfPossession()`) in its upgrade request when a
|
|
10
|
+
token is held, as Android does; without one it goes without and an
|
|
11
|
+
attestation starts, so a reconnect has it.
|
|
12
|
+
- **`fetch` refuses `PinVault-Token` / `PinVault-Proof` headers:** only the
|
|
13
|
+
library sets them, for its token hosts. On iOS a WebSocket drops such
|
|
14
|
+
headers given by the app (the library's own go in their place).
|
|
15
|
+
- **Docs and types:** `expectedSignerSha256` is Android only; iOS uses
|
|
16
|
+
`ios.expectedBundleIds` / `ios.expectedTeamIds`.
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- Depends on PinVault 2.6.0 (Maven Central, Swift package tag `v2.6.0`).
|
|
21
|
+
|
|
22
|
+
## 2.5.0 — 2026-10-12
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
|
|
26
|
+
- **Expo: apps with their own Android backup rules build again, with
|
|
27
|
+
PinVault's excludes kept.** An app or plugin (`expo-secure-store`) that sets
|
|
28
|
+
`fullBackupContent` / `dataExtractionRules` failed the manifest merge
|
|
29
|
+
against the library's rules. At the end of prebuild the plugin now copies
|
|
30
|
+
those rules to `res/xml/pinvault_merged_<name>.xml` with PinVault's excludes
|
|
31
|
+
added (only where the app's includes reach) and points the manifest at the
|
|
32
|
+
copy with `tools:replace`; rules it cannot find stop prebuild. Built with
|
|
33
|
+
Expo SDK 54 + `expo-secure-store`, Android release.
|
|
34
|
+
|
|
35
|
+
### Changed
|
|
36
|
+
|
|
37
|
+
- Depends on PinVault 2.5.0 (Maven Central, Swift package tag `v2.5.0`).
|
|
38
|
+
|
|
3
39
|
## 2.4.2 — 2026-10-10
|
|
4
40
|
|
|
5
41
|
### Added
|
package/README.md
CHANGED
|
@@ -29,9 +29,9 @@ npm install @umutcansu/react-native-pinvault
|
|
|
29
29
|
cd ios && pod install
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
The native libraries come with it, at the package's own version: npm 2.
|
|
33
|
-
uses `io.github.umutcansu:pinvault:2.
|
|
34
|
-
package at tag `v2.
|
|
32
|
+
The native libraries come with it, at the package's own version: npm 2.6.0
|
|
33
|
+
uses `io.github.umutcansu:pinvault:2.6.0` from Maven Central and the Swift
|
|
34
|
+
package at tag `v2.6.0`. The New Architecture must stay on (React Native's
|
|
35
35
|
default since 0.76).
|
|
36
36
|
|
|
37
37
|
**iOS.** The pod depends on the PinVault Swift package through React Native's
|
|
@@ -102,6 +102,18 @@ npx expo install @umutcansu/react-native-pinvault
|
|
|
102
102
|
Unknown options and wrong types stop prebuild. Tested with Expo SDK 54
|
|
103
103
|
(React Native 0.81) on Android and iOS, release builds.
|
|
104
104
|
|
|
105
|
+
**Backup rules.** The Android library keeps its stores out of cloud backup
|
|
106
|
+
and device transfer with its own `fullBackupContent` / `dataExtractionRules`.
|
|
107
|
+
An app (or a plugin such as `expo-secure-store`) that sets its own rules used
|
|
108
|
+
to fail the manifest merge; replacing them by hand would drop PinVault's
|
|
109
|
+
excludes. At the end of prebuild the plugin copies each such rules
|
|
110
|
+
file (from the app or a library under `node_modules`) to
|
|
111
|
+
`res/xml/pinvault_merged_<name>.xml` with PinVault's excludes added, and
|
|
112
|
+
points the manifest at the copy with `tools:replace`. Rules it cannot find stop
|
|
113
|
+
prebuild. A bare React Native app with its own rules adds the
|
|
114
|
+
`<exclude>` lines of the library's `pinvault_backup_rules.xml` /
|
|
115
|
+
`pinvault_data_extraction_rules.xml` to them and uses `tools:replace`.
|
|
116
|
+
|
|
105
117
|
## Quick start
|
|
106
118
|
|
|
107
119
|
```ts
|
|
@@ -146,7 +158,8 @@ names), enum values are the Kotlin constant names (`'TOKEN_MTLS'`,
|
|
|
146
158
|
serverScope, clientCaPins, clientCertHosts, renewalUrl, attestation, tokenHosts, proofOfPossession, … }],
|
|
147
159
|
vaultFiles: [{ key, endpoint, configApi, accessPolicy, encryption, userAuth, storage,
|
|
148
160
|
maxOfflineAge: { amount: 7, unit: 'DAYS' }, … }],
|
|
149
|
-
requireCaTrust, requireUnlockedDevice, requireHardwareBackedKeys,
|
|
161
|
+
requireCaTrust, requireUnlockedDevice, requireHardwareBackedKeys,
|
|
162
|
+
expectedSignerSha256, // Android only; iOS: ios.expectedBundleIds / expectedTeamIds
|
|
150
163
|
wipeVaultFilesOnRevocation, vaultFileMaxOfflineAge, updateIntervalMinutes, deviceAlias, …
|
|
151
164
|
environmentGuard: async (operation) => boolean, // JS, see below
|
|
152
165
|
requirePinnedReactNativeNetworking, // see Networking
|
|
@@ -368,7 +381,11 @@ signer check of attestation (`expectedSignerSha256`, `expectedTeamIds`) reports.
|
|
|
368
381
|
passed. SocketRocket judges the trust before it writes the upgrade request,
|
|
369
382
|
so a refused chain sends no header or cookie. Subprotocols are kept
|
|
370
383
|
(`RCTSetCustomSRWebSocketProvider` is not used: its block never sees them).
|
|
371
|
-
`start` checks the hook is still the initializer's implementation. A
|
|
384
|
+
`start` checks the hook is still the initializer's implementation. A `wss`
|
|
385
|
+
socket to a token host of an attesting block carries `PinVault-Token` (and
|
|
386
|
+
`PinVault-Proof` with `proofOfPossession()`) when a token is held, as on
|
|
387
|
+
Android; without one it goes without and an attestation starts, so a
|
|
388
|
+
reconnect has it. A
|
|
372
389
|
WebSocket to a host that requires a client certificate fails on iOS (no
|
|
373
390
|
identity is presented); use it over TLS, or Android.
|
|
374
391
|
Opt out natively with the Info.plist key `PinVaultPinReactNativeNetworking`
|
|
@@ -451,7 +468,9 @@ as one more signal. The decisive check is server-side attestation
|
|
|
451
468
|
- **CODE** — TypeScript strict; the plugin logs only in development builds
|
|
452
469
|
(`__DEV__`); R8 rules ship in `android/consumer-rules.pro`.
|
|
453
470
|
- **RESILIENCE** — `requireHardwareBackedKeys`, `requireUnlockedDevice` and
|
|
454
|
-
`expectedSignerSha256`
|
|
471
|
+
`expectedSignerSha256` (Android) / `ios.expectedBundleIds` + `ios.expectedTeamIds`
|
|
472
|
+
(iOS) are config keys; turn them on in release builds. Setting only
|
|
473
|
+
`expectedSignerSha256` leaves iOS without an app-identity check.
|
|
455
474
|
|
|
456
475
|
## Privacy: what leaves the device
|
|
457
476
|
|
package/RNPinVault.podspec
CHANGED
|
@@ -4,7 +4,7 @@ package = JSON.parse(File.read(File.join(__dir__, "package.json")))
|
|
|
4
4
|
|
|
5
5
|
# PinVault for iOS is a Swift package (Package.swift at the repository root,
|
|
6
6
|
# product "PinVault"). React Native's spm_dependency adds it to the Pods project:
|
|
7
|
-
# - consumers: the git URL at the tag of this package's version (v2.
|
|
7
|
+
# - consumers: the git URL at the tag of this package's version (v2.6.0);
|
|
8
8
|
# - development: PINVAULT_IOS_PACKAGE_PATH = a PinVault checkout (the sample's
|
|
9
9
|
# Podfile sets it to this repository), the counterpart of pinvault.localPath.
|
|
10
10
|
pinvault_url = "https://github.com/umutcansu/PinVault.git"
|
package/android/build.gradle
CHANGED
|
@@ -42,6 +42,9 @@ internal object PinnedFetch {
|
|
|
42
42
|
private val METHODS = setOf("GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS")
|
|
43
43
|
private val TOKEN = Regex("[!#$%&'*+.^_`|~0-9A-Za-z-]{1,256}")
|
|
44
44
|
|
|
45
|
+
/** The attestation headers: only the library sets them, for its token hosts (and a proof only it can sign). */
|
|
46
|
+
val LIBRARY_HEADERS = listOf("PinVault-Token", "PinVault-Proof")
|
|
47
|
+
|
|
45
48
|
fun parse(json: String): FetchRequest {
|
|
46
49
|
// Base64 inflates by 4/3; leave room for the other fields.
|
|
47
50
|
val f = StrictJson.parseObject(json, "request", maxChars = (MAX_REQUEST_BYTES * 4 / 3 + 64 * 1024).toInt())
|
|
@@ -53,6 +56,9 @@ internal object PinnedFetch {
|
|
|
53
56
|
val headers = Headers.Builder()
|
|
54
57
|
f.stringMap("headers", 128, 256, 8192)?.forEach { (name, value) ->
|
|
55
58
|
if (!TOKEN.matches(name)) throw BridgeInputException("request.headers: '${name.take(40)}' is not a header name")
|
|
59
|
+
if (LIBRARY_HEADERS.any { it.equals(name, ignoreCase = true) }) {
|
|
60
|
+
throw BridgeInputException("request.headers.$name: set by PinVault itself (a token host's requests carry it)")
|
|
61
|
+
}
|
|
56
62
|
if (value.any { it == '\r' || it == '\n' || it.code == 0 }) {
|
|
57
63
|
throw BridgeInputException("request.headers.$name: line breaks are not allowed")
|
|
58
64
|
}
|
|
@@ -27,6 +27,8 @@ public enum PinnedFetch {
|
|
|
27
27
|
public static let maxResponseBytesLimit: Int64 = 50 * 1024 * 1024
|
|
28
28
|
static let methods: Set<String> = ["GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"]
|
|
29
29
|
static let tokenChars = CharacterSet(charactersIn: "!#$%&'*+.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-")
|
|
30
|
+
/// The attestation headers: only the library sets them, for its token hosts (and a proof only it can sign).
|
|
31
|
+
static let libraryHeaders = ["PinVault-Token", "PinVault-Proof"]
|
|
30
32
|
|
|
31
33
|
public static func parse(_ json: String) throws -> FetchRequest {
|
|
32
34
|
let f = try StrictJSON.parseObject(json, path: "request", maxChars: Int(maxRequestBytes * 4 / 3) + 64 * 1024)
|
|
@@ -42,6 +44,9 @@ public enum PinnedFetch {
|
|
|
42
44
|
guard name.unicodeScalars.allSatisfy({ tokenChars.contains($0) }) else {
|
|
43
45
|
throw BridgeInputError("request.headers: '\(name.prefix(40))' is not a header name")
|
|
44
46
|
}
|
|
47
|
+
if libraryHeaders.contains(where: { $0.caseInsensitiveCompare(name) == .orderedSame }) {
|
|
48
|
+
throw BridgeInputError("request.headers.\(name): set by PinVault itself (a token host's requests carry it)")
|
|
49
|
+
}
|
|
45
50
|
if value.unicodeScalars.contains(where: { $0 == "\r" || $0 == "\n" || $0.value == 0 }) {
|
|
46
51
|
throw BridgeInputError("request.headers.\(name): line breaks are not allowed")
|
|
47
52
|
}
|
|
@@ -33,6 +33,15 @@ public final class PinVaultReactNetworking: NSObject {
|
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
/// The attestation headers (`PinVault-Token`, `PinVault-Proof`) a `wss`
|
|
37
|
+
/// WebSocket's upgrade request carries (RNPinVaultWebSocketPinning.mm), as
|
|
38
|
+
/// OkHttp's `newWebSocket` adds them on Android: the held token only —
|
|
39
|
+
/// without one the socket goes without and an attestation starts.
|
|
40
|
+
@objc public static func webSocketUpgradeHeaders(_ url: URL) -> [String: String] {
|
|
41
|
+
guard PinVaultBridge.isStarted else { return [:] }
|
|
42
|
+
return PinVault.shared.webSocketUpgradeHeaders(for: url)
|
|
43
|
+
}
|
|
44
|
+
|
|
36
45
|
/// The request token for RN; nothing reaches the blocks before `resume()`.
|
|
37
46
|
@objc public static func prepare(
|
|
38
47
|
_ request: URLRequest,
|
|
@@ -111,10 +111,34 @@ static id PolicyFor(NSURL *url)
|
|
|
111
111
|
return policy;
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
+
// The upgrade request with the attestation headers of a wss socket to a token
|
|
115
|
+
// host (SocketRocket sends the request's header fields in the upgrade). Only
|
|
116
|
+
// the library sets them: the app's own PinVault-Token / PinVault-Proof are
|
|
117
|
+
// dropped, as `fetch` refuses them.
|
|
118
|
+
static NSURLRequest *WithAttestationHeaders(NSURLRequest *request)
|
|
119
|
+
{
|
|
120
|
+
BOOL callerSet = [request valueForHTTPHeaderField:@"PinVault-Token"] != nil ||
|
|
121
|
+
[request valueForHTTPHeaderField:@"PinVault-Proof"] != nil;
|
|
122
|
+
NSDictionary<NSString *, NSString *> *headers = [request.URL.scheme.lowercaseString isEqualToString:@"wss"]
|
|
123
|
+
? [RNPinVaultReactNetworking webSocketUpgradeHeaders:request.URL]
|
|
124
|
+
: @{};
|
|
125
|
+
if (headers.count == 0 && !callerSet) {
|
|
126
|
+
return request;
|
|
127
|
+
}
|
|
128
|
+
NSMutableURLRequest *copy = [request mutableCopy];
|
|
129
|
+
[copy setValue:nil forHTTPHeaderField:@"PinVault-Token"];
|
|
130
|
+
[copy setValue:nil forHTTPHeaderField:@"PinVault-Proof"];
|
|
131
|
+
[headers enumerateKeysAndObjectsUsingBlock:^(NSString *name, NSString *value, BOOL *stop) {
|
|
132
|
+
[copy setValue:value forHTTPHeaderField:name];
|
|
133
|
+
}];
|
|
134
|
+
return copy;
|
|
135
|
+
}
|
|
136
|
+
|
|
114
137
|
static id PinnedInit(id self, SEL _cmd, NSURLRequest *request, NSArray *protocols, id securityPolicy)
|
|
115
138
|
{
|
|
116
139
|
if (RequiresTLS(request.URL)) {
|
|
117
140
|
securityPolicy = PolicyFor(request.URL);
|
|
141
|
+
request = WithAttestationHeaders(request);
|
|
118
142
|
}
|
|
119
143
|
return gOriginalInit(self, _cmd, request, protocols, securityPolicy);
|
|
120
144
|
}
|
|
@@ -106,6 +106,11 @@ export type PinVaultConfig = {
|
|
|
106
106
|
requireUnlockedDevice?: boolean;
|
|
107
107
|
requireHardwareBackedKeys?: boolean;
|
|
108
108
|
managedTrustRoots?: boolean;
|
|
109
|
+
/**
|
|
110
|
+
* Android only: the SHA-256 digests of the signing certificates the app must be
|
|
111
|
+
* signed with. iOS has no signer digest and ignores this; set `ios.expectedBundleIds`
|
|
112
|
+
* and `ios.expectedTeamIds` there.
|
|
113
|
+
*/
|
|
109
114
|
expectedSignerSha256?: string[];
|
|
110
115
|
environmentGuard?: EnvironmentGuard;
|
|
111
116
|
/** How long the native side waits for `environmentGuard` (ms, 100–30000, default 5000). */
|
|
@@ -136,7 +141,9 @@ export type PinVaultConfig = {
|
|
|
136
141
|
ios?: {
|
|
137
142
|
/** `resolve(host:to:)`: connect to `address` while pinning and verifying `host`. */
|
|
138
143
|
resolve?: Record<string, string>;
|
|
144
|
+
/** The bundle ids the app must run as (iOS counterpart of `expectedSignerSha256`). */
|
|
139
145
|
expectedBundleIds?: string[];
|
|
146
|
+
/** The Apple team ids the app must be signed by (iOS counterpart of `expectedSignerSha256`). */
|
|
140
147
|
expectedTeamIds?: string[];
|
|
141
148
|
/** `userAuthStrength(_:)`; `BIOMETRIC_CURRENT_SET` = `userAuthBiometricOnly()`. */
|
|
142
149
|
userAuthStrength?: 'DEVICE_OWNER' | 'BIOMETRIC_CURRENT_SET';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umutcansu/react-native-pinvault",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.0",
|
|
4
4
|
"description": "PinVault for React Native: dynamic certificate pinning with signed remote configs, mTLS enrollment and signed vault files, as a thin bridge over the native PinVault libraries",
|
|
5
5
|
"main": "./lib/module/index.js",
|
|
6
6
|
"types": "./lib/typescript/src/index.d.ts",
|
package/plugin/withPinVault.js
CHANGED
|
@@ -29,9 +29,11 @@ const {
|
|
|
29
29
|
withAppDelegate,
|
|
30
30
|
withDangerousMod,
|
|
31
31
|
withInfoPlist,
|
|
32
|
+
withFinalizedMod,
|
|
32
33
|
withPodfileProperties,
|
|
33
34
|
withXcodeProject,
|
|
34
35
|
createRunOncePlugin,
|
|
36
|
+
XML,
|
|
35
37
|
} = configPlugins;
|
|
36
38
|
|
|
37
39
|
const pkg = require('../package.json');
|
|
@@ -41,6 +43,29 @@ const BG_TASK_ID = 'io.github.umutcansu.pinvault.refresh';
|
|
|
41
43
|
const MIN_IOS = '16.0';
|
|
42
44
|
const ALLOW_NO_FILE_META = 'io.github.umutcansu.pinvault.ALLOW_NO_NATIVE_SECURITY_FILE';
|
|
43
45
|
const NETWORKING_PROVIDER = 'io.github.umutcansu.pinvault.reactnative.PinVaultNetworkingInitializer';
|
|
46
|
+
// PinVault's own backup rules (pinvault/src/main/res/xml): what must never
|
|
47
|
+
// reach a backup or a device transfer. The test checks this list against them.
|
|
48
|
+
const BACKUP_EXCLUDES = [
|
|
49
|
+
['sharedpref', 'pinvault_secure_config.xml'],
|
|
50
|
+
['sharedpref', 'pinvault_secure_client_cert.xml'],
|
|
51
|
+
['sharedpref', 'pinvault_secure_signing_keys.xml'],
|
|
52
|
+
['sharedpref', 'pinvault_secure_vault_files.xml'],
|
|
53
|
+
['sharedpref', 'pinvault_vault_file_versions.xml'],
|
|
54
|
+
['file', 'vault_files'],
|
|
55
|
+
['sharedpref', 'pinvault_client_cert.xml'],
|
|
56
|
+
['sharedpref', 'ssl_cert_config.xml'],
|
|
57
|
+
['sharedpref', 'ssl_cert_config_default.xml'],
|
|
58
|
+
['sharedpref', 'ssl_cert_config_default-tls.xml'],
|
|
59
|
+
['sharedpref', 'ssl_cert_config_secure-mtls.xml'],
|
|
60
|
+
['sharedpref', 'pinvault_signing_keys.xml'],
|
|
61
|
+
['sharedpref', 'pinvault_vault_files.xml'],
|
|
62
|
+
];
|
|
63
|
+
const OWN_RULES = {
|
|
64
|
+
'android:fullBackupContent': '@xml/pinvault_backup_rules',
|
|
65
|
+
'android:dataExtractionRules': '@xml/pinvault_data_extraction_rules',
|
|
66
|
+
};
|
|
67
|
+
const MERGED_PREFIX = 'pinvault_merged_';
|
|
68
|
+
const MERGED_FROM = /<!-- pinvault-merged-from: @xml\/([A-Za-z0-9_]+) -->/;
|
|
44
69
|
const KNOWN_OPTIONS = [
|
|
45
70
|
'nativeSecurityFile',
|
|
46
71
|
'faceIDPermission',
|
|
@@ -159,6 +184,136 @@ function applyAndroidManifest(manifest, props) {
|
|
|
159
184
|
return manifest;
|
|
160
185
|
}
|
|
161
186
|
|
|
187
|
+
/** Whether an `<include>` list (empty = everything) takes in [domain]/[file]. */
|
|
188
|
+
function included(includes, domain, file) {
|
|
189
|
+
if (includes.length === 0) return true;
|
|
190
|
+
return includes.some((i) => {
|
|
191
|
+
const d = i.$ && i.$.domain;
|
|
192
|
+
const p = String((i.$ && i.$.path) || '.').replace(/^\.\/?/, '').replace(/\/$/, '');
|
|
193
|
+
return d === domain && (p === '' || file === p || file.startsWith(`${p}/`));
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Adds PinVault's excludes to one rules element (a parsed `<full-backup-content>`
|
|
199
|
+
* or a section). Only where the element's includes reach: lint refuses an
|
|
200
|
+
* exclude outside every include (FullBackupContent), and such a file is not
|
|
201
|
+
* backed up anyway.
|
|
202
|
+
*/
|
|
203
|
+
function addExcludes(node) {
|
|
204
|
+
const out = node && typeof node === 'object' ? node : {};
|
|
205
|
+
const includes = Array.isArray(out.include) ? out.include : [];
|
|
206
|
+
out.exclude = Array.isArray(out.exclude) ? out.exclude : [];
|
|
207
|
+
for (const [domain, file] of BACKUP_EXCLUDES) {
|
|
208
|
+
if (!included(includes, domain, file)) continue;
|
|
209
|
+
if (!out.exclude.some((e) => e.$ && e.$.domain === domain && e.$.path === file)) {
|
|
210
|
+
out.exclude.push({ $: { domain, path: file } });
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return out;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* An app's backup rules (parsed with XML.parseXMLAsync) with PinVault's
|
|
218
|
+
* excludes added. Excludes win over includes, so an app that includes
|
|
219
|
+
* `sharedpref/.` still keeps PinVault's stores out. A data-extraction section
|
|
220
|
+
* the app does not write (= everything) gets one with PinVault's excludes.
|
|
221
|
+
*/
|
|
222
|
+
function mergeBackupRules(xml) {
|
|
223
|
+
if (xml && 'full-backup-content' in xml) {
|
|
224
|
+
return { 'full-backup-content': addExcludes(xml['full-backup-content']) };
|
|
225
|
+
}
|
|
226
|
+
if (xml && 'data-extraction-rules' in xml) {
|
|
227
|
+
const root = xml['data-extraction-rules'] && typeof xml['data-extraction-rules'] === 'object' ? xml['data-extraction-rules'] : {};
|
|
228
|
+
for (const section of ['cloud-backup', 'device-transfer']) {
|
|
229
|
+
root[section] = (Array.isArray(root[section]) ? root[section] : [{}]).map(addExcludes);
|
|
230
|
+
}
|
|
231
|
+
if (Array.isArray(root['cross-platform-transfer'])) root['cross-platform-transfer'] = root['cross-platform-transfer'].map(addExcludes);
|
|
232
|
+
return { 'data-extraction-rules': root };
|
|
233
|
+
}
|
|
234
|
+
throw new Error(`[${pkg.name}] backup rules file has neither <full-backup-content> nor <data-extraction-rules>`);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/** `res/xml/<name>.xml` of the app, or of a library under node_modules (Expo modules ship theirs there). */
|
|
238
|
+
function findRulesFile(projectRoot, platformRoot, name) {
|
|
239
|
+
const file = path.join('android', 'src', 'main', 'res', 'xml', `${name}.xml`);
|
|
240
|
+
const candidates = [path.join(platformRoot, 'app', 'src', 'main', 'res', 'xml', `${name}.xml`)];
|
|
241
|
+
// node_modules of the project and its parents (monorepos hoist packages up).
|
|
242
|
+
for (let dir = path.resolve(projectRoot); ; dir = path.dirname(dir)) {
|
|
243
|
+
const modules = path.join(dir, 'node_modules');
|
|
244
|
+
if (fs.existsSync(modules)) {
|
|
245
|
+
for (const entry of fs.readdirSync(modules)) {
|
|
246
|
+
if (entry.startsWith('@')) {
|
|
247
|
+
for (const scoped of fs.readdirSync(path.join(modules, entry))) candidates.push(path.join(modules, entry, scoped, file));
|
|
248
|
+
} else {
|
|
249
|
+
candidates.push(path.join(modules, entry, file));
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
if (path.dirname(dir) === dir) break;
|
|
254
|
+
}
|
|
255
|
+
return candidates.find((c) => fs.existsSync(c));
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* AndroidManifest.xml on disk, after every other plugin: an app (or a plugin
|
|
260
|
+
* such as expo-secure-store) that sets its own `fullBackupContent` /
|
|
261
|
+
* `dataExtractionRules` clashed with PinVault's at the manifest merge, and a
|
|
262
|
+
* hand-written `tools:replace` would drop PinVault's excludes. Each such file
|
|
263
|
+
* is copied to `res/xml/pinvault_merged_<name>.xml` with PinVault's excludes
|
|
264
|
+
* added, and the manifest points at the copy with `tools:replace`. Idempotent:
|
|
265
|
+
* a rerun without --clean merges from the original again.
|
|
266
|
+
*/
|
|
267
|
+
async function mergeAndroidBackupRules(projectRoot, platformRoot) {
|
|
268
|
+
const manifestPath = path.join(platformRoot, 'app', 'src', 'main', 'AndroidManifest.xml');
|
|
269
|
+
const manifest = await XML.readXMLAsync({ path: manifestPath });
|
|
270
|
+
const app = AndroidConfig.Manifest.getMainApplicationOrThrow(manifest);
|
|
271
|
+
const resDir = path.join(platformRoot, 'app', 'src', 'main', 'res', 'xml');
|
|
272
|
+
const replace = new Set(String(app.$['tools:replace'] || '').split(',').map((s) => s.trim()).filter(Boolean));
|
|
273
|
+
let changed = false;
|
|
274
|
+
for (const attr of Object.keys(OWN_RULES)) {
|
|
275
|
+
const value = app.$[attr];
|
|
276
|
+
if (value === undefined || value === OWN_RULES[attr]) continue;
|
|
277
|
+
// fullBackupContent="false": no full backup at all, stricter than PinVault's rules.
|
|
278
|
+
if (attr === 'android:fullBackupContent' && value === 'false') {
|
|
279
|
+
if (!replace.has(attr)) { replace.add(attr); changed = true; }
|
|
280
|
+
continue;
|
|
281
|
+
}
|
|
282
|
+
const ref = /^@xml\/([A-Za-z0-9_]+)$/.exec(value);
|
|
283
|
+
if (!ref) throw new Error(`[${pkg.name}] ${attr}="${value}" is not an @xml resource; merge PinVault's backup excludes by hand (README, "Expo")`);
|
|
284
|
+
let name = ref[1];
|
|
285
|
+
if (name.startsWith(MERGED_PREFIX)) {
|
|
286
|
+
const previous = path.join(resDir, `${name}.xml`);
|
|
287
|
+
const from = fs.existsSync(previous) ? MERGED_FROM.exec(fs.readFileSync(previous, 'utf8')) : null;
|
|
288
|
+
if (!from) throw new Error(`[${pkg.name}] ${previous} is missing or not ours; run expo prebuild --clean`);
|
|
289
|
+
name = from[1];
|
|
290
|
+
}
|
|
291
|
+
const source = findRulesFile(projectRoot, platformRoot, name);
|
|
292
|
+
if (!source) {
|
|
293
|
+
throw new Error(`[${pkg.name}] ${attr} points at @xml/${name}, which was not found in the app or node_modules; ` +
|
|
294
|
+
"PinVault's backup excludes cannot be merged into it (README, \"Expo\")");
|
|
295
|
+
}
|
|
296
|
+
const merged = mergeBackupRules(await XML.parseXMLAsync(fs.readFileSync(source, 'utf8')));
|
|
297
|
+
const out = `${MERGED_PREFIX}${name}`;
|
|
298
|
+
fs.mkdirSync(resDir, { recursive: true });
|
|
299
|
+
fs.writeFileSync(
|
|
300
|
+
path.join(resDir, `${out}.xml`),
|
|
301
|
+
'<?xml version="1.0" encoding="utf-8"?>\n' +
|
|
302
|
+
`<!-- pinvault-merged-from: @xml/${name} -->\n` +
|
|
303
|
+
`<!-- Written by ${pkg.name} at expo prebuild: these rules plus PinVault's excludes. -->\n` +
|
|
304
|
+
XML.format(merged) + '\n'
|
|
305
|
+
);
|
|
306
|
+
app.$[attr] = `@xml/${out}`;
|
|
307
|
+
replace.add(attr);
|
|
308
|
+
changed = true;
|
|
309
|
+
}
|
|
310
|
+
if (!changed) return false;
|
|
311
|
+
manifest.manifest.$['xmlns:tools'] = manifest.manifest.$['xmlns:tools'] || 'http://schemas.android.com/tools';
|
|
312
|
+
app.$['tools:replace'] = [...replace].join(',');
|
|
313
|
+
await XML.writeXMLAsync({ path: manifestPath, xml: manifest });
|
|
314
|
+
return true;
|
|
315
|
+
}
|
|
316
|
+
|
|
162
317
|
function withPinVault(config, options) {
|
|
163
318
|
const props = checkOptions(options);
|
|
164
319
|
|
|
@@ -189,6 +344,15 @@ function withPinVault(config, options) {
|
|
|
189
344
|
return c;
|
|
190
345
|
});
|
|
191
346
|
|
|
347
|
+
// Last of all: other plugins have written their backup rules by then.
|
|
348
|
+
config = withFinalizedMod(config, [
|
|
349
|
+
'android',
|
|
350
|
+
async (c) => {
|
|
351
|
+
await mergeAndroidBackupRules(c.modRequest.projectRoot, c.modRequest.platformProjectRoot);
|
|
352
|
+
return c;
|
|
353
|
+
},
|
|
354
|
+
]);
|
|
355
|
+
|
|
192
356
|
if (props.backgroundUpdates) {
|
|
193
357
|
config = withAppDelegate(config, (c) => {
|
|
194
358
|
c.modResults.contents = addBackgroundTaskToAppDelegate(c.modResults.contents, c.modResults.language);
|
|
@@ -229,4 +393,7 @@ function withPinVault(config, options) {
|
|
|
229
393
|
}
|
|
230
394
|
|
|
231
395
|
module.exports = createRunOncePlugin(withPinVault, pkg.name, pkg.version);
|
|
232
|
-
module.exports.internal = {
|
|
396
|
+
module.exports.internal = {
|
|
397
|
+
addBackgroundTaskToAppDelegate, applyInfoPlist, applyAndroidManifest, checkOptions, versionLess,
|
|
398
|
+
mergeBackupRules, mergeAndroidBackupRules, BACKUP_EXCLUDES,
|
|
399
|
+
};
|
package/src/types.ts
CHANGED
|
@@ -114,6 +114,11 @@ export type PinVaultConfig = {
|
|
|
114
114
|
requireUnlockedDevice?: boolean;
|
|
115
115
|
requireHardwareBackedKeys?: boolean;
|
|
116
116
|
managedTrustRoots?: boolean;
|
|
117
|
+
/**
|
|
118
|
+
* Android only: the SHA-256 digests of the signing certificates the app must be
|
|
119
|
+
* signed with. iOS has no signer digest and ignores this; set `ios.expectedBundleIds`
|
|
120
|
+
* and `ios.expectedTeamIds` there.
|
|
121
|
+
*/
|
|
117
122
|
expectedSignerSha256?: string[];
|
|
118
123
|
environmentGuard?: EnvironmentGuard;
|
|
119
124
|
/** How long the native side waits for `environmentGuard` (ms, 100–30000, default 5000). */
|
|
@@ -144,7 +149,9 @@ export type PinVaultConfig = {
|
|
|
144
149
|
ios?: {
|
|
145
150
|
/** `resolve(host:to:)`: connect to `address` while pinning and verifying `host`. */
|
|
146
151
|
resolve?: Record<string, string>;
|
|
152
|
+
/** The bundle ids the app must run as (iOS counterpart of `expectedSignerSha256`). */
|
|
147
153
|
expectedBundleIds?: string[];
|
|
154
|
+
/** The Apple team ids the app must be signed by (iOS counterpart of `expectedSignerSha256`). */
|
|
148
155
|
expectedTeamIds?: string[];
|
|
149
156
|
/** `userAuthStrength(_:)`; `BIOMETRIC_CURRENT_SET` = `userAuthBiometricOnly()`. */
|
|
150
157
|
userAuthStrength?: 'DEVICE_OWNER' | 'BIOMETRIC_CURRENT_SET';
|