Update the way we handle push notifications (#1061)

This commit is contained in:
David Perez 2024-02-23 17:12:02 -06:00 committed by Álison Fernandes
parent 40dddf017d
commit 3febae577a
5 changed files with 113 additions and 115 deletions

View file

@ -41,7 +41,6 @@ class AuthRequestNotificationManagerImpl(
@SuppressLint("MissingPermission")
private fun handlePasswordlessRequestData(data: PasswordlessRequestData) {
val notificationManager = NotificationManagerCompat.from(context)
if (notificationManager.areNotificationsEnabled(NOTIFICATION_CHANNEL_ID)) return
// Construct the channel, calling this more than once is safe
notificationManager.createNotificationChannel(
NotificationChannelCompat
@ -52,6 +51,7 @@ class AuthRequestNotificationManagerImpl(
.setName(context.getString(R.string.pending_log_in_requests))
.build(),
)
if (!notificationManager.areNotificationsEnabled(NOTIFICATION_CHANNEL_ID)) return
// Create the notification
val builder = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
.setContentIntent(createContentIntent(data))

View file

@ -27,7 +27,6 @@ import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.decodeFromJsonElement
import java.time.Clock
import java.time.ZoneOffset
import java.time.ZonedDateTime
@ -128,7 +127,7 @@ class PushManagerImpl @Inject constructor(
-> {
if (settingsDiskSource.getApprovePasswordlessLoginsEnabled(userId) == true) {
val payload: NotificationPayload.PasswordlessRequestNotification =
json.decodeFromJsonElement(notification.payload)
json.decodeFromString(string = notification.payload)
mutablePasswordlessRequestSharedFlow.tryEmit(
PasswordlessRequestData(
loginRequestId = payload.id,
@ -140,7 +139,7 @@ class PushManagerImpl @Inject constructor(
NotificationType.LOG_OUT -> {
val payload: NotificationPayload.UserNotification =
json.decodeFromJsonElement(notification.payload)
json.decodeFromString(notification.payload)
mutableLogoutSharedFlow.tryEmit(
NotificationLogoutData(payload.userId),
)
@ -150,7 +149,7 @@ class PushManagerImpl @Inject constructor(
NotificationType.SYNC_CIPHER_UPDATE,
-> {
val payload: NotificationPayload.SyncCipherNotification =
json.decodeFromJsonElement(notification.payload)
json.decodeFromString(notification.payload)
if (!isLoggedIn(userId) || !payload.userMatchesNotification(userId)) return
mutableSyncCipherUpsertSharedFlow.tryEmit(
SyncCipherUpsertData(
@ -167,7 +166,7 @@ class PushManagerImpl @Inject constructor(
NotificationType.SYNC_LOGIN_DELETE,
-> {
val payload: NotificationPayload.SyncCipherNotification =
json.decodeFromJsonElement(notification.payload)
json.decodeFromString(notification.payload)
if (!isLoggedIn(userId) || !payload.userMatchesNotification(userId)) return
mutableSyncCipherDeleteSharedFlow.tryEmit(
SyncCipherDeleteData(payload.id),
@ -185,7 +184,7 @@ class PushManagerImpl @Inject constructor(
NotificationType.SYNC_FOLDER_UPDATE,
-> {
val payload: NotificationPayload.SyncFolderNotification =
json.decodeFromJsonElement(notification.payload)
json.decodeFromString(notification.payload)
if (!isLoggedIn(userId) || !payload.userMatchesNotification(userId)) return
mutableSyncFolderUpsertSharedFlow.tryEmit(
SyncFolderUpsertData(
@ -198,7 +197,7 @@ class PushManagerImpl @Inject constructor(
NotificationType.SYNC_FOLDER_DELETE -> {
val payload: NotificationPayload.SyncFolderNotification =
json.decodeFromJsonElement(notification.payload)
json.decodeFromString(notification.payload)
if (!isLoggedIn(userId) || !payload.userMatchesNotification(userId)) return
mutableSyncFolderDeleteSharedFlow.tryEmit(
@ -215,7 +214,7 @@ class PushManagerImpl @Inject constructor(
NotificationType.SYNC_SEND_UPDATE,
-> {
val payload: NotificationPayload.SyncSendNotification =
json.decodeFromJsonElement(notification.payload)
json.decodeFromString(notification.payload)
if (!isLoggedIn(userId) || !payload.userMatchesNotification(userId)) return
mutableSyncSendUpsertSharedFlow.tryEmit(
SyncSendUpsertData(
@ -228,7 +227,7 @@ class PushManagerImpl @Inject constructor(
NotificationType.SYNC_SEND_DELETE -> {
val payload: NotificationPayload.SyncSendNotification =
json.decodeFromJsonElement(notification.payload)
json.decodeFromString(notification.payload)
if (!isLoggedIn(userId) || !payload.userMatchesNotification(userId)) return
mutableSyncSendDeleteSharedFlow.tryEmit(
SyncSendDeleteData(payload.id),

View file

@ -2,19 +2,18 @@ package com.x8bit.bitwarden.data.platform.manager.model
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonElement
/**
* Represents a Bitwarden push notification.
*
* @property contextId The context ID. This is mainly used to check if the push notification
* originated from this app.
* @property notificationType The type of notication.
* @property notificationType The type of notification.
* @property payload Data associated with the push notification.
*/
@Serializable
data class BitwardenNotification(
@SerialName("contextId") val contextId: String,
@SerialName("contextId") val contextId: String?,
@SerialName("type") val notificationType: NotificationType,
@SerialName("payload") val payload: JsonElement,
@SerialName("payload") val payload: String,
)

View file

@ -20,12 +20,12 @@ sealed class NotificationPayload {
*/
@Serializable
data class SyncCipherNotification(
@SerialName("id") val id: String,
@SerialName("userId") override val userId: String?,
@SerialName("organizationId") val organizationId: String?,
@SerialName("collectionIds") val collectionIds: List<String>?,
@SerialName("Id") val id: String,
@SerialName("UserId") override val userId: String?,
@SerialName("OrganizationId") val organizationId: String?,
@SerialName("CollectionIds") val collectionIds: List<String>?,
@Contextual
@SerialName("revisionDate") val revisionDate: ZonedDateTime,
@SerialName("RevisionDate") val revisionDate: ZonedDateTime,
) : NotificationPayload()
/**
@ -33,10 +33,10 @@ sealed class NotificationPayload {
*/
@Serializable
data class SyncFolderNotification(
@SerialName("id") val id: String,
@SerialName("userId") override val userId: String,
@SerialName("Id") val id: String,
@SerialName("UserId") override val userId: String,
@Contextual
@SerialName("revisionDate") val revisionDate: ZonedDateTime,
@SerialName("RevisionDate") val revisionDate: ZonedDateTime,
) : NotificationPayload()
/**
@ -44,9 +44,9 @@ sealed class NotificationPayload {
*/
@Serializable
data class UserNotification(
@SerialName("userId") override val userId: String,
@SerialName("UserId") override val userId: String,
@Contextual
@SerialName("date") val date: ZonedDateTime,
@SerialName("Date") val date: ZonedDateTime,
) : NotificationPayload()
/**
@ -54,10 +54,10 @@ sealed class NotificationPayload {
*/
@Serializable
data class SyncSendNotification(
@SerialName("id") val id: String,
@SerialName("userId") override val userId: String,
@SerialName("Id") val id: String,
@SerialName("UserId") override val userId: String,
@Contextual
@SerialName("revisionDate") val revisionDate: ZonedDateTime,
@SerialName("RevisionDate") val revisionDate: ZonedDateTime,
) : NotificationPayload()
/**
@ -65,7 +65,7 @@ sealed class NotificationPayload {
*/
@Serializable
data class PasswordlessRequestNotification(
@SerialName("userId") override val userId: String,
@SerialName("id") val id: String,
@SerialName("UserId") override val userId: String,
@SerialName("Id") val id: String,
) : NotificationPayload()
}

View file

@ -844,10 +844,10 @@ private const val AUTH_REQUEST_NOTIFICATION_JSON = """
{
"contextId": "801f459d-8e51-47d0-b072-3f18c9f66f64",
"type": 15,
"payload": {
"id": "aab5cdcc-f4a7-4e65-bf6d-5e0eab052321",
"userId": "078966a2-93c2-4618-ae2a-0a2394c88d37"
}
"payload": "{
\"Id\": \"aab5cdcc-f4a7-4e65-bf6d-5e0eab052321\",
\"UserId\": \"078966a2-93c2-4618-ae2a-0a2394c88d37\"
}"
}
"""
@ -855,10 +855,10 @@ private const val AUTH_REQUEST_RESPONSE_NOTIFICATION_JSON = """
{
"contextId": "801f459d-8e51-47d0-b072-3f18c9f66f64",
"type": 16,
"payload": {
"id": "aab5cdcc-f4a7-4e65-bf6d-5e0eab052321",
"userId": "078966a2-93c2-4618-ae2a-0a2394c88d37"
}
"payload": "{
\"Id\": \"aab5cdcc-f4a7-4e65-bf6d-5e0eab052321\",
\"UserId\": \"078966a2-93c2-4618-ae2a-0a2394c88d37\"
}"
}
"""
@ -870,10 +870,10 @@ private const val LOGOUT_NOTIFICATION_JSON = """
{
"contextId": "801f459d-8e51-47d0-b072-3f18c9f66f64",
"type": 11,
"payload": {
"userId": "078966a2-93c2-4618-ae2a-0a2394c88d37",
"date": "2023-10-27T12:00:00.000Z"
}
"payload": "{
\"UserId\": \"078966a2-93c2-4618-ae2a-0a2394c88d37\",
\"Date\": \"2023-10-27T12:00:00.000Z\"
}"
}
"""
@ -881,13 +881,13 @@ private const val SYNC_CIPHER_CREATE_NOTIFICATION_JSON = """
{
"contextId": "801f459d-8e51-47d0-b072-3f18c9f66f64",
"type": 1,
"payload": {
"id": "aab5cdcc-f4a7-4e65-bf6d-5e0eab052321",
"userId": "078966a2-93c2-4618-ae2a-0a2394c88d37",
"organizationId": "6a41d965-ed95-4eae-98c3-5f1ec609c2c1",
"collectionIds": [],
"revisionDate": "2023-10-27T12:00:00.000Z"
}
"payload": "{
\"Id\": \"aab5cdcc-f4a7-4e65-bf6d-5e0eab052321\",
\"UserId\": \"078966a2-93c2-4618-ae2a-0a2394c88d37\",
\"OrganizationId\": \"6a41d965-ed95-4eae-98c3-5f1ec609c2c1\",
\"CollectionIds\": [],
\"RevisionDate\": \"2023-10-27T12:00:00.000Z\"
}"
}
"""
@ -895,13 +895,13 @@ private const val SYNC_CIPHER_DELETE_NOTIFICATION_JSON = """
{
"contextId": "801f459d-8e51-47d0-b072-3f18c9f66f64",
"type": 9,
"payload": {
"id": "aab5cdcc-f4a7-4e65-bf6d-5e0eab052321",
"userId": "078966a2-93c2-4618-ae2a-0a2394c88d37",
"organizationId": "6a41d965-ed95-4eae-98c3-5f1ec609c2c1",
"collectionIds": [],
"revisionDate": "2023-10-27T12:00:00.000Z"
}
"payload": "{
\"Id\": \"aab5cdcc-f4a7-4e65-bf6d-5e0eab052321\",
\"UserId\": \"078966a2-93c2-4618-ae2a-0a2394c88d37\",
\"OrganizationId\": \"6a41d965-ed95-4eae-98c3-5f1ec609c2c1\",
\"CollectionIds\": [],
\"RevisionDate\": \"2023-10-27T12:00:00.000Z\"
}"
}
"""
@ -909,13 +909,13 @@ private const val SYNC_CIPHER_UPDATE_NOTIFICATION_JSON = """
{
"contextId": "801f459d-8e51-47d0-b072-3f18c9f66f64",
"type": 0,
"payload": {
"id": "aab5cdcc-f4a7-4e65-bf6d-5e0eab052321",
"userId": "078966a2-93c2-4618-ae2a-0a2394c88d37",
"organizationId": "6a41d965-ed95-4eae-98c3-5f1ec609c2c1",
"collectionIds": [],
"revisionDate": "2023-10-27T12:00:00.000Z"
}
"payload": "{
\"Id\": \"aab5cdcc-f4a7-4e65-bf6d-5e0eab052321\",
\"UserId\": \"078966a2-93c2-4618-ae2a-0a2394c88d37\",
\"OrganizationId\": \"6a41d965-ed95-4eae-98c3-5f1ec609c2c1\",
\"CollectionIds\": [],
\"RevisionDate\": \"2023-10-27T12:00:00.000Z\"
}"
}
"""
@ -923,10 +923,10 @@ private const val SYNC_CIPHERS_NOTIFICATION_JSON = """
{
"contextId": "801f459d-8e51-47d0-b072-3f18c9f66f64",
"type": 4,
"payload": {
"userId": "078966a2-93c2-4618-ae2a-0a2394c88d37",
"date": "2023-10-27T12:00:00.000Z"
}
"payload": "{
\"UserId\": \"078966a2-93c2-4618-ae2a-0a2394c88d37\",
\"Date\": \"2023-10-27T12:00:00.000Z\"
}"
}
"""
@ -934,11 +934,11 @@ private const val SYNC_FOLDER_CREATE_NOTIFICATION_JSON = """
{
"contextId": "801f459d-8e51-47d0-b072-3f18c9f66f64",
"type": 7,
"payload": {
"id": "aab5cdcc-f4a7-4e65-bf6d-5e0eab052321",
"userId": "078966a2-93c2-4618-ae2a-0a2394c88d37",
"revisionDate": "2023-10-27T12:00:00.000Z"
}
"payload": "{
\"Id\": \"aab5cdcc-f4a7-4e65-bf6d-5e0eab052321\",
\"UserId\": \"078966a2-93c2-4618-ae2a-0a2394c88d37\",
\"RevisionDate\": \"2023-10-27T12:00:00.000Z\"
}"
}
"""
@ -946,11 +946,11 @@ private const val SYNC_FOLDER_DELETE_NOTIFICATION_JSON = """
{
"contextId": "801f459d-8e51-47d0-b072-3f18c9f66f64",
"type": 3,
"payload": {
"id": "aab5cdcc-f4a7-4e65-bf6d-5e0eab052321",
"userId": "078966a2-93c2-4618-ae2a-0a2394c88d37",
"revisionDate": "2023-10-27T12:00:00.000Z"
}
"payload": "{
\"Id\": \"aab5cdcc-f4a7-4e65-bf6d-5e0eab052321\",
\"UserId\": \"078966a2-93c2-4618-ae2a-0a2394c88d37\",
\"RevisionDate\": \"2023-10-27T12:00:00.000Z\"
}"
}
"""
@ -958,11 +958,11 @@ private const val SYNC_FOLDER_UPDATE_NOTIFICATION_JSON = """
{
"contextId": "801f459d-8e51-47d0-b072-3f18c9f66f64",
"type": 8,
"payload": {
"id": "aab5cdcc-f4a7-4e65-bf6d-5e0eab052321",
"userId": "078966a2-93c2-4618-ae2a-0a2394c88d37",
"revisionDate": "2023-10-27T12:00:00.000Z"
}
"payload": "{
\"Id\": \"aab5cdcc-f4a7-4e65-bf6d-5e0eab052321\",
\"UserId\": \"078966a2-93c2-4618-ae2a-0a2394c88d37\",
\"RevisionDate\": \"2023-10-27T12:00:00.000Z\"
}"
}
"""
@ -970,13 +970,13 @@ private const val SYNC_LOGIN_DELETE_NOTIFICATION_JSON = """
{
"contextId": "801f459d-8e51-47d0-b072-3f18c9f66f64",
"type": 2,
"payload": {
"id": "aab5cdcc-f4a7-4e65-bf6d-5e0eab052321",
"userId": "078966a2-93c2-4618-ae2a-0a2394c88d37",
"organizationId": "6a41d965-ed95-4eae-98c3-5f1ec609c2c1",
"collectionIds": [],
"revisionDate": "2023-10-27T12:00:00.000Z"
}
"payload": "{
\"Id\": \"aab5cdcc-f4a7-4e65-bf6d-5e0eab052321\",
\"UserId\": \"078966a2-93c2-4618-ae2a-0a2394c88d37\",
\"OrganizationId\": \"6a41d965-ed95-4eae-98c3-5f1ec609c2c1\",
\"CollectionIds\": [],
\"RevisionDate\": \"2023-10-27T12:00:00.000Z\"
}"
}
"""
@ -984,10 +984,10 @@ private const val SYNC_ORG_KEYS_NOTIFICATION_JSON = """
{
"contextId": "801f459d-8e51-47d0-b072-3f18c9f66f64",
"type": 6,
"payload": {
"userId": "078966a2-93c2-4618-ae2a-0a2394c88d37",
"date": "2023-10-27T12:00:00.000Z"
}
"payload": "{
\"UserId\": \"078966a2-93c2-4618-ae2a-0a2394c88d37\",
\"Date\": \"2023-10-27T12:00:00.000Z\"
}"
}
"""
@ -995,11 +995,11 @@ private const val SYNC_SEND_CREATE_NOTIFICATION_JSON = """
{
"contextId": "801f459d-8e51-47d0-b072-3f18c9f66f64",
"type": 12,
"payload": {
"id": "aab5cdcc-f4a7-4e65-bf6d-5e0eab052321",
"userId": "078966a2-93c2-4618-ae2a-0a2394c88d37",
"revisionDate": "2023-10-27T12:00:00.000Z"
}
"payload": "{
\"Id\": \"aab5cdcc-f4a7-4e65-bf6d-5e0eab052321\",
\"UserId\": \"078966a2-93c2-4618-ae2a-0a2394c88d37\",
\"RevisionDate\": \"2023-10-27T12:00:00.000Z\"
}"
}
"""
@ -1007,11 +1007,11 @@ private const val SYNC_SEND_DELETE_NOTIFICATION_JSON = """
{
"contextId": "801f459d-8e51-47d0-b072-3f18c9f66f64",
"type": 14,
"payload": {
"id": "aab5cdcc-f4a7-4e65-bf6d-5e0eab052321",
"userId": "078966a2-93c2-4618-ae2a-0a2394c88d37",
"revisionDate": "2023-10-27T12:00:00.000Z"
}
"payload": "{
\"Id\": \"aab5cdcc-f4a7-4e65-bf6d-5e0eab052321\",
\"UserId\": \"078966a2-93c2-4618-ae2a-0a2394c88d37\",
\"RevisionDate\": \"2023-10-27T12:00:00.000Z\"
}"
}
"""
@ -1019,11 +1019,11 @@ private const val SYNC_SEND_UPDATE_NOTIFICATION_JSON = """
{
"contextId": "801f459d-8e51-47d0-b072-3f18c9f66f64",
"type": 13,
"payload": {
"id": "aab5cdcc-f4a7-4e65-bf6d-5e0eab052321",
"userId": "078966a2-93c2-4618-ae2a-0a2394c88d37",
"revisionDate": "2023-10-27T12:00:00.000Z"
}
"payload": "{
\"Id\": \"aab5cdcc-f4a7-4e65-bf6d-5e0eab052321\",
\"UserId\": \"078966a2-93c2-4618-ae2a-0a2394c88d37\",
\"RevisionDate\": \"2023-10-27T12:00:00.000Z\"
}"
}
"""
@ -1031,10 +1031,10 @@ private const val SYNC_SETTINGS_NOTIFICATION_JSON = """
{
"contextId": "801f459d-8e51-47d0-b072-3f18c9f66f64",
"type": 10,
"payload": {
"userId": "078966a2-93c2-4618-ae2a-0a2394c88d37",
"date": "2023-10-27T12:00:00.000Z"
}
"payload": "{
\"UserId\": \"078966a2-93c2-4618-ae2a-0a2394c88d37\",
\"Date\": \"2023-10-27T12:00:00.000Z\"
}"
}
"""
@ -1042,9 +1042,9 @@ private const val SYNC_VAULT_NOTIFICATION_JSON = """
{
"contextId": "801f459d-8e51-47d0-b072-3f18c9f66f64",
"type": 5,
"payload": {
"userId": "078966a2-93c2-4618-ae2a-0a2394c88d37",
"date": "2023-10-27T12:00:00.000Z"
}
"payload": "{
\"UserId\": \"078966a2-93c2-4618-ae2a-0a2394c88d37\",
\"Date\": \"2023-10-27T12:00:00.000Z\"
}"
}
"""