@advenue/react-native 0.8.0 → 1.0.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/README.md +8 -7
- package/android/src/main/java/expo/modules/advenue/AdvenueAndroidModule.kt +118 -347
- package/android/src/main/kotlin/io/advenue/Advenue.kt +549 -0
- package/android/src/main/kotlin/io/advenue/AdvenueConfig.kt +114 -0
- package/android/src/main/kotlin/io/advenue/core/Backoff.kt +28 -0
- package/android/src/main/kotlin/io/advenue/core/ClientEvent.kt +136 -0
- package/android/src/main/kotlin/io/advenue/core/CommandPipe.kt +186 -0
- package/android/src/main/kotlin/io/advenue/core/Consent.kt +52 -0
- package/android/src/main/kotlin/io/advenue/core/Contracts.kt +80 -0
- package/android/src/main/kotlin/io/advenue/core/Conversion.kt +69 -0
- package/android/src/main/kotlin/io/advenue/core/Engine.kt +414 -0
- package/android/src/main/kotlin/io/advenue/core/EventQueue.kt +89 -0
- package/android/src/main/kotlin/io/advenue/core/HmacSigner.kt +31 -0
- package/android/src/main/kotlin/io/advenue/core/InstallReferrer.kt +146 -0
- package/android/src/main/kotlin/io/advenue/core/Json.kt +272 -0
- package/android/src/main/kotlin/io/advenue/core/Limits.kt +47 -0
- package/android/src/main/kotlin/io/advenue/core/MetaReferrer.kt +80 -0
- package/android/src/main/kotlin/io/advenue/core/SessionTracker.kt +189 -0
- package/android/src/main/kotlin/io/advenue/core/SystemServices.kt +58 -0
- package/android/src/main/kotlin/io/advenue/core/Tcf.kt +48 -0
- package/android/src/main/kotlin/io/advenue/core/Time.kt +56 -0
- package/android/src/main/kotlin/io/advenue/platform/Collectors.kt +149 -0
- package/android/src/main/kotlin/io/advenue/platform/CompositeStore.kt +33 -0
- package/android/src/main/kotlin/io/advenue/platform/ConversionFetcher.kt +68 -0
- package/android/src/main/kotlin/io/advenue/platform/ForegroundTracker.kt +90 -0
- package/android/src/main/kotlin/io/advenue/platform/HttpUrlTransport.kt +101 -0
- package/android/src/main/kotlin/io/advenue/platform/Identity.kt +79 -0
- package/android/src/main/kotlin/io/advenue/platform/InstallEnrichment.kt +197 -0
- package/android/src/main/kotlin/io/advenue/platform/InstallScopedStore.kt +91 -0
- package/android/src/main/kotlin/io/advenue/platform/LifecycleBridge.kt +72 -0
- package/android/src/main/kotlin/io/advenue/platform/PreferencesStore.kt +32 -0
- package/android/src/main/kotlin/io/advenue/plugin/Contracts.kt +67 -0
- package/android/src/main/kotlin/io/advenue/plugin/FirebaseAppInstanceIdSource.kt +73 -0
- package/android/src/main/kotlin/io/advenue/plugin/PlayAdvertisingIdSource.kt +47 -0
- package/android/src/main/kotlin/io/advenue/plugin/PlayInstallReferrerSource.kt +85 -0
- package/android/src/main/kotlin/io/advenue/plugin/PlayIntegritySource.kt +86 -0
- package/android/src/main/kotlin/io/advenue/plugin/PluginRegistry.kt +61 -0
- package/dist/index.cjs +183 -655
- package/dist/index.d.cts +199 -331
- package/dist/index.d.ts +199 -331
- package/dist/index.js +182 -661
- package/ios/AdvenueIosModule.swift +144 -432
- package/ios/vendor/Advenue/Advenue.swift +596 -0
- package/ios/vendor/Advenue/AdvenueConfig.swift +77 -0
- package/ios/vendor/AdvenueCore/AdvenueValue.swift +103 -0
- package/ios/vendor/AdvenueCore/Attestation.swift +52 -0
- package/ios/vendor/AdvenueCore/Backoff.swift +28 -0
- package/ios/vendor/AdvenueCore/ClientEvent.swift +154 -0
- package/ios/vendor/AdvenueCore/Consent.swift +40 -0
- package/ios/vendor/AdvenueCore/Contracts.swift +59 -0
- package/ios/vendor/AdvenueCore/Conversion.swift +74 -0
- package/ios/vendor/AdvenueCore/ConversionValue.swift +217 -0
- package/ios/vendor/AdvenueCore/Engine.swift +587 -0
- package/ios/vendor/AdvenueCore/EventQueue.swift +89 -0
- package/ios/vendor/AdvenueCore/Limits.swift +41 -0
- package/ios/vendor/AdvenueCore/PIIScrub.swift +102 -0
- package/ios/vendor/AdvenueCore/SessionTracker.swift +139 -0
- package/ios/vendor/AdvenueCore/SkanConfig.swift +76 -0
- package/ios/vendor/AdvenueCore/SkanReporter.swift +25 -0
- package/ios/vendor/AdvenueCore/SkanState.swift +258 -0
- package/ios/vendor/AdvenueCore/Tcf.swift +48 -0
- package/ios/vendor/AdvenueCore/Transport.swift +14 -0
- package/ios/vendor/AdvenueFirebase/FirebaseAppInstanceId.swift +33 -0
- package/ios/vendor/AdvenuePlatform/AdvertisingIdentity.swift +87 -0
- package/ios/vendor/AdvenuePlatform/ChallengeFetcher.swift +42 -0
- package/ios/vendor/AdvenuePlatform/ConversionFetcher.swift +63 -0
- package/ios/vendor/AdvenuePlatform/CryptoKitSigner.swift +19 -0
- package/ios/vendor/AdvenuePlatform/DeviceCheckAttestation.swift +91 -0
- package/ios/vendor/AdvenuePlatform/DeviceInfo.swift +65 -0
- package/ios/vendor/AdvenuePlatform/ForegroundTracker.swift +55 -0
- package/ios/vendor/AdvenuePlatform/HttpTransport.swift +96 -0
- package/ios/vendor/AdvenuePlatform/Identity.swift +52 -0
- package/ios/vendor/AdvenuePlatform/InstallEnrichment.swift +143 -0
- package/ios/vendor/AdvenuePlatform/KeychainStore.swift +95 -0
- package/ios/vendor/AdvenuePlatform/SearchAdsToken.swift +76 -0
- package/ios/vendor/AdvenuePlatform/SkanConfigFetcher.swift +70 -0
- package/ios/vendor/AdvenuePlatform/StoreKitSkanReporter.swift +140 -0
- package/ios/vendor/AdvenuePlatform/SystemServices.swift +55 -0
- package/ios/vendor/AdvenuePlatform/TcfReader.swift +18 -0
- package/ios/vendor/AdvenuePlatform/UserDefaultsStore.swift +26 -0
- package/package.json +9 -11
- package/scripts/check-dist.mjs +17 -0
- package/scripts/check-vendored-swift.mjs +148 -0
- package/scripts/vendor-natives.mjs +149 -0
- package/scripts/vendor-natives.test.mjs +112 -0
- package/src/deep-links.ts +19 -1
- package/src/index.ts +267 -803
- package/src/native-types.ts +74 -171
- package/src/native.ts +0 -23
- package/src/types.ts +81 -0
- package/src/aem.ts +0 -33
- package/src/mmkv-storage.ts +0 -21
- package/src/native-storage.ts +0 -63
- package/src/secure-store.ts +0 -26
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
package io.advenue.plugin
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.content.pm.PackageManager
|
|
5
|
+
import com.google.android.play.core.integrity.IntegrityManagerFactory
|
|
6
|
+
import com.google.android.play.core.integrity.StandardIntegrityManager.PrepareIntegrityTokenRequest
|
|
7
|
+
import com.google.android.play.core.integrity.StandardIntegrityManager.StandardIntegrityTokenProvider
|
|
8
|
+
import com.google.android.play.core.integrity.StandardIntegrityManager.StandardIntegrityTokenRequest
|
|
9
|
+
import com.google.android.gms.tasks.Tasks
|
|
10
|
+
import java.util.concurrent.TimeUnit
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Play Integrity Standard API — device attestation.
|
|
14
|
+
*
|
|
15
|
+
* The token provider is warmed once, because preparing it is the slow half and
|
|
16
|
+
* doing it per request would put seconds on the install path.
|
|
17
|
+
*
|
|
18
|
+
* The Google Cloud project number comes from the app's manifest:
|
|
19
|
+
* ```xml
|
|
20
|
+
* <meta-data android:name="io.advenue.INTEGRITY_CLOUD_PROJECT_NUMBER"
|
|
21
|
+
* android:value="123456789012" />
|
|
22
|
+
* ```
|
|
23
|
+
* Read as a long **and** as a string, because Android stores a large
|
|
24
|
+
* `android:value` as a String — reading only one of the two makes the feature
|
|
25
|
+
* silently unavailable for most projects.
|
|
26
|
+
*/
|
|
27
|
+
public class PlayIntegritySource : AttestationSource {
|
|
28
|
+
@Volatile private var provider: StandardIntegrityTokenProvider? = null
|
|
29
|
+
@Volatile private var warmed = false
|
|
30
|
+
|
|
31
|
+
override fun token(context: Context, requestHash: String): String? {
|
|
32
|
+
val app = context.applicationContext
|
|
33
|
+
warm(app)
|
|
34
|
+
val provider = this.provider ?: return null
|
|
35
|
+
|
|
36
|
+
return runCatching {
|
|
37
|
+
Tasks.await(
|
|
38
|
+
provider.request(
|
|
39
|
+
StandardIntegrityTokenRequest.builder().setRequestHash(requestHash).build(),
|
|
40
|
+
),
|
|
41
|
+
10,
|
|
42
|
+
TimeUnit.SECONDS,
|
|
43
|
+
)
|
|
44
|
+
.token()
|
|
45
|
+
}
|
|
46
|
+
.getOrNull()
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
private fun warm(context: Context) {
|
|
50
|
+
if (warmed) return
|
|
51
|
+
warmed = true
|
|
52
|
+
val projectNumber = cloudProjectNumber(context)
|
|
53
|
+
// Zero means the app never configured it — a different situation from Play
|
|
54
|
+
// Integrity being unavailable, and the two need different answers from
|
|
55
|
+
// support. Neither is an error here: attestation is best-effort and the
|
|
56
|
+
// install proceeds without it.
|
|
57
|
+
if (projectNumber == 0L) return
|
|
58
|
+
|
|
59
|
+
runCatching {
|
|
60
|
+
val manager = IntegrityManagerFactory.createStandard(context)
|
|
61
|
+
provider =
|
|
62
|
+
Tasks.await(
|
|
63
|
+
manager.prepareIntegrityToken(
|
|
64
|
+
PrepareIntegrityTokenRequest.builder().setCloudProjectNumber(projectNumber).build(),
|
|
65
|
+
),
|
|
66
|
+
15,
|
|
67
|
+
TimeUnit.SECONDS,
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
private fun cloudProjectNumber(context: Context): Long =
|
|
73
|
+
runCatching {
|
|
74
|
+
val info =
|
|
75
|
+
context.packageManager.getApplicationInfo(context.packageName, PackageManager.GET_META_DATA)
|
|
76
|
+
val meta = info.metaData ?: return 0L
|
|
77
|
+
meta.getLong(META_KEY, 0L).takeIf { it != 0L }
|
|
78
|
+
?: meta.getString(META_KEY)?.toLongOrNull()
|
|
79
|
+
?: 0L
|
|
80
|
+
}
|
|
81
|
+
.getOrDefault(0L)
|
|
82
|
+
|
|
83
|
+
private companion object {
|
|
84
|
+
private const val META_KEY = "io.advenue.INTEGRITY_CLOUD_PROJECT_NUMBER"
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
package io.advenue.plugin
|
|
2
|
+
|
|
3
|
+
import java.util.concurrent.ConcurrentHashMap
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Resolves a plugin's entry class by fixed name, once, at initialisation.
|
|
7
|
+
*
|
|
8
|
+
* The consumer adds a Gradle line and writes nothing else, which is how Adjust's
|
|
9
|
+
* ten plugins work — `sdk-core/src/main/java/com/adjust/sdk/Reflection.java`
|
|
10
|
+
* resolves them the same way.
|
|
11
|
+
*
|
|
12
|
+
* **This is not the rejected "compileOnly plus reflection" shape.** There,
|
|
13
|
+
* reflection wrapped every vendor API call and every one of them was untyped.
|
|
14
|
+
* Here there is one lookup of *our own* class, at init, and the resolved class
|
|
15
|
+
* then talks to its dependency with ordinary compile-time typing.
|
|
16
|
+
*
|
|
17
|
+
* **ServiceLoader was considered and rejected.** It is the JVM standard and R8
|
|
18
|
+
* understands it, but its registration lives in a `META-INF/services` resource,
|
|
19
|
+
* which jar merging and aggressive shrinkers drop silently. A silently absent
|
|
20
|
+
* referrer plugin is an attribution outage that looks like organic traffic — the
|
|
21
|
+
* worst failure shape available. A missing class is detectable, and one
|
|
22
|
+
* `consumerProguardFiles` rule keeps it.
|
|
23
|
+
*/
|
|
24
|
+
public object PluginRegistry {
|
|
25
|
+
public const val PLAY_REFERRER: String = "io.advenue.plugin.PlayInstallReferrerSource"
|
|
26
|
+
public const val PLAY_IDENTITY: String = "io.advenue.plugin.PlayAdvertisingIdSource"
|
|
27
|
+
public const val PLAY_INTEGRITY: String = "io.advenue.plugin.PlayIntegritySource"
|
|
28
|
+
public const val FIREBASE: String = "io.advenue.plugin.FirebaseAppInstanceIdSource"
|
|
29
|
+
|
|
30
|
+
private val cache = ConcurrentHashMap<String, Any>()
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* The plugin at [className], or null when the artifact is not on the
|
|
34
|
+
* classpath — which is the ordinary case, not an error.
|
|
35
|
+
*
|
|
36
|
+
* A class that exists but does not implement the contract is a packaging
|
|
37
|
+
* mistake, and it degrades to "no plugin" rather than taking the host app
|
|
38
|
+
* down: an SDK that throws during `initialize` crashes an app that merely
|
|
39
|
+
* mis-declared a dependency.
|
|
40
|
+
*/
|
|
41
|
+
@Suppress("UNCHECKED_CAST")
|
|
42
|
+
public inline fun <reified T : Any> load(className: String): T? = loadAs(className, T::class.java)
|
|
43
|
+
|
|
44
|
+
@PublishedApi
|
|
45
|
+
internal fun <T : Any> loadAs(className: String, type: Class<T>): T? {
|
|
46
|
+
cache[className]?.let { return if (type.isInstance(it)) type.cast(it) else null }
|
|
47
|
+
return try {
|
|
48
|
+
val loaded = Class.forName(className).getDeclaredConstructor().newInstance()
|
|
49
|
+
if (!type.isInstance(loaded)) return null
|
|
50
|
+
cache[className] = loaded
|
|
51
|
+
type.cast(loaded)
|
|
52
|
+
} catch (_: Throwable) {
|
|
53
|
+
null
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Test surface: forget what was resolved, so a test can vary the classpath. */
|
|
58
|
+
internal fun reset() {
|
|
59
|
+
cache.clear()
|
|
60
|
+
}
|
|
61
|
+
}
|