Skip to content

Commit

Permalink
[PM-8217] Add creationDate and isTwoFactorEnable properties (#4504)
Browse files Browse the repository at this point in the history
  • Loading branch information
andrebispo5 authored Dec 23, 2024
1 parent 6223f36 commit 688dd3a
Show file tree
Hide file tree
Showing 21 changed files with 88 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package com.x8bit.bitwarden.data.auth.datasource.disk.model

import com.x8bit.bitwarden.data.auth.datasource.network.model.KdfTypeJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.UserDecryptionOptionsJson
import kotlinx.serialization.Contextual
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonNames
import java.time.ZonedDateTime

/**
* Represents the current account information for a given user.
Expand Down Expand Up @@ -35,6 +37,7 @@ data class AccountJson(
* @property userId The ID of the user.
* @property email The user's email address.
* @property isEmailVerified Whether or not the user's email is verified.
* @property isTwoFactorEnabled If the profile has two factor authentication enabled.
* @property name The user's name (if applicable).
* @property stamp The account's security stamp (if applicable).
* @property organizationId The ID of the associated organization (if applicable).
Expand All @@ -46,6 +49,7 @@ data class AccountJson(
* @property kdfMemory The amount of memory to use when calculating a password hash (MB).
* @property kdfParallelism The number of threads to use when calculating a password hash.
* @property userDecryptionOptions The options available to a user for decryption.
* @property creationDate The creation date of the account.
*/
@OptIn(ExperimentalSerializationApi::class)
@Serializable
Expand All @@ -59,6 +63,9 @@ data class AccountJson(
@SerialName("emailVerified")
val isEmailVerified: Boolean?,

@SerialName("isTwoFactorEnabled")
val isTwoFactorEnabled: Boolean?,

@SerialName("name")
val name: String?,

Expand Down Expand Up @@ -92,6 +99,10 @@ data class AccountJson(
@SerialName("userDecryptionOptions")
@JsonNames("accountDecryptionOptions")
val userDecryptionOptions: UserDecryptionOptionsJson?,

@SerialName("creationDate")
@Contextual
val creationDate: ZonedDateTime?,
)

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ fun GetTokenResponseJson.Success.toUserState(
userId = userId,
email = jwtTokenData.email,
isEmailVerified = jwtTokenData.isEmailVerified,
isTwoFactorEnabled = null,
name = jwtTokenData.name,
stamp = null,
organizationId = null,
Expand All @@ -36,6 +37,7 @@ fun GetTokenResponseJson.Success.toUserState(
kdfMemory = this.kdfMemory,
kdfParallelism = this.kdfParallelism,
userDecryptionOptions = this.userDecryptionOptions,
creationDate = null,
),
settings = AccountJson.Settings(
environmentUrlData = environmentUrlData,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ fun UserStateJson.toUpdatedUserStateJson(
avatarColorHex = syncProfile.avatarColor,
stamp = syncProfile.securityStamp,
hasPremium = syncProfile.isPremium || syncProfile.isPremiumFromOrganization,
isTwoFactorEnabled = syncProfile.isTwoFactorEnabled,
creationDate = syncProfile.creationDate,
)
val updatedAccount = account.copy(profile = updatedProfile)
return this
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ data class SyncResponseJson(
* @property key The key of the profile (nullable).
* @property securityStamp The secure stamp of the profile (nullable).
* @property providers A list of providers associated with the profile (nullable).
* @property creationDate The creation date of the account.
*/
@Serializable
data class Profile(
Expand Down Expand Up @@ -209,6 +210,10 @@ data class SyncResponseJson(

@SerialName("providers")
val providers: List<Provider>?,

@SerialName("creationDate")
@Contextual
val creationDate: ZonedDateTime,
) {
/**
* Represents an organization in the vault response.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import org.junit.jupiter.api.Assertions.assertFalse
import org.junit.jupiter.api.Assertions.assertNull
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test
import java.time.ZonedDateTime

@Suppress("LargeClass")
class AuthDiskSourceTest {
Expand Down Expand Up @@ -1256,6 +1257,7 @@ private const val USER_STATE_JSON = """
"userId": "activeUserId",
"email": "email",
"emailVerified": true,
"isTwoFactorEnabled": false,
"name": "name",
"stamp": "stamp",
"orgIdentifier": "organizationId",
Expand All @@ -1278,7 +1280,8 @@ private const val USER_STATE_JSON = """
"keyConnectorOption": {
"keyConnectorUrl": "keyConnectorUrl"
}
}
},
"creationDate": "2024-09-13T01:00:00.000Z"
},
"tokens": {
"accessToken": "accessToken",
Expand Down Expand Up @@ -1318,6 +1321,8 @@ private val USER_STATE = UserStateJson(
kdfIterations = 600000,
kdfMemory = 16,
kdfParallelism = 4,
isTwoFactorEnabled = false,
creationDate = ZonedDateTime.parse("2024-09-13T01:00:00.00Z"),
userDecryptionOptions = UserDecryptionOptionsJson(
hasMasterPassword = true,
trustedDeviceUserDecryptionOptions = TrustedDeviceUserDecryptionOptionsJson(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1168,6 +1168,8 @@ private val ACCOUNT: AccountJson = AccountJson(
kdfMemory = 16,
kdfParallelism = 4,
userDecryptionOptions = null,
isTwoFactorEnabled = false,
creationDate = ZonedDateTime.parse("2024-09-13T01:00:00.00Z"),
),
tokens = AccountTokensJson(
accessToken = ACCESS_TOKEN,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,8 @@ private val DEFAULT_ACCOUNT = AccountJson(
kdfMemory = 16,
kdfParallelism = 4,
userDecryptionOptions = DEFAULT_USER_DECRYPTION_OPTIONS,
isTwoFactorEnabled = false,
creationDate = ZonedDateTime.parse("2024-09-13T01:00:00.00Z"),
),
settings = AccountJson.Settings(
environmentUrlData = EnvironmentUrlDataJson.DEFAULT_US,
Expand All @@ -319,6 +321,8 @@ private val UPDATED_ACCOUNT = AccountJson(
kdfMemory = 16,
kdfParallelism = 4,
userDecryptionOptions = UPDATED_USER_DECRYPTION_OPTIONS,
isTwoFactorEnabled = false,
creationDate = ZonedDateTime.parse("2024-09-13T01:00:00.00Z"),
),
settings = AccountJson.Settings(
environmentUrlData = EnvironmentUrlDataJson.DEFAULT_US,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import io.mockk.verify
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import java.time.ZonedDateTime

@ExtendWith(MainDispatcherExtension::class)
class UserLogoutManagerTest {
Expand Down Expand Up @@ -256,6 +257,8 @@ private val ACCOUNT_1 = AccountJson(
kdfMemory = 16,
kdfParallelism = 4,
userDecryptionOptions = null,
isTwoFactorEnabled = false,
creationDate = ZonedDateTime.parse("2024-09-13T01:00:00.00Z"),
),
tokens = AccountTokensJson(
accessToken = ACCESS_TOKEN,
Expand All @@ -281,6 +284,8 @@ private val ACCOUNT_2 = AccountJson(
kdfMemory = null,
kdfParallelism = null,
userDecryptionOptions = null,
isTwoFactorEnabled = false,
creationDate = ZonedDateTime.parse("2024-09-13T01:00:00.00Z"),
),
tokens = AccountTokensJson(
accessToken = ACCESS_TOKEN_2,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import com.x8bit.bitwarden.data.auth.datasource.network.model.TrustedDeviceUserD
import com.x8bit.bitwarden.data.auth.datasource.network.model.UserDecryptionOptionsJson
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import java.time.ZonedDateTime

class TrustDeviceResponseExtensionsTest {
@Test
Expand Down Expand Up @@ -78,6 +79,8 @@ private val DEFAULT_ACCOUNT = AccountJson(
kdfMemory = 16,
kdfParallelism = 4,
userDecryptionOptions = DEFAULT_USER_DECRYPTION_OPTIONS,
isTwoFactorEnabled = false,
creationDate = ZonedDateTime.parse("2024-09-13T01:00:00.00Z"),
),
settings = AccountJson.Settings(
environmentUrlData = EnvironmentUrlDataJson.DEFAULT_US,
Expand All @@ -100,6 +103,8 @@ private val UPDATED_ACCOUNT = AccountJson(
kdfMemory = 16,
kdfParallelism = 4,
userDecryptionOptions = UPDATED_USER_DECRYPTION_OPTIONS,
isTwoFactorEnabled = false,
creationDate = ZonedDateTime.parse("2024-09-13T01:00:00.00Z"),
),
settings = AccountJson.Settings(
environmentUrlData = EnvironmentUrlDataJson.DEFAULT_US,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6571,6 +6571,8 @@ class AuthRepositoryTest {
kdfMemory = 16,
kdfParallelism = 4,
userDecryptionOptions = null,
isTwoFactorEnabled = false,
creationDate = ZonedDateTime.parse("2024-09-13T01:00:00.00Z"),
)
private val ACCOUNT_1 = AccountJson(
profile = PROFILE_1,
Expand All @@ -6594,6 +6596,8 @@ class AuthRepositoryTest {
kdfMemory = null,
kdfParallelism = null,
userDecryptionOptions = null,
isTwoFactorEnabled = false,
creationDate = ZonedDateTime.parse("2024-09-13T01:00:00.00Z"),
),
settings = AccountJson.Settings(
environmentUrlData = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertNull
import org.junit.jupiter.api.Test
import java.time.ZonedDateTime

class AuthDiskSourceExtensionsTest {
private val authDiskSource: AuthDiskSource = FakeAuthDiskSource()
Expand Down Expand Up @@ -531,6 +532,8 @@ private val MOCK_PROFILE = AccountJson.Profile(
kdfMemory = null,
kdfParallelism = null,
userDecryptionOptions = null,
isTwoFactorEnabled = false,
creationDate = ZonedDateTime.parse("2024-09-13T01:00:00.00Z"),
)

private val MOCK_ACCOUNT = AccountJson(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@ private val PROFILE_1 = AccountJson.Profile(
kdfMemory = 16,
kdfParallelism = 4,
userDecryptionOptions = null,
isTwoFactorEnabled = null,
creationDate = null,
)
private val ACCOUNT_1 = AccountJson(
profile = PROFILE_1,
Expand All @@ -164,6 +166,8 @@ private val ACCOUNT_2 = AccountJson(
kdfMemory = null,
kdfParallelism = null,
userDecryptionOptions = null,
isTwoFactorEnabled = null,
creationDate = null,
),
settings = AccountJson.Settings(
environmentUrlData = EnvironmentUrlDataJson.DEFAULT_US,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import io.mockk.every
import io.mockk.mockk
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import java.time.ZonedDateTime

@Suppress("LargeClass")
class UserStateJsonExtensionsTest {
Expand Down Expand Up @@ -59,6 +60,8 @@ class UserStateJsonExtensionsTest {
kdfMemory = 16,
kdfParallelism = 4,
userDecryptionOptions = null,
isTwoFactorEnabled = false,
creationDate = ZonedDateTime.parse("2024-09-13T01:00:00.00Z"),
)
val originalAccount = AccountJson(
profile = originalProfile,
Expand Down Expand Up @@ -110,6 +113,8 @@ class UserStateJsonExtensionsTest {
trustedDeviceUserDecryptionOptions = null,
keyConnectorUserDecryptionOptions = null,
),
isTwoFactorEnabled = false,
creationDate = ZonedDateTime.parse("2024-09-13T01:00:00.00Z"),
)
val originalAccount = AccountJson(
profile = originalProfile,
Expand Down Expand Up @@ -178,6 +183,8 @@ class UserStateJsonExtensionsTest {
kdfMemory = 16,
kdfParallelism = 4,
userDecryptionOptions = null,
isTwoFactorEnabled = false,
creationDate = ZonedDateTime.parse("2024-09-13T01:00:00.00Z"),
)
val originalAccount = AccountJson(
profile = originalProfile,
Expand All @@ -192,6 +199,8 @@ class UserStateJsonExtensionsTest {
profile = originalProfile.copy(
avatarColorHex = "avatarColor",
stamp = "securityStamp",
isTwoFactorEnabled = false,
creationDate = ZonedDateTime.parse("2024-09-13T01:00:00.00Z"),
),
),
),
Expand All @@ -210,6 +219,9 @@ class UserStateJsonExtensionsTest {
every { securityStamp } returns "securityStamp"
every { isPremium } returns true
every { isPremiumFromOrganization } returns true
every { isTwoFactorEnabled } returns false
every { creationDate } returns ZonedDateTime
.parse("2024-09-13T01:00:00.00Z")
}
},
),
Expand All @@ -235,6 +247,8 @@ class UserStateJsonExtensionsTest {
kdfMemory = 16,
kdfParallelism = 4,
userDecryptionOptions = null,
isTwoFactorEnabled = false,
creationDate = ZonedDateTime.parse("2024-09-13T01:00:00.00Z"),
)
val originalAccount = AccountJson(
profile = originalProfile,
Expand Down Expand Up @@ -296,6 +310,8 @@ class UserStateJsonExtensionsTest {
keyConnectorUserDecryptionOptions = keyConnectorOptionsJson,
trustedDeviceUserDecryptionOptions = trustedDeviceOptionsJson,
),
isTwoFactorEnabled = false,
creationDate = ZonedDateTime.parse("2024-09-13T01:00:00.00Z"),
)
val originalAccount = AccountJson(
profile = originalProfile,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertFalse
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test
import java.time.ZonedDateTime

class FirstTimeActionManagerTest {
private val fakeAuthDiskSource = FakeAuthDiskSource()
Expand Down Expand Up @@ -328,6 +329,8 @@ private val MOCK_PROFILE = AccountJson.Profile(
kdfMemory = 16,
kdfParallelism = 4,
userDecryptionOptions = MOCK_USER_DECRYPTION_OPTIONS,
isTwoFactorEnabled = false,
creationDate = ZonedDateTime.parse("2024-09-13T01:00:00.00Z"),
)

private val MOCK_ACCOUNT = AccountJson(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import org.junit.jupiter.api.Assertions.assertNull
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test
import java.time.Instant
import java.time.ZonedDateTime

@Suppress("LargeClass")
class SettingsRepositoryTest {
Expand Down Expand Up @@ -1259,6 +1260,8 @@ private val MOCK_PROFILE = AccountJson.Profile(
kdfMemory = 16,
kdfParallelism = 4,
userDecryptionOptions = MOCK_USER_DECRYPTION_OPTIONS,
isTwoFactorEnabled = false,
creationDate = ZonedDateTime.parse("2024-09-13T01:00:00.00Z"),
)

private val MOCK_ACCOUNT = AccountJson(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import org.junit.jupiter.api.Test
import java.time.Clock
import java.time.Instant
import java.time.ZoneOffset
import java.time.ZonedDateTime

@Suppress("LargeClass")
class GeneratorRepositoryTest {
Expand Down Expand Up @@ -788,6 +789,8 @@ private val USER_STATE = UserStateJson(
keyConnectorUrl = "keyConnectorUrl",
),
),
isTwoFactorEnabled = false,
creationDate = ZonedDateTime.parse("2024-09-13T01:00:00.00Z"),
),
tokens = AccountTokensJson(
accessToken = "accessToken",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ fun createMockProfile(number: Int): SyncResponseJson.Profile =
key = "mockKey-$number",
securityStamp = "mockSecurityStamp-$number",
providers = listOf(createMockProvider(number = number)),
creationDate = ZonedDateTime.parse("2024-09-13T01:00:00.00Z"),
)

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ private const val SYNC_SUCCESS_JSON = """
"forcePasswordReset": false,
"usesKeyConnector": false,
"avatarColor": "mockAvatarColor-1",
"creationDate": "2024-09-13T01:00:00.00Z",
"organizations": [
{
"usePolicies": false,
Expand Down
Loading

0 comments on commit 688dd3a

Please sign in to comment.