block creation or sending of duplicate channels. (#3913)

This commit is contained in:
Dane Evans 2025-12-06 23:47:33 +11:00 committed by GitHub
parent 499ed58311
commit 7db7f61386
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 108 additions and 9 deletions

View file

@ -89,3 +89,21 @@ fun ChannelSet.qrCode(shouldAdd: Boolean): Bitmap? = try {
Timber.e("URL was too complex to render as barcode")
null
}
/**
* Check if the ChannelSet contains any duplicate PSKs.
*
* @return true if there are duplicate PSKs, false otherwise
*/
fun ChannelSet.hasDuplicateKeys(): Boolean {
val pskList = mutableListOf<ByteArray>()
for (setting in settingsList) {
val channel = Channel(setting, loraConfig)
val pskBytes = channel.psk.toByteArray()
if (pskList.any { it contentEquals pskBytes }) {
return true
}
pskList.add(pskBytes)
}
return false
}

View file

@ -218,6 +218,7 @@
<string name="meshtastic_service_notifications">Service notifications</string>
<string name="about">About</string>
<string name="channel_invalid">This Channel URL is invalid and can not be used</string>
<string name="channel_key_already_in_use">A channel with this key is already in use</string>
<string name="contact_invalid">This contact is invalid and can not be added</string>
<string name="debug_panel">Debug Panel</string>
<string name="debug_decoded_payload">Decoded Payload:</string>

View file

@ -40,9 +40,11 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.PreviewScreenSizes
import androidx.compose.ui.unit.dp
@ -50,15 +52,19 @@ import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import kotlinx.coroutines.launch
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.model.Channel
import org.meshtastic.core.model.util.hasDuplicateKeys
import org.meshtastic.core.strings.Res
import org.meshtastic.core.strings.accept
import org.meshtastic.core.strings.add
import org.meshtastic.core.strings.cancel
import org.meshtastic.core.strings.channel_key_already_in_use
import org.meshtastic.core.strings.new_channel_rcvd
import org.meshtastic.core.strings.replace
import org.meshtastic.core.ui.component.ChannelSelection
import org.meshtastic.core.ui.util.showToast
import org.meshtastic.proto.AppOnlyProtos.ChannelSet
import org.meshtastic.proto.ConfigProtos.Config.LoRaConfig.ModemPreset
import org.meshtastic.proto.channelSet
@ -290,10 +296,16 @@ fun ScannedQrCodeDialog(
)
}
val context = LocalContext.current
val coroutineScope = rememberCoroutineScope()
TextButton(
onClick = {
onDismiss()
onConfirm(selectedChannelSet)
if (selectedChannelSet.hasDuplicateKeys()) {
coroutineScope.launch { context.showToast(Res.string.channel_key_already_in_use) }
} else {
onDismiss()
onConfirm(selectedChannelSet)
}
},
enabled = selectedChannelSet.settingsCount in 1..8,
) {