Skip to content

Commit bc64cb1

Browse files
authored
fix(scanner): open group chat invites scanned from a QR code (#1535)
Scanning an app.flipcash.com/chat/{uuid} QR code did nothing from the camera and showed "no code found" from the gallery. The router already classifies the link as a GroupChatInvite, but isScannable refused it and Scanner had no destination for it, so it fell through to an empty route list. GroupChatInvite is now scannable and opens the same destination as a tapped invite link: Sheets.Tips, then Messaging.Chat by chat id, which is the gated preview for someone who is not yet a member. Login and EmailVerification stay refused, since they carry secrets.
1 parent ee0dcb4 commit bc64cb1

3 files changed

Lines changed: 9 additions & 15 deletions

File tree

‎apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/navigation/DeeplinkType.kt‎

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,6 @@ sealed interface DeeplinkType: Parcelable {
6060
* send as a photo. A new route type is refused until someone adds it here, which is the
6161
* property an `else -> false` would not have.
6262
*
63-
* [GroupChatInvite] is false because no scan path opens one -- `Scanner`'s `Navigatable`
64-
* branch has no case for it. It is a gap named rather than a risk.
65-
*
6663
* iOS's equivalent is `ScanViewModel.canScanQR`.
6764
*/
6865
val isScannable: Boolean
@@ -72,11 +69,11 @@ sealed interface DeeplinkType: Parcelable {
7269
is TipChat,
7370
is Tipcard,
7471
is TipcardByUsername,
72+
is GroupChatInvite,
7573
-> true
7674

7775
is Login,
7876
is EmailVerification,
79-
is GroupChatInvite,
8077
-> false
8178
}
8279
}

‎apps/flipcash/core/src/test/kotlin/com/flipcash/app/core/navigation/DeeplinkScanPolicyTest.kt‎

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class DeeplinkScanPolicyTest {
2323
assertTrue(DeeplinkType.TipChat(ChatIdentifier.ByChatId(CHAT_ID)).isScannable)
2424
assertTrue(DeeplinkType.Tipcard(USER_ID).isScannable)
2525
assertTrue(DeeplinkType.TipcardByUsername(USERNAME).isScannable)
26+
assertTrue(DeeplinkType.GroupChatInvite(CHAT_ID).isScannable)
2627
}
2728

2829
@Test
@@ -31,17 +32,6 @@ class DeeplinkScanPolicyTest {
3132
assertFalse(DeeplinkType.EmailVerification(EMAIL, CODE).isScannable)
3233
}
3334

34-
/**
35-
* Not a security judgement -- an invite is harmless. It is that no scan path has ever opened
36-
* one: `Scanner`'s `Navigatable` branch has no case for it and falls to `emptyList()`. Naming
37-
* it here keeps that a stated decision rather than a gap, and flipping it means adding the
38-
* destination too.
39-
*/
40-
@Test
41-
fun `a group chat invite is not a scan destination`() {
42-
assertFalse(DeeplinkType.GroupChatInvite(CHAT_ID).isScannable)
43-
}
44-
4535
private companion object {
4636
const val ENTROPY = "0123456789abcdef"
4737
const val USERNAME = "someone"

‎apps/flipcash/features/scanner/src/main/kotlin/com/flipcash/app/scanner/internal/Scanner.kt‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
2525
import com.flipcash.app.analytics.rememberAnalytics
2626
import com.flipcash.app.core.AppRoute
2727
import com.flipcash.app.core.AppRoute.Token.*
28+
import com.flipcash.app.core.chat.ChatIdentifier
2829
import com.flipcash.app.core.extensions.navigateAll
2930
import com.flipcash.app.core.navigation.DeeplinkType
3031
import com.flipcash.app.core.tipping.TipCardOwner
@@ -119,6 +120,12 @@ internal fun Scanner() {
119120
AppRoute.Sheets.Tips(),
120121
AppRoute.Messaging.Chat(deeplink.identifier),
121122
)
123+
// Same destination as the tapped /chat/{uuid} link: the chat screen is the
124+
// gated preview when the viewer is not yet a member.
125+
is DeeplinkType.GroupChatInvite -> listOf(
126+
AppRoute.Sheets.Tips(),
127+
AppRoute.Messaging.Chat(ChatIdentifier.ByChatId(deeplink.chatId)),
128+
)
122129
else -> emptyList()
123130
}
124131
if (routes.isNotEmpty()) {

0 commit comments

Comments
 (0)