feat(privacy): add per-account toggle to disable NIP-89 client tag
Adds a "Don't add client tag to my events" switch under Security Filters. NostrSignerWithClientTag now consults a runtime predicate at sign-time, so the toggle takes effect immediately on the live session without rewrapping the signer or rebuilding Account. https://claude.ai/code/session_01KhNVTm8LLdVphqyxVkZtDS
This commit is contained in:
@@ -95,6 +95,7 @@ private object PrefKeys {
|
|||||||
const val LOCAL_RELAY_SERVERS = "localRelayServers"
|
const val LOCAL_RELAY_SERVERS = "localRelayServers"
|
||||||
const val DEFAULT_FILE_SERVER = "defaultFileServer"
|
const val DEFAULT_FILE_SERVER = "defaultFileServer"
|
||||||
const val STRIP_LOCATION_ON_UPLOAD = "stripLocationOnUpload"
|
const val STRIP_LOCATION_ON_UPLOAD = "stripLocationOnUpload"
|
||||||
|
const val DISABLE_CLIENT_TAG = "disableClientTag"
|
||||||
const val DEFAULT_HOME_FOLLOW_LIST = "defaultHomeFollowList"
|
const val DEFAULT_HOME_FOLLOW_LIST = "defaultHomeFollowList"
|
||||||
const val DEFAULT_STORIES_FOLLOW_LIST = "defaultStoriesFollowList"
|
const val DEFAULT_STORIES_FOLLOW_LIST = "defaultStoriesFollowList"
|
||||||
const val DEFAULT_NOTIFICATION_FOLLOW_LIST = "defaultNotificationFollowList"
|
const val DEFAULT_NOTIFICATION_FOLLOW_LIST = "defaultNotificationFollowList"
|
||||||
@@ -346,6 +347,7 @@ object LocalPreferences {
|
|||||||
)
|
)
|
||||||
|
|
||||||
putBoolean(PrefKeys.STRIP_LOCATION_ON_UPLOAD, settings.stripLocationOnUpload)
|
putBoolean(PrefKeys.STRIP_LOCATION_ON_UPLOAD, settings.stripLocationOnUpload)
|
||||||
|
putBoolean(PrefKeys.DISABLE_CLIENT_TAG, settings.disableClientTag)
|
||||||
|
|
||||||
putString(PrefKeys.DEFAULT_HOME_FOLLOW_LIST, JsonMapper.toJson(settings.defaultHomeFollowList.value))
|
putString(PrefKeys.DEFAULT_HOME_FOLLOW_LIST, JsonMapper.toJson(settings.defaultHomeFollowList.value))
|
||||||
putString(PrefKeys.DEFAULT_STORIES_FOLLOW_LIST, JsonMapper.toJson(settings.defaultStoriesFollowList.value))
|
putString(PrefKeys.DEFAULT_STORIES_FOLLOW_LIST, JsonMapper.toJson(settings.defaultStoriesFollowList.value))
|
||||||
@@ -513,6 +515,7 @@ object LocalPreferences {
|
|||||||
Log.d("LocalPreferences") { "Load account from file $npub - keys ready" }
|
Log.d("LocalPreferences") { "Load account from file $npub - keys ready" }
|
||||||
|
|
||||||
val stripLocationOnUpload = getBoolean(PrefKeys.STRIP_LOCATION_ON_UPLOAD, true)
|
val stripLocationOnUpload = getBoolean(PrefKeys.STRIP_LOCATION_ON_UPLOAD, true)
|
||||||
|
val disableClientTag = getBoolean(PrefKeys.DISABLE_CLIENT_TAG, false)
|
||||||
val hideDeleteRequestDialog = getBoolean(PrefKeys.HIDE_DELETE_REQUEST_DIALOG, false)
|
val hideDeleteRequestDialog = getBoolean(PrefKeys.HIDE_DELETE_REQUEST_DIALOG, false)
|
||||||
val hideBlockAlertDialog = getBoolean(PrefKeys.HIDE_BLOCK_ALERT_DIALOG, false)
|
val hideBlockAlertDialog = getBoolean(PrefKeys.HIDE_BLOCK_ALERT_DIALOG, false)
|
||||||
val hideNIP17WarningDialog = getBoolean(PrefKeys.HIDE_NIP_17_WARNING_DIALOG, false)
|
val hideNIP17WarningDialog = getBoolean(PrefKeys.HIDE_NIP_17_WARNING_DIALOG, false)
|
||||||
@@ -620,6 +623,7 @@ object LocalPreferences {
|
|||||||
localRelayServers = MutableStateFlow(localRelayServers),
|
localRelayServers = MutableStateFlow(localRelayServers),
|
||||||
defaultFileServer = defaultFileServer.await(),
|
defaultFileServer = defaultFileServer.await(),
|
||||||
stripLocationOnUpload = stripLocationOnUpload,
|
stripLocationOnUpload = stripLocationOnUpload,
|
||||||
|
disableClientTag = disableClientTag,
|
||||||
defaultHomeFollowList = MutableStateFlow(followListPrefs.home),
|
defaultHomeFollowList = MutableStateFlow(followListPrefs.home),
|
||||||
defaultStoriesFollowList = MutableStateFlow(followListPrefs.stories),
|
defaultStoriesFollowList = MutableStateFlow(followListPrefs.stories),
|
||||||
defaultNotificationFollowList = MutableStateFlow(followListPrefs.notification),
|
defaultNotificationFollowList = MutableStateFlow(followListPrefs.notification),
|
||||||
|
|||||||
@@ -149,6 +149,7 @@ class AccountSettings(
|
|||||||
var localRelayServers: MutableStateFlow<Set<String>> = MutableStateFlow(setOf()),
|
var localRelayServers: MutableStateFlow<Set<String>> = MutableStateFlow(setOf()),
|
||||||
var defaultFileServer: ServerName = DEFAULT_MEDIA_SERVERS[0],
|
var defaultFileServer: ServerName = DEFAULT_MEDIA_SERVERS[0],
|
||||||
var stripLocationOnUpload: Boolean = true,
|
var stripLocationOnUpload: Boolean = true,
|
||||||
|
var disableClientTag: Boolean = false,
|
||||||
val defaultHomeFollowList: MutableStateFlow<TopFilter> = MutableStateFlow(TopFilter.AllFollows),
|
val defaultHomeFollowList: MutableStateFlow<TopFilter> = MutableStateFlow(TopFilter.AllFollows),
|
||||||
val defaultStoriesFollowList: MutableStateFlow<TopFilter> = MutableStateFlow(TopFilter.Global),
|
val defaultStoriesFollowList: MutableStateFlow<TopFilter> = MutableStateFlow(TopFilter.Global),
|
||||||
val defaultNotificationFollowList: MutableStateFlow<TopFilter> = MutableStateFlow(TopFilter.Global),
|
val defaultNotificationFollowList: MutableStateFlow<TopFilter> = MutableStateFlow(TopFilter.Global),
|
||||||
@@ -403,6 +404,13 @@ class AccountSettings(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun changeDisableClientTag(disable: Boolean) {
|
||||||
|
if (disableClientTag != disable) {
|
||||||
|
disableClientTag = disable
|
||||||
|
saveAccountSettings()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ---
|
// ---
|
||||||
// list names
|
// list names
|
||||||
// ---
|
// ---
|
||||||
|
|||||||
+6
-1
@@ -135,7 +135,12 @@ class AccountCacheState(
|
|||||||
val cached = accounts.value[signer.pubKey]
|
val cached = accounts.value[signer.pubKey]
|
||||||
if (cached != null) return cached
|
if (cached != null) return cached
|
||||||
|
|
||||||
val signerWithClientTag = NostrSignerWithClientTag(signer, CLIENT_TAG_NAME)
|
val signerWithClientTag =
|
||||||
|
NostrSignerWithClientTag(
|
||||||
|
inner = signer,
|
||||||
|
clientName = CLIENT_TAG_NAME,
|
||||||
|
disabled = { accountSettings.disableClientTag },
|
||||||
|
)
|
||||||
|
|
||||||
val accountDir = File(rootFilesDir(), "accounts/${signer.pubKey}").apply { mkdirs() }
|
val accountDir = File(rootFilesDir(), "accounts/${signer.pubKey}").apply { mkdirs() }
|
||||||
|
|
||||||
|
|||||||
+15
@@ -371,6 +371,21 @@ private fun HeaderOptions(accountViewModel: AccountViewModel) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SettingsRow(
|
||||||
|
R.string.disable_client_tag_title,
|
||||||
|
R.string.disable_client_tag_explainer,
|
||||||
|
) {
|
||||||
|
var disableClientTag by remember { mutableStateOf(accountViewModel.account.settings.disableClientTag) }
|
||||||
|
|
||||||
|
Switch(
|
||||||
|
checked = disableClientTag,
|
||||||
|
onCheckedChange = {
|
||||||
|
disableClientTag = it
|
||||||
|
accountViewModel.account.settings.changeDisableClientTag(it)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
SettingsRow(
|
SettingsRow(
|
||||||
R.string.show_sensitive_content_title,
|
R.string.show_sensitive_content_title,
|
||||||
R.string.show_sensitive_content_explainer,
|
R.string.show_sensitive_content_explainer,
|
||||||
|
|||||||
@@ -1172,6 +1172,8 @@
|
|||||||
|
|
||||||
<string name="filter_spam_from_strangers_title">Filter spam</string>
|
<string name="filter_spam_from_strangers_title">Filter spam</string>
|
||||||
<string name="filter_spam_from_strangers_explainer">Hides posts from strangers that were exactly the same for 5 or more times</string>
|
<string name="filter_spam_from_strangers_explainer">Hides posts from strangers that were exactly the same for 5 or more times</string>
|
||||||
|
<string name="disable_client_tag_title">Don\'t add client tag to my events</string>
|
||||||
|
<string name="disable_client_tag_explainer">When enabled, Amethyst will not append a NIP-89 client tag to events you publish.</string>
|
||||||
<string name="warn_when_posts_have_reports_from_your_follows_title">Warn on reports</string>
|
<string name="warn_when_posts_have_reports_from_your_follows_title">Warn on reports</string>
|
||||||
<string name="warn_when_posts_have_reports_from_your_follows_explainer">Shows a warning message when posts have 5 or more reports from your follows</string>
|
<string name="warn_when_posts_have_reports_from_your_follows_explainer">Shows a warning message when posts have 5 or more reports from your follows</string>
|
||||||
<string name="show_sensitive_content_title">Show sensitive content</string>
|
<string name="show_sensitive_content_title">Show sensitive content</string>
|
||||||
|
|||||||
+13
-1
@@ -40,12 +40,19 @@ import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent
|
|||||||
class NostrSignerWithClientTag(
|
class NostrSignerWithClientTag(
|
||||||
val inner: NostrSigner,
|
val inner: NostrSigner,
|
||||||
val clientTag: Array<String>,
|
val clientTag: Array<String>,
|
||||||
|
val disabled: () -> Boolean = { false },
|
||||||
) : NostrSigner(inner.pubKey) {
|
) : NostrSigner(inner.pubKey) {
|
||||||
constructor(
|
constructor(
|
||||||
inner: NostrSigner,
|
inner: NostrSigner,
|
||||||
clientName: String,
|
clientName: String,
|
||||||
) : this(inner, ClientTag.assemble(clientName))
|
) : this(inner, ClientTag.assemble(clientName))
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
inner: NostrSigner,
|
||||||
|
clientName: String,
|
||||||
|
disabled: () -> Boolean,
|
||||||
|
) : this(inner, ClientTag.assemble(clientName), disabled)
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
inner: NostrSigner,
|
inner: NostrSigner,
|
||||||
clientName: String,
|
clientName: String,
|
||||||
@@ -60,7 +67,12 @@ class NostrSignerWithClientTag(
|
|||||||
kind: Int,
|
kind: Int,
|
||||||
tags: Array<Array<String>>,
|
tags: Array<Array<String>>,
|
||||||
content: String,
|
content: String,
|
||||||
): T = inner.sign(createdAt, kind, appendClientTag(tags), content)
|
): T =
|
||||||
|
if (disabled()) {
|
||||||
|
inner.sign(createdAt, kind, tags, content)
|
||||||
|
} else {
|
||||||
|
inner.sign(createdAt, kind, appendClientTag(tags), content)
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun nip04Encrypt(
|
override suspend fun nip04Encrypt(
|
||||||
plaintext: String,
|
plaintext: String,
|
||||||
|
|||||||
Reference in New Issue
Block a user