mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-05 13:43:33 +00:00
fix(android): block self-package notification forwarding in allowlist mode (#99568)
Always reject the OpenClaw app package in allowsPackage, matching the blocklist fail-closed behavior and preventing gateway/node forwarding loops. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -27,6 +27,7 @@ internal data class NotificationForwardingPolicy(
|
||||
val quietEnd: String,
|
||||
val maxEventsPerMinute: Int,
|
||||
val sessionKey: String?,
|
||||
val selfPackageName: String = "",
|
||||
)
|
||||
|
||||
/** Applies the operator-configured package allow/block list after trimming input. */
|
||||
@@ -35,6 +36,10 @@ internal fun NotificationForwardingPolicy.allowsPackage(packageName: String): Bo
|
||||
if (normalized.isEmpty()) {
|
||||
return false
|
||||
}
|
||||
val self = selfPackageName.trim()
|
||||
if (self.isNotEmpty() && normalized == self) {
|
||||
return false
|
||||
}
|
||||
return when (mode) {
|
||||
NotificationPackageFilterMode.Allowlist -> packages.contains(normalized)
|
||||
NotificationPackageFilterMode.Blocklist -> !packages.contains(normalized)
|
||||
|
||||
@@ -313,6 +313,7 @@ class SecurePrefs(
|
||||
quietEnd = quietEnd,
|
||||
maxEventsPerMinute = maxEvents.coerceAtLeast(1),
|
||||
sessionKey = sessionKey,
|
||||
selfPackageName = normalizedAppPackage,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -77,6 +77,25 @@ class NotificationForwardingPolicyTest {
|
||||
assertFalse(policy.allowsPackage("com.other.app"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun allowsPackage_neverForwardsSelfPackageEvenInAllowlist() {
|
||||
val policy =
|
||||
NotificationForwardingPolicy(
|
||||
enabled = true,
|
||||
mode = NotificationPackageFilterMode.Allowlist,
|
||||
packages = setOf("ai.openclaw.app", "com.other.app"),
|
||||
quietHoursEnabled = false,
|
||||
quietStart = "22:00",
|
||||
quietEnd = "07:00",
|
||||
maxEventsPerMinute = 20,
|
||||
sessionKey = null,
|
||||
selfPackageName = "ai.openclaw.app",
|
||||
)
|
||||
|
||||
assertFalse(policy.allowsPackage("ai.openclaw.app"))
|
||||
assertTrue(policy.allowsPackage("com.other.app"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWithinQuietHours_handlesWindowCrossingMidnight() {
|
||||
val policy =
|
||||
|
||||
@@ -128,4 +128,20 @@ class SecurePrefsNotificationForwardingTest {
|
||||
assertFalse(policy.enabled)
|
||||
assertEquals(NotificationPackageFilterMode.Blocklist, policy.mode)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getNotificationForwardingPolicy_blocksSelfPackageInAllowlistMode() {
|
||||
val context = RuntimeEnvironment.getApplication()
|
||||
val plainPrefs = context.getSharedPreferences("openclaw.node", Context.MODE_PRIVATE)
|
||||
plainPrefs.edit().clear().commit()
|
||||
|
||||
val prefs = SecurePrefs(context)
|
||||
prefs.setNotificationForwardingMode(NotificationPackageFilterMode.Allowlist)
|
||||
prefs.setNotificationForwardingPackages(listOf("ai.openclaw.app", "com.other.app"))
|
||||
|
||||
val policy = prefs.getNotificationForwardingPolicy(appPackageName = "ai.openclaw.app")
|
||||
|
||||
assertFalse(policy.allowsPackage("ai.openclaw.app"))
|
||||
assertTrue(policy.allowsPackage("com.other.app"))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user