Merge branch 'main' into feature/add-password-credential-manager-provider

This commit is contained in:
Nailik 2024-11-20 09:47:58 +01:00 committed by GitHub
commit ebf448d4d3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
104 changed files with 1278 additions and 359 deletions

View file

@ -9,6 +9,7 @@ import com.x8bit.bitwarden.data.auth.datasource.network.model.RegisterFinishRequ
import com.x8bit.bitwarden.data.auth.datasource.network.model.RegisterRequestJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.RegisterResponseJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.SendVerificationEmailRequestJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.SendVerificationEmailResponseJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.TwoFactorDataModel
import com.x8bit.bitwarden.data.auth.datasource.network.model.VerifyEmailTokenRequestJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.VerifyEmailTokenResponseJson
@ -68,7 +69,7 @@ interface IdentityService {
*/
suspend fun sendVerificationEmail(
body: SendVerificationEmailRequestJson,
): Result<String?>
): Result<SendVerificationEmailResponseJson>
/**
* Register a new account to Bitwarden using email verification flow.

View file

@ -11,6 +11,7 @@ import com.x8bit.bitwarden.data.auth.datasource.network.model.RegisterFinishRequ
import com.x8bit.bitwarden.data.auth.datasource.network.model.RegisterRequestJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.RegisterResponseJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.SendVerificationEmailRequestJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.SendVerificationEmailResponseJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.TwoFactorDataModel
import com.x8bit.bitwarden.data.auth.datasource.network.model.VerifyEmailTokenRequestJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.VerifyEmailTokenResponseJson
@ -132,11 +133,20 @@ class IdentityServiceImpl(
override suspend fun sendVerificationEmail(
body: SendVerificationEmailRequestJson,
): Result<String?> {
): Result<SendVerificationEmailResponseJson> {
return unauthenticatedIdentityApi
.sendVerificationEmail(body = body)
.toResult()
.map { it?.content }
.map { SendVerificationEmailResponseJson.Success(it?.content) }
.recoverCatching { throwable ->
throwable
.toBitwardenError()
.parseErrorBodyOrNull<SendVerificationEmailResponseJson.Invalid>(
code = 400,
json = json,
)
?: throw throwable
}
}
override suspend fun verifyEmailRegistrationToken(

View file

@ -22,6 +22,7 @@ import com.x8bit.bitwarden.data.auth.datasource.network.model.RegisterResponseJs
import com.x8bit.bitwarden.data.auth.datasource.network.model.ResendEmailRequestJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.ResetPasswordRequestJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.SendVerificationEmailRequestJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.SendVerificationEmailResponseJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.SetPasswordRequestJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.TrustedDeviceUserDecryptionOptionsJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.TwoFactorAuthMethod
@ -1282,7 +1283,15 @@ class AuthRepositoryImpl(
)
.fold(
onSuccess = {
SendVerificationEmailResult.Success(it)
when (it) {
is SendVerificationEmailResponseJson.Invalid -> {
SendVerificationEmailResult.Error(it.message)
}
is SendVerificationEmailResponseJson.Success -> {
SendVerificationEmailResult.Success(it.emailVerificationToken)
}
}
},
onFailure = {
SendVerificationEmailResult.Error(null)

View file

@ -297,7 +297,7 @@ private fun CheckEmailLegacyContent(
),
highlights = listOf(
ClickableTextHighlight(
textToHighlight = stringResource(id = R.string.log_in),
textToHighlight = stringResource(id = R.string.log_in_verb),
onTextClick = onLoginClick,
),
),

View file

@ -42,14 +42,20 @@ fun PasswordStrengthIndicator(
currentCharacterCount: Int,
minimumCharacterCount: Int? = null,
) {
val minimumRequirementMet = (minimumCharacterCount == null) ||
(currentCharacterCount >= minimumCharacterCount)
val widthPercent by animateFloatAsState(
targetValue = when (state) {
PasswordStrengthState.NONE -> 0f
PasswordStrengthState.WEAK_1 -> .25f
PasswordStrengthState.WEAK_2 -> .5f
PasswordStrengthState.WEAK_3 -> .66f
PasswordStrengthState.GOOD -> .82f
PasswordStrengthState.STRONG -> 1f
targetValue = if (minimumRequirementMet) {
when (state) {
PasswordStrengthState.NONE -> 0f
PasswordStrengthState.WEAK_1 -> .25f
PasswordStrengthState.WEAK_2 -> .5f
PasswordStrengthState.WEAK_3 -> .66f
PasswordStrengthState.GOOD -> .82f
PasswordStrengthState.STRONG -> 1f
}
} else {
0f
},
label = "Width Percent State",
)
@ -107,11 +113,13 @@ fun PasswordStrengthIndicator(
minimumCharacterCount = minCount,
)
}
Text(
text = label(),
style = BitwardenTheme.typography.labelSmall,
color = indicatorColor,
)
if (minimumRequirementMet) {
Text(
text = label(),
style = BitwardenTheme.typography.labelSmall,
color = indicatorColor,
)
}
}
}
}
@ -122,14 +130,6 @@ private fun MinimumCharacterCount(
minimumRequirementMet: Boolean,
minimumCharacterCount: Int,
) {
val characterCountColor by animateColorAsState(
targetValue = if (minimumRequirementMet) {
BitwardenTheme.colorScheme.status.strong
} else {
BitwardenTheme.colorScheme.text.secondary
},
label = "minmumCharacterCountColor",
)
Row(
modifier = modifier,
verticalAlignment = Alignment.CenterVertically,
@ -145,14 +145,14 @@ private fun MinimumCharacterCount(
Icon(
painter = rememberVectorPainter(id = it),
contentDescription = null,
tint = characterCountColor,
tint = BitwardenTheme.colorScheme.text.secondary,
modifier = Modifier.size(12.dp),
)
}
Spacer(modifier = Modifier.width(2.dp))
Text(
text = stringResource(R.string.minimum_characters, minimumCharacterCount),
color = characterCountColor,
color = BitwardenTheme.colorScheme.text.secondary,
style = BitwardenTheme.typography.labelSmall,
)
}

View file

@ -1,14 +1,11 @@
package com.x8bit.bitwarden.ui.auth.feature.createaccount
import android.widget.Toast
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
@ -17,31 +14,23 @@ import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.rememberTopAppBarState
import androidx.compose.material3.ripple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTag
import androidx.compose.ui.semantics.toggleableState
import androidx.compose.ui.state.ToggleableState
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.core.net.toUri
@ -76,7 +65,6 @@ import com.x8bit.bitwarden.ui.platform.components.field.BitwardenTextField
import com.x8bit.bitwarden.ui.platform.components.scaffold.BitwardenScaffold
import com.x8bit.bitwarden.ui.platform.components.text.BitwardenClickableText
import com.x8bit.bitwarden.ui.platform.components.toggle.BitwardenSwitch
import com.x8bit.bitwarden.ui.platform.components.toggle.color.bitwardenSwitchColors
import com.x8bit.bitwarden.ui.platform.components.util.rememberVectorPainter
import com.x8bit.bitwarden.ui.platform.composition.LocalIntentManager
import com.x8bit.bitwarden.ui.platform.manager.intent.IntentManager
@ -283,6 +271,9 @@ fun CreateAccountScreen(
onPrivacyPolicyClick = remember(viewModel) {
{ viewModel.trySendAction(PrivacyPolicyClick) }
},
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp),
)
Spacer(modifier = Modifier.navigationBarsPadding())
}
@ -290,52 +281,24 @@ fun CreateAccountScreen(
}
@OptIn(ExperimentalLayoutApi::class)
@Suppress("LongMethod")
@Composable
private fun TermsAndPrivacySwitch(
isChecked: Boolean,
onCheckedChange: (Boolean) -> Unit,
onTermsClick: () -> Unit,
onPrivacyPolicyClick: () -> Unit,
modifier: Modifier = Modifier,
) {
Row(
horizontalArrangement = Arrangement.Start,
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.semantics(mergeDescendants = true) {
testTag = "AcceptPoliciesToggle"
toggleableState = ToggleableState(isChecked)
}
.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = ripple(
color = BitwardenTheme.colorScheme.background.pressed,
),
onClick = { onCheckedChange.invoke(!isChecked) },
)
.padding(start = 16.dp)
.fillMaxWidth(),
) {
Switch(
modifier = Modifier
.height(32.dp)
.width(52.dp),
checked = isChecked,
onCheckedChange = null,
colors = bitwardenSwitchColors(),
)
Column(Modifier.padding(start = 16.dp, top = 4.dp, bottom = 4.dp)) {
Text(
text = stringResource(id = R.string.accept_policies),
style = BitwardenTheme.typography.bodyLarge,
color = BitwardenTheme.colorScheme.text.primary,
)
BitwardenSwitch(
modifier = modifier,
label = stringResource(id = R.string.accept_policies),
isChecked = isChecked,
contentDescription = "AcceptPoliciesToggle",
onCheckedChange = onCheckedChange,
subContent = {
FlowRow(
horizontalArrangement = Arrangement.Start,
modifier = Modifier
.padding(end = 16.dp)
.fillMaxWidth()
.wrapContentHeight(),
modifier = Modifier.fillMaxWidth(),
) {
BitwardenClickableText(
label = stringResource(id = R.string.terms_of_service),
@ -357,6 +320,6 @@ private fun TermsAndPrivacySwitch(
innerPadding = PaddingValues(vertical = 4.dp, horizontal = 0.dp),
)
}
}
}
},
)
}

View file

@ -117,7 +117,7 @@ fun EnterpriseSignOnScreen(
},
actions = {
BitwardenTextButton(
label = stringResource(id = R.string.log_in),
label = stringResource(id = R.string.log_in_verb),
onClick = remember(viewModel) {
{ viewModel.trySendAction(EnterpriseSignOnAction.LogInClick) }
},

View file

@ -272,7 +272,7 @@ private fun LoginScreenContent(
if (state.shouldShowLoginWithDevice) {
BitwardenOutlinedButton(
label = stringResource(id = R.string.log_in_with_device),
icon = rememberVectorPainter(id = R.drawable.ic_mobile),
icon = rememberVectorPainter(id = R.drawable.ic_mobile_small),
onClick = onLoginWithDeviceClick,
modifier = Modifier
.testTag("LogInWithAnotherDeviceButton")
@ -285,7 +285,7 @@ private fun LoginScreenContent(
BitwardenOutlinedButton(
label = stringResource(id = R.string.log_in_sso),
icon = rememberVectorPainter(id = R.drawable.ic_briefcase),
icon = rememberVectorPainter(id = R.drawable.ic_enterprise_small),
onClick = onSingleSignOnClick,
modifier = Modifier
.testTag("LogInWithSsoButton")

View file

@ -2,8 +2,6 @@ package com.x8bit.bitwarden.ui.auth.feature.startregistration
import android.widget.Toast
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
@ -16,15 +14,12 @@ import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.rememberTopAppBarState
import androidx.compose.material3.ripple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
@ -38,8 +33,6 @@ import androidx.compose.ui.semantics.CustomAccessibilityAction
import androidx.compose.ui.semantics.customActions
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTag
import androidx.compose.ui.semantics.toggleableState
import androidx.compose.ui.state.ToggleableState
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign
@ -70,7 +63,7 @@ import com.x8bit.bitwarden.ui.platform.components.dialog.LoadingDialogState
import com.x8bit.bitwarden.ui.platform.components.dropdown.EnvironmentSelector
import com.x8bit.bitwarden.ui.platform.components.field.BitwardenTextField
import com.x8bit.bitwarden.ui.platform.components.scaffold.BitwardenScaffold
import com.x8bit.bitwarden.ui.platform.components.toggle.color.bitwardenSwitchColors
import com.x8bit.bitwarden.ui.platform.components.toggle.BitwardenSwitch
import com.x8bit.bitwarden.ui.platform.components.util.rememberVectorPainter
import com.x8bit.bitwarden.ui.platform.composition.LocalIntentManager
import com.x8bit.bitwarden.ui.platform.manager.intent.IntentManager
@ -277,7 +270,9 @@ private fun StartRegistrationContent(
isChecked = isReceiveMarketingEmailsToggled,
onCheckedChange = handler.onReceiveMarketingEmailsToggle,
onUnsubscribeClick = handler.onUnsubscribeMarketingEmailsClick,
modifier = Modifier.standardHorizontalMargin(),
modifier = Modifier
.fillMaxWidth()
.standardHorizontalMargin(),
)
Spacer(modifier = Modifier.height(24.dp))
}
@ -361,7 +356,6 @@ private fun TermsAndPrivacyText(
}
}
@Suppress("LongMethod")
@Composable
private fun ReceiveMarketingEmailsSwitch(
isChecked: Boolean,
@ -373,7 +367,9 @@ private fun ReceiveMarketingEmailsSwitch(
@Suppress("MaxLineLength")
val annotatedLinkString = createClickableAnnotatedString(
mainString = stringResource(id = R.string.get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time),
mainString = stringResource(
id = R.string.get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time,
),
highlights = listOf(
ClickableTextHighlight(
textToHighlight = unsubscribeString,
@ -381,13 +377,9 @@ private fun ReceiveMarketingEmailsSwitch(
),
),
)
Row(
horizontalArrangement = Arrangement.Start,
verticalAlignment = Alignment.CenterVertically,
BitwardenSwitch(
modifier = modifier
.semantics(mergeDescendants = true) {
testTag = "ReceiveMarketingEmailsToggle"
toggleableState = ToggleableState(isChecked)
customActions = listOf(
CustomAccessibilityAction(
label = unsubscribeString,
@ -397,30 +389,12 @@ private fun ReceiveMarketingEmailsSwitch(
},
),
)
}
.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = ripple(
color = BitwardenTheme.colorScheme.background.pressed,
),
onClick = { onCheckedChange.invoke(!isChecked) },
)
.fillMaxWidth(),
) {
Switch(
modifier = Modifier
.height(32.dp)
.width(52.dp),
checked = isChecked,
onCheckedChange = null,
colors = bitwardenSwitchColors(),
)
Spacer(modifier = Modifier.width(16.dp))
Text(
text = annotatedLinkString,
style = BitwardenTheme.typography.bodyMedium,
)
}
},
label = annotatedLinkString,
isChecked = isChecked,
onCheckedChange = onCheckedChange,
contentDescription = "ReceiveMarketingEmailsToggle",
)
}
@PreviewScreenSizes

View file

@ -44,7 +44,7 @@ import com.x8bit.bitwarden.R
import com.x8bit.bitwarden.ui.platform.base.util.EventsEffect
import com.x8bit.bitwarden.ui.platform.base.util.standardHorizontalMargin
import com.x8bit.bitwarden.ui.platform.components.button.BitwardenFilledButton
import com.x8bit.bitwarden.ui.platform.components.button.BitwardenTextButton
import com.x8bit.bitwarden.ui.platform.components.button.BitwardenOutlinedButton
import com.x8bit.bitwarden.ui.platform.components.scaffold.BitwardenScaffold
import com.x8bit.bitwarden.ui.platform.components.util.rememberVectorPainter
import com.x8bit.bitwarden.ui.platform.theme.BitwardenTheme
@ -164,8 +164,8 @@ private fun WelcomeScreenContent(
.fillMaxWidth(),
)
BitwardenTextButton(
label = stringResource(id = R.string.log_in),
BitwardenOutlinedButton(
label = stringResource(id = R.string.log_in_verb),
onClick = onLoginClick,
modifier = Modifier
.standardHorizontalMargin(landscape = LANDSCAPE_HORIZONTAL_MARGIN)
@ -189,7 +189,7 @@ private fun WelcomeCardLandscape(
Image(
painter = rememberVectorPainter(id = state.imageRes),
contentDescription = null,
modifier = Modifier.size(132.dp),
modifier = Modifier.size(124.dp),
)
Column(
@ -227,7 +227,7 @@ private fun WelcomeCardPortrait(
Image(
painter = rememberVectorPainter(id = state.imageRes),
contentDescription = null,
modifier = Modifier.size(200.dp),
modifier = Modifier.size(124.dp),
)
Text(

View file

@ -82,7 +82,7 @@ data class WelcomeState(
@Parcelize
data object CardOne : WelcomeCard() {
override val imageRes: Int get() = R.drawable.img_vault_items
override val titleRes: Int get() = R.string.privacy_prioritized
override val titleRes: Int get() = R.string.security_prioritized
override val messageRes: Int get() = R.string.welcome_message_1
}

View file

@ -0,0 +1,55 @@
package com.x8bit.bitwarden.ui.platform.components.button
import androidx.annotation.DrawableRes
import androidx.compose.material3.FilledIconButton
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.tooling.preview.Preview
import com.x8bit.bitwarden.R
import com.x8bit.bitwarden.ui.platform.components.button.color.bitwardenFilledIconButtonColors
import com.x8bit.bitwarden.ui.platform.components.util.rememberVectorPainter
import com.x8bit.bitwarden.ui.platform.theme.BitwardenTheme
/**
* A filled icon button that displays an icon.
*
* @param vectorIconRes Icon to display on the button.
* @param contentDescription The content description for this icon button.
* @param onClick Callback for when the icon button is clicked.
* @param modifier A [Modifier] for the composable.
* @param isEnabled Whether or not the button should be enabled.
*/
@Composable
fun BitwardenFilledIconButton(
@DrawableRes vectorIconRes: Int,
contentDescription: String,
onClick: () -> Unit,
modifier: Modifier = Modifier,
isEnabled: Boolean = true,
) {
FilledIconButton(
modifier = modifier.semantics(mergeDescendants = true) {},
onClick = onClick,
colors = bitwardenFilledIconButtonColors(),
enabled = isEnabled,
) {
Icon(
painter = rememberVectorPainter(id = vectorIconRes),
contentDescription = contentDescription,
)
}
}
@Preview(showBackground = true)
@Composable
private fun BitwardenFilledIconButton_preview() {
BitwardenTheme {
BitwardenFilledIconButton(
vectorIconRes = R.drawable.ic_question_circle,
contentDescription = "Sample Icon",
onClick = {},
)
}
}

View file

@ -5,6 +5,17 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import com.x8bit.bitwarden.ui.platform.theme.BitwardenTheme
/**
* Provides a default set of Bitwarden-styled colors for a filled icon button.
*/
@Composable
fun bitwardenFilledIconButtonColors(): IconButtonColors = IconButtonColors(
containerColor = BitwardenTheme.colorScheme.filledButton.background,
contentColor = BitwardenTheme.colorScheme.filledButton.foreground,
disabledContainerColor = BitwardenTheme.colorScheme.filledButton.backgroundDisabled,
disabledContentColor = BitwardenTheme.colorScheme.filledButton.foregroundDisabled,
)
/**
* Provides a default set of Bitwarden-styled colors for a standard icon button.
*/

View file

@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.x8bit.bitwarden.ui.platform.base.util.bottomDivider
@ -35,10 +36,8 @@ fun <T> BitwardenContentCard(
Column(
modifier = modifier
.fillMaxWidth()
.background(
color = BitwardenTheme.colorScheme.background.secondary,
shape = BitwardenTheme.shapes.content,
),
.clip(shape = BitwardenTheme.shapes.content)
.background(color = BitwardenTheme.colorScheme.background.secondary),
) {
contentItems.forEachIndexed { index, item ->
Box(

View file

@ -95,7 +95,7 @@ private fun BitwardenContentBlock(
}
Spacer(Modifier.height(12.dp))
}
Spacer(Modifier.width(16.dp))
Spacer(Modifier.width(12.dp))
}
}

View file

@ -7,7 +7,7 @@ import androidx.compose.ui.text.input.KeyboardType
import com.x8bit.bitwarden.R
import com.x8bit.bitwarden.ui.platform.base.util.ZERO_WIDTH_CHARACTER
import com.x8bit.bitwarden.ui.platform.base.util.orNullIfBlank
import com.x8bit.bitwarden.ui.platform.components.button.BitwardenTonalIconButton
import com.x8bit.bitwarden.ui.platform.components.button.BitwardenFilledIconButton
import com.x8bit.bitwarden.ui.platform.components.field.BitwardenTextFieldWithActions
/**
@ -51,7 +51,7 @@ fun BitwardenStepper(
value = clampedValue?.toString() ?: ZERO_WIDTH_CHARACTER,
actionsTestTag = stepperActionsTestTag,
actions = {
BitwardenTonalIconButton(
BitwardenFilledIconButton(
vectorIconRes = R.drawable.ic_minus,
contentDescription = "\u2212",
onClick = {
@ -63,7 +63,7 @@ fun BitwardenStepper(
isEnabled = isDecrementEnabled && !isAtRangeMinimum,
modifier = Modifier.testTag("DecrementValue"),
)
BitwardenTonalIconButton(
BitwardenFilledIconButton(
vectorIconRes = R.drawable.ic_plus,
contentDescription = "+",
onClick = {

View file

@ -22,15 +22,17 @@ import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.toggleableState
import androidx.compose.ui.state.ToggleableState
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.x8bit.bitwarden.R
import com.x8bit.bitwarden.ui.platform.base.util.toAnnotatedString
import com.x8bit.bitwarden.ui.platform.components.button.BitwardenStandardIconButton
import com.x8bit.bitwarden.ui.platform.components.toggle.color.bitwardenSwitchColors
import com.x8bit.bitwarden.ui.platform.theme.BitwardenTheme
/**
* A wide custom switch composable
* A custom switch composable
*
* @param label The descriptive text label to be displayed adjacent to the switch.
* @param isChecked The current state of the switch (either checked or unchecked).
@ -45,7 +47,6 @@ import com.x8bit.bitwarden.ui.platform.theme.BitwardenTheme
* in between the [label] and the toggle. This lambda extends [RowScope], allowing flexibility in
* defining the layout of the actions.
*/
@Suppress("LongMethod")
@Composable
fun BitwardenSwitch(
label: String,
@ -57,6 +58,154 @@ fun BitwardenSwitch(
readOnly: Boolean = false,
enabled: Boolean = true,
actions: (@Composable RowScope.() -> Unit)? = null,
) {
BitwardenSwitch(
modifier = modifier,
label = label.toAnnotatedString(),
isChecked = isChecked,
onCheckedChange = onCheckedChange,
contentDescription = contentDescription,
readOnly = readOnly,
enabled = enabled,
actions = actions,
subContent = {
description?.let {
Text(
text = it,
style = BitwardenTheme.typography.bodyMedium,
color = if (enabled) {
BitwardenTheme.colorScheme.text.secondary
} else {
BitwardenTheme.colorScheme.filledButton.foregroundDisabled
},
)
}
},
)
}
/**
* A custom switch composable
*
* @param label The descriptive text label to be displayed adjacent to the switch.
* @param isChecked The current state of the switch (either checked or unchecked).
* @param onCheckedChange A lambda that is invoked when the switch's state changes.
* @param modifier A [Modifier] that you can use to apply custom modifications to the composable.
* @param description An optional description label to be displayed below the [label].
* @param contentDescription A description of the switch's UI for accessibility purposes.
* @param readOnly Disables the click functionality without modifying the other UI characteristics.
* @param enabled Whether or not this switch is enabled. This is similar to setting [readOnly] but
* comes with some additional visual changes.
* @param actions A lambda containing the set of actions (usually icons or similar) to display
* in between the [label] and the toggle. This lambda extends [RowScope], allowing flexibility in
* defining the layout of the actions.
*/
@Composable
fun BitwardenSwitch(
label: AnnotatedString,
isChecked: Boolean,
onCheckedChange: ((Boolean) -> Unit)?,
modifier: Modifier = Modifier,
description: String? = null,
contentDescription: String? = null,
readOnly: Boolean = false,
enabled: Boolean = true,
actions: (@Composable RowScope.() -> Unit)? = null,
) {
BitwardenSwitch(
modifier = modifier,
label = label,
isChecked = isChecked,
onCheckedChange = onCheckedChange,
contentDescription = contentDescription,
readOnly = readOnly,
enabled = enabled,
actions = actions,
subContent = {
description?.let {
Text(
text = it,
style = BitwardenTheme.typography.bodyMedium,
color = if (enabled) {
BitwardenTheme.colorScheme.text.secondary
} else {
BitwardenTheme.colorScheme.filledButton.foregroundDisabled
},
)
}
},
)
}
/**
* A custom switch composable
*
* @param label The descriptive text label to be displayed adjacent to the switch.
* @param isChecked The current state of the switch (either checked or unchecked).
* @param onCheckedChange A lambda that is invoked when the switch's state changes.
* @param modifier A [Modifier] that you can use to apply custom modifications to the composable.
* @param contentDescription A description of the switch's UI for accessibility purposes.
* @param readOnly Disables the click functionality without modifying the other UI characteristics.
* @param enabled Whether or not this switch is enabled. This is similar to setting [readOnly] but
* comes with some additional visual changes.
* @param actions A lambda containing the set of actions (usually icons or similar) to display
* in between the [label] and the toggle. This lambda extends [RowScope], allowing flexibility in
* defining the layout of the actions.
* @param subContent A lambda containing content directly below the label.
*/
@Composable
fun BitwardenSwitch(
label: String,
isChecked: Boolean,
onCheckedChange: ((Boolean) -> Unit)?,
modifier: Modifier = Modifier,
contentDescription: String? = null,
readOnly: Boolean = false,
enabled: Boolean = true,
actions: (@Composable RowScope.() -> Unit)? = null,
subContent: @Composable () -> Unit,
) {
BitwardenSwitch(
modifier = modifier,
label = label.toAnnotatedString(),
isChecked = isChecked,
onCheckedChange = onCheckedChange,
contentDescription = contentDescription,
readOnly = readOnly,
enabled = enabled,
actions = actions,
subContent = subContent,
)
}
/**
* A custom switch composable
*
* @param label The descriptive text label to be displayed adjacent to the switch.
* @param isChecked The current state of the switch (either checked or unchecked).
* @param onCheckedChange A lambda that is invoked when the switch's state changes.
* @param modifier A [Modifier] that you can use to apply custom modifications to the composable.
* @param contentDescription A description of the switch's UI for accessibility purposes.
* @param readOnly Disables the click functionality without modifying the other UI characteristics.
* @param enabled Whether or not this switch is enabled. This is similar to setting [readOnly] but
* comes with some additional visual changes.
* @param actions A lambda containing the set of actions (usually icons or similar) to display
* in between the [label] and the toggle. This lambda extends [RowScope], allowing flexibility in
* defining the layout of the actions.
* @param subContent A lambda containing content directly below the label.
*/
@Suppress("LongMethod")
@Composable
fun BitwardenSwitch(
label: AnnotatedString,
isChecked: Boolean,
onCheckedChange: ((Boolean) -> Unit)?,
modifier: Modifier = Modifier,
contentDescription: String? = null,
readOnly: Boolean = false,
enabled: Boolean = true,
actions: (@Composable RowScope.() -> Unit)? = null,
subContent: @Composable () -> Unit,
) {
Row(
verticalAlignment = Alignment.CenterVertically,
@ -95,17 +244,7 @@ fun BitwardenSwitch(
},
modifier = Modifier.testTag(tag = "SwitchText"),
)
description?.let {
Text(
text = it,
style = BitwardenTheme.typography.bodyMedium,
color = if (enabled) {
BitwardenTheme.colorScheme.text.secondary
} else {
BitwardenTheme.colorScheme.filledButton.foregroundDisabled
},
)
}
subContent()
}
actions
@ -131,6 +270,7 @@ private fun BitwardenSwitch_preview() {
Column {
BitwardenSwitch(
label = "Label",
description = "description",
isChecked = true,
onCheckedChange = {},
)
@ -141,6 +281,7 @@ private fun BitwardenSwitch_preview() {
)
BitwardenSwitch(
label = "Label",
description = "description",
isChecked = true,
onCheckedChange = {},
actions = {

View file

@ -5,6 +5,7 @@ import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.ExperimentalMaterial3Api
@ -110,6 +111,7 @@ fun DebugMenuScreen(
}
},
)
Spacer(modifier = Modifier.navigationBarsPadding())
}
}
}

View file

@ -524,6 +524,8 @@ private fun ImportLoginsSuccessBottomSheetContent(
iconVectorResource = R.drawable.ic_shield,
),
),
bottomDividerPaddingStart = 48.dp,
showBottomDivider = true,
modifier = Modifier.standardHorizontalMargin(),
) { contentData ->
BitwardenContentBlock(

View file

@ -6,7 +6,6 @@ import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Text
@ -68,8 +67,6 @@ fun ImportLoginsInstructionStep(
) { instructionStep ->
InstructionRowItem(
instructionStep = instructionStep,
modifier = modifier
.padding(all = 12.dp),
)
}
Spacer(Modifier.height(24.dp))

View file

@ -16,6 +16,7 @@ import com.x8bit.bitwarden.R
import com.x8bit.bitwarden.ui.platform.components.button.BitwardenTonalIconButton
import com.x8bit.bitwarden.ui.platform.components.field.BitwardenPasswordFieldWithActions
import com.x8bit.bitwarden.ui.platform.components.field.BitwardenTextField
import com.x8bit.bitwarden.ui.platform.components.field.BitwardenTextFieldWithActions
import com.x8bit.bitwarden.ui.platform.components.header.BitwardenListHeaderText
import com.x8bit.bitwarden.ui.vault.feature.item.handlers.VaultCardItemTypeHandlers
import com.x8bit.bitwarden.ui.vault.feature.item.handlers.VaultCommonItemTypeHandlers
@ -173,14 +174,22 @@ fun VaultItemCardContent(
.padding(horizontal = 16.dp),
)
Spacer(modifier = Modifier.height(8.dp))
BitwardenTextField(
BitwardenTextFieldWithActions(
label = stringResource(id = R.string.notes),
value = notes,
onValueChange = { },
readOnly = true,
singleLine = false,
actions = {
BitwardenTonalIconButton(
vectorIconRes = R.drawable.ic_copy,
contentDescription = stringResource(id = R.string.copy_notes),
onClick = vaultCommonItemTypeHandlers.onCopyNotesClick,
modifier = Modifier.testTag(tag = "CipherNotesCopyButton"),
)
},
textFieldTestTag = "CipherNotesLabel",
modifier = Modifier
.testTag("CipherNotesLabel")
.fillMaxWidth()
.padding(horizontal = 16.dp),
)

View file

@ -13,19 +13,23 @@ import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.x8bit.bitwarden.R
import com.x8bit.bitwarden.ui.platform.components.button.BitwardenTonalIconButton
import com.x8bit.bitwarden.ui.platform.components.field.BitwardenTextField
import com.x8bit.bitwarden.ui.platform.components.field.BitwardenTextFieldWithActions
import com.x8bit.bitwarden.ui.platform.components.header.BitwardenListHeaderText
import com.x8bit.bitwarden.ui.vault.feature.item.handlers.VaultCommonItemTypeHandlers
import com.x8bit.bitwarden.ui.vault.feature.item.handlers.VaultIdentityItemTypeHandlers
/**
* The top level content UI state for the [VaultItemScreen] when viewing a Identity cipher.
*/
@Suppress("LongMethod")
@Suppress("LongMethod", "MaxLineLength")
@Composable
fun VaultItemIdentityContent(
identityState: VaultItemState.ViewState.Content.ItemType.Identity,
commonState: VaultItemState.ViewState.Content.Common,
vaultCommonItemTypeHandlers: VaultCommonItemTypeHandlers,
vaultIdentityItemTypeHandlers: VaultIdentityItemTypeHandlers,
modifier: Modifier = Modifier,
) {
LazyColumn(modifier = modifier) {
@ -54,14 +58,14 @@ fun VaultItemIdentityContent(
identityState.identityName?.let { identityName ->
item {
Spacer(modifier = Modifier.height(8.dp))
BitwardenTextField(
IdentityCopyField(
label = stringResource(id = R.string.identity_name),
value = identityName,
onValueChange = { },
readOnly = true,
singleLine = false,
copyContentDescription = stringResource(id = R.string.copy_identity_name),
textFieldTestTag = "IdentityNameEntry",
copyActionTestTag = "IdentityCopyNameButton",
onCopyClick = vaultIdentityItemTypeHandlers.onCopyIdentityNameClick,
modifier = Modifier
.testTag("IdentityNameEntry")
.fillMaxWidth()
.padding(horizontal = 16.dp),
)
@ -70,14 +74,14 @@ fun VaultItemIdentityContent(
identityState.username?.let { username ->
item {
Spacer(modifier = Modifier.height(8.dp))
BitwardenTextField(
IdentityCopyField(
label = stringResource(id = R.string.username),
value = username,
onValueChange = { },
readOnly = true,
singleLine = false,
copyContentDescription = stringResource(id = R.string.copy_username),
textFieldTestTag = "IdentityUsernameEntry",
copyActionTestTag = "IdentityCopyUsernameButton",
onCopyClick = vaultIdentityItemTypeHandlers.onCopyUsernameClick,
modifier = Modifier
.testTag("IdentityUsernameEntry")
.fillMaxWidth()
.padding(horizontal = 16.dp),
)
@ -86,14 +90,14 @@ fun VaultItemIdentityContent(
identityState.company?.let { company ->
item {
Spacer(modifier = Modifier.height(8.dp))
BitwardenTextField(
IdentityCopyField(
label = stringResource(id = R.string.company),
value = company,
onValueChange = { },
readOnly = true,
singleLine = false,
copyContentDescription = stringResource(id = R.string.copy_company),
textFieldTestTag = "IdentityCompanyEntry",
copyActionTestTag = "IdentityCopyCompanyButton",
onCopyClick = vaultIdentityItemTypeHandlers.onCopyCompanyClick,
modifier = Modifier
.testTag("IdentityCompanyEntry")
.fillMaxWidth()
.padding(horizontal = 16.dp),
)
@ -102,14 +106,14 @@ fun VaultItemIdentityContent(
identityState.ssn?.let { ssn ->
item {
Spacer(modifier = Modifier.height(8.dp))
BitwardenTextField(
IdentityCopyField(
label = stringResource(id = R.string.ssn),
value = ssn,
onValueChange = { },
readOnly = true,
singleLine = false,
copyContentDescription = stringResource(id = R.string.copy_ssn),
textFieldTestTag = "IdentitySsnEntry",
copyActionTestTag = "IdentityCopySsnButton",
onCopyClick = vaultIdentityItemTypeHandlers.onCopySsnClick,
modifier = Modifier
.testTag("IdentitySsnEntry")
.fillMaxWidth()
.padding(horizontal = 16.dp),
)
@ -118,14 +122,14 @@ fun VaultItemIdentityContent(
identityState.passportNumber?.let { passportNumber ->
item {
Spacer(modifier = Modifier.height(8.dp))
BitwardenTextField(
IdentityCopyField(
label = stringResource(id = R.string.passport_number),
value = passportNumber,
onValueChange = { },
readOnly = true,
singleLine = false,
copyContentDescription = stringResource(id = R.string.copy_passport_number),
textFieldTestTag = "IdentityPassportNumberEntry",
copyActionTestTag = "IdentityCopyPassportNumberButton",
onCopyClick = vaultIdentityItemTypeHandlers.onCopyPassportNumberClick,
modifier = Modifier
.testTag("IdentityPassportNumberEntry")
.fillMaxWidth()
.padding(horizontal = 16.dp),
)
@ -134,14 +138,14 @@ fun VaultItemIdentityContent(
identityState.licenseNumber?.let { licenseNumber ->
item {
Spacer(modifier = Modifier.height(8.dp))
BitwardenTextField(
IdentityCopyField(
label = stringResource(id = R.string.license_number),
value = licenseNumber,
onValueChange = { },
readOnly = true,
singleLine = false,
copyContentDescription = stringResource(id = R.string.copy_license_number),
textFieldTestTag = "IdentityLicenseNumberEntry",
copyActionTestTag = "IdentityCopyLicenseNumberButton",
onCopyClick = vaultIdentityItemTypeHandlers.onCopyLicenseNumberClick,
modifier = Modifier
.testTag("IdentityLicenseNumberEntry")
.fillMaxWidth()
.padding(horizontal = 16.dp),
)
@ -150,14 +154,14 @@ fun VaultItemIdentityContent(
identityState.email?.let { email ->
item {
Spacer(modifier = Modifier.height(8.dp))
BitwardenTextField(
IdentityCopyField(
label = stringResource(id = R.string.email),
value = email,
onValueChange = { },
readOnly = true,
singleLine = false,
copyContentDescription = stringResource(id = R.string.copy_email),
textFieldTestTag = "IdentityEmailEntry",
copyActionTestTag = "IdentityCopyEmailButton",
onCopyClick = vaultIdentityItemTypeHandlers.onCopyEmailClick,
modifier = Modifier
.testTag("IdentityEmailEntry")
.fillMaxWidth()
.padding(horizontal = 16.dp),
)
@ -166,14 +170,14 @@ fun VaultItemIdentityContent(
identityState.phone?.let { phone ->
item {
Spacer(modifier = Modifier.height(8.dp))
BitwardenTextField(
IdentityCopyField(
label = stringResource(id = R.string.phone),
value = phone,
onValueChange = { },
readOnly = true,
singleLine = false,
copyContentDescription = stringResource(id = R.string.copy_phone),
textFieldTestTag = "IdentityPhoneEntry",
copyActionTestTag = "IdentityCopyPhoneButton",
onCopyClick = vaultIdentityItemTypeHandlers.onCopyPhoneClick,
modifier = Modifier
.testTag("IdentityPhoneEntry")
.fillMaxWidth()
.padding(horizontal = 16.dp),
)
@ -182,20 +186,19 @@ fun VaultItemIdentityContent(
identityState.address?.let { address ->
item {
Spacer(modifier = Modifier.height(8.dp))
BitwardenTextField(
IdentityCopyField(
label = stringResource(id = R.string.address),
value = address,
onValueChange = { },
readOnly = true,
singleLine = false,
copyContentDescription = stringResource(id = R.string.copy_address),
textFieldTestTag = "IdentityAddressEntry",
copyActionTestTag = "IdentityCopyAddressButton",
onCopyClick = vaultIdentityItemTypeHandlers.onCopyAddressClick,
modifier = Modifier
.testTag("IdentityAddressEntry")
.fillMaxWidth()
.padding(horizontal = 16.dp),
)
}
}
commonState.notes?.let { notes ->
item {
Spacer(modifier = Modifier.height(4.dp))
@ -206,14 +209,14 @@ fun VaultItemIdentityContent(
.padding(horizontal = 16.dp),
)
Spacer(modifier = Modifier.height(8.dp))
BitwardenTextField(
IdentityCopyField(
label = stringResource(id = R.string.notes),
value = notes,
onValueChange = { },
readOnly = true,
singleLine = false,
copyContentDescription = stringResource(id = R.string.copy_notes),
textFieldTestTag = "CipherNotesLabel",
copyActionTestTag = "CipherNotesCopyButton",
onCopyClick = vaultCommonItemTypeHandlers.onCopyNotesClick,
modifier = Modifier
.testTag("CipherNotesLabel")
.fillMaxWidth()
.padding(horizontal = 16.dp),
)
@ -284,3 +287,32 @@ fun VaultItemIdentityContent(
}
}
}
@Composable
private fun IdentityCopyField(
label: String,
value: String,
copyContentDescription: String,
textFieldTestTag: String,
copyActionTestTag: String,
onCopyClick: () -> Unit,
modifier: Modifier = Modifier,
) {
BitwardenTextFieldWithActions(
label = label,
value = value,
onValueChange = { },
readOnly = true,
singleLine = false,
actions = {
BitwardenTonalIconButton(
vectorIconRes = R.drawable.ic_copy,
contentDescription = copyContentDescription,
onClick = onCopyClick,
modifier = Modifier.testTag(tag = copyActionTestTag),
)
},
modifier = modifier,
textFieldTestTag = textFieldTestTag,
)
}

View file

@ -158,8 +158,8 @@ fun VaultItemLoginContent(
Spacer(modifier = Modifier.height(8.dp))
NotesField(
notes = notes,
onCopyAction = vaultCommonItemTypeHandlers.onCopyNotesClick,
modifier = Modifier
.testTag("CipherNotesLabel")
.fillMaxWidth()
.padding(horizontal = 16.dp),
)
@ -273,14 +273,24 @@ private fun Fido2CredentialField(
@Composable
private fun NotesField(
notes: String,
onCopyAction: () -> Unit,
modifier: Modifier = Modifier,
) {
BitwardenTextField(
BitwardenTextFieldWithActions(
label = stringResource(id = R.string.notes),
value = notes,
onValueChange = { },
readOnly = true,
singleLine = false,
actions = {
BitwardenTonalIconButton(
vectorIconRes = R.drawable.ic_copy,
contentDescription = stringResource(id = R.string.copy_notes),
onClick = onCopyAction,
modifier = Modifier.testTag(tag = "CipherNotesCopyButton"),
)
},
textFieldTestTag = "CipherNotesLabel",
modifier = modifier,
)
}

View file

@ -44,6 +44,7 @@ import com.x8bit.bitwarden.ui.platform.manager.intent.IntentManager
import com.x8bit.bitwarden.ui.platform.util.persistentListOfNotNull
import com.x8bit.bitwarden.ui.vault.feature.item.handlers.VaultCardItemTypeHandlers
import com.x8bit.bitwarden.ui.vault.feature.item.handlers.VaultCommonItemTypeHandlers
import com.x8bit.bitwarden.ui.vault.feature.item.handlers.VaultIdentityItemTypeHandlers
import com.x8bit.bitwarden.ui.vault.feature.item.handlers.VaultLoginItemTypeHandlers
import com.x8bit.bitwarden.ui.vault.feature.item.handlers.VaultSshKeyItemTypeHandlers
@ -272,6 +273,9 @@ fun VaultItemScreen(
vaultSshKeyItemTypeHandlers = remember(viewModel) {
VaultSshKeyItemTypeHandlers.create(viewModel = viewModel)
},
vaultIdentityItemTypeHandlers = remember(viewModel) {
VaultIdentityItemTypeHandlers.create(viewModel = viewModel)
},
)
}
}
@ -350,6 +354,7 @@ private fun VaultItemContent(
vaultLoginItemTypeHandlers: VaultLoginItemTypeHandlers,
vaultCardItemTypeHandlers: VaultCardItemTypeHandlers,
vaultSshKeyItemTypeHandlers: VaultSshKeyItemTypeHandlers,
vaultIdentityItemTypeHandlers: VaultIdentityItemTypeHandlers,
modifier: Modifier = Modifier,
) {
when (viewState) {
@ -386,6 +391,7 @@ private fun VaultItemContent(
commonState = viewState.common,
identityState = viewState.type,
vaultCommonItemTypeHandlers = vaultCommonItemTypeHandlers,
vaultIdentityItemTypeHandlers = vaultIdentityItemTypeHandlers,
modifier = modifier,
)
}

View file

@ -16,7 +16,9 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp
import com.x8bit.bitwarden.R
import com.x8bit.bitwarden.ui.platform.components.button.BitwardenTonalIconButton
import com.x8bit.bitwarden.ui.platform.components.field.BitwardenTextField
import com.x8bit.bitwarden.ui.platform.components.field.BitwardenTextFieldWithActions
import com.x8bit.bitwarden.ui.platform.components.header.BitwardenListHeaderText
import com.x8bit.bitwarden.ui.platform.theme.BitwardenTheme
import com.x8bit.bitwarden.ui.vault.feature.item.handlers.VaultCommonItemTypeHandlers
@ -66,14 +68,22 @@ fun VaultItemSecureNoteContent(
.padding(horizontal = 16.dp),
)
Spacer(modifier = Modifier.height(8.dp))
BitwardenTextField(
BitwardenTextFieldWithActions(
label = stringResource(id = R.string.notes),
value = notes,
onValueChange = { },
readOnly = true,
singleLine = false,
actions = {
BitwardenTonalIconButton(
vectorIconRes = R.drawable.ic_copy,
contentDescription = stringResource(id = R.string.copy_notes),
onClick = vaultCommonItemTypeHandlers.onCopyNotesClick,
modifier = Modifier.testTag(tag = "CipherNotesCopyButton"),
)
},
textFieldTestTag = "CipherNotesLabel",
modifier = Modifier
.testTag("CipherNotesLabel")
.fillMaxWidth()
.padding(horizontal = 16.dp),
)

View file

@ -133,6 +133,7 @@ class VaultItemViewModel @Inject constructor(
is VaultItemAction.ItemType.Login -> handleLoginTypeActions(action)
is VaultItemAction.ItemType.Card -> handleCardTypeActions(action)
is VaultItemAction.ItemType.SshKey -> handleSshKeyTypeActions(action)
is VaultItemAction.ItemType.Identity -> handleIdentityTypeActions(action)
is VaultItemAction.Common -> handleCommonActions(action)
is VaultItemAction.Internal -> handleInternalAction(action)
}
@ -184,6 +185,7 @@ class VaultItemViewModel @Inject constructor(
}
is VaultItemAction.Common.RestoreVaultItemClick -> handleRestoreItemClicked()
is VaultItemAction.Common.CopyNotesClick -> handleCopyNotesClick()
}
}
@ -508,6 +510,13 @@ class VaultItemViewModel @Inject constructor(
}
}
private fun handleCopyNotesClick() {
onContent { content ->
val notes = content.common.notes.orEmpty()
clipboardManager.setText(text = notes)
}
}
//endregion Common Handlers
//region Login Type Handlers
@ -812,6 +821,99 @@ class VaultItemViewModel @Inject constructor(
//endregion SSH Key Type Handlers
//region Identity Type Handlers
private fun handleIdentityTypeActions(action: VaultItemAction.ItemType.Identity) {
when (action) {
VaultItemAction.ItemType.Identity.CopyIdentityNameClick -> {
handleCopyIdentityNameClick()
}
VaultItemAction.ItemType.Identity.CopyUsernameClick -> {
handleCopyIdentityUsernameClick()
}
VaultItemAction.ItemType.Identity.CopyCompanyClick -> handleCopyCompanyClick()
VaultItemAction.ItemType.Identity.CopySsnClick -> handleCopySsnClick()
VaultItemAction.ItemType.Identity.CopyPassportNumberClick -> {
handleCopyPassportNumberClick()
}
VaultItemAction.ItemType.Identity.CopyLicenseNumberClick -> {
handleCopyLicenseNumberClick()
}
VaultItemAction.ItemType.Identity.CopyEmailClick -> handleCopyEmailClick()
VaultItemAction.ItemType.Identity.CopyPhoneClick -> handleCopyPhoneClick()
VaultItemAction.ItemType.Identity.CopyAddressClick -> handleCopyAddressClick()
}
}
private fun handleCopyIdentityNameClick() {
onIdentityContent { _, identity ->
val identityName = identity.identityName.orEmpty()
clipboardManager.setText(text = identityName)
}
}
private fun handleCopyIdentityUsernameClick() {
onIdentityContent { _, identity ->
val username = identity.username.orEmpty()
clipboardManager.setText(text = username)
}
}
private fun handleCopyCompanyClick() {
onIdentityContent { _, identity ->
val company = identity.company.orEmpty()
clipboardManager.setText(text = company)
}
}
private fun handleCopySsnClick() {
onIdentityContent { _, identity ->
val ssn = identity.ssn.orEmpty()
clipboardManager.setText(text = ssn)
}
}
private fun handleCopyPassportNumberClick() {
onIdentityContent { _, identity ->
val passportNumber = identity.passportNumber.orEmpty()
clipboardManager.setText(text = passportNumber)
}
}
private fun handleCopyLicenseNumberClick() {
onIdentityContent { _, identity ->
val licenseNumber = identity.licenseNumber.orEmpty()
clipboardManager.setText(text = licenseNumber)
}
}
private fun handleCopyEmailClick() {
onIdentityContent { _, identity ->
val email = identity.email.orEmpty()
clipboardManager.setText(text = email)
}
}
private fun handleCopyPhoneClick() {
onIdentityContent { _, identity ->
val phone = identity.phone.orEmpty()
clipboardManager.setText(text = phone)
}
}
private fun handleCopyAddressClick() {
onIdentityContent { _, identity ->
val address = identity.address.orEmpty()
clipboardManager.setText(text = address)
}
}
//endregion Identity Type Handlers
//region Internal Type Handlers
private fun handleInternalAction(action: VaultItemAction.Internal) {
@ -1133,6 +1235,21 @@ class VaultItemViewModel @Inject constructor(
}
}
}
private inline fun onIdentityContent(
crossinline block: (
VaultItemState.ViewState.Content,
VaultItemState.ViewState.Content.ItemType.Identity,
) -> Unit,
) {
state.viewState.asContentOrNull()
?.let { content ->
(content.type as? VaultItemState.ViewState.Content.ItemType.Identity)
?.let { identityContent ->
block(content, identityContent)
}
}
}
}
/**
@ -1724,6 +1841,11 @@ sealed class VaultItemAction {
* The user confirmed cloning a cipher without its FIDO 2 credentials.
*/
data object ConfirmCloneWithoutFido2CredentialClick : Common()
/**
* The user has clicked the copy button for notes text field.
*/
data object CopyNotesClick : Common()
}
/**
@ -1827,6 +1949,56 @@ sealed class VaultItemAction {
*/
data object CopyFingerprintClick : SshKey()
}
/**
* Represents actions specific to the Identity type.
*/
sealed class Identity : VaultItemAction() {
/**
* The user has clicked the copy button for the identity name.
*/
data object CopyIdentityNameClick : Identity()
/**
* The user has clicked the copy button for the username.
*/
data object CopyUsernameClick : Identity()
/**
* The user has clicked the copy button for the company.
*/
data object CopyCompanyClick : Identity()
/**
* The user has clicked the copy button for the SSN.
*/
data object CopySsnClick : Identity()
/**
* The user has clicked the copy button for the passport number.
*/
data object CopyPassportNumberClick : Identity()
/**
* The user has clicked the copy button for the license number.
*/
data object CopyLicenseNumberClick : Identity()
/**
* The user has clicked the copy button for the email.
*/
data object CopyEmailClick : Identity()
/**
* The user has clicked the copy button for the phone number.
*/
data object CopyPhoneClick : Identity()
/**
* The user has clicked the copy button for the address.
*/
data object CopyAddressClick : Identity()
}
}
/**

View file

@ -21,6 +21,7 @@ data class VaultCommonItemTypeHandlers(
Boolean,
) -> Unit,
val onAttachmentDownloadClick: (VaultItemState.ViewState.Content.Common.AttachmentItem) -> Unit,
val onCopyNotesClick: () -> Unit,
) {
@Suppress("UndocumentedPublicClass")
companion object {
@ -52,6 +53,9 @@ data class VaultCommonItemTypeHandlers(
onAttachmentDownloadClick = {
viewModel.trySendAction(VaultItemAction.Common.AttachmentDownloadClick(it))
},
onCopyNotesClick = {
viewModel.trySendAction(VaultItemAction.Common.CopyNotesClick)
},
)
}
}

View file

@ -0,0 +1,59 @@
package com.x8bit.bitwarden.ui.vault.feature.item.handlers
import com.x8bit.bitwarden.ui.vault.feature.item.VaultItemAction
import com.x8bit.bitwarden.ui.vault.feature.item.VaultItemViewModel
/**
* A collection of handler functions for managing actions within the context of viewing identity
* items in a vault.
*/
data class VaultIdentityItemTypeHandlers(
val onCopyIdentityNameClick: () -> Unit,
val onCopyUsernameClick: () -> Unit,
val onCopyCompanyClick: () -> Unit,
val onCopySsnClick: () -> Unit,
val onCopyPassportNumberClick: () -> Unit,
val onCopyLicenseNumberClick: () -> Unit,
val onCopyEmailClick: () -> Unit,
val onCopyPhoneClick: () -> Unit,
val onCopyAddressClick: () -> Unit,
) {
@Suppress("UndocumentedPublicClass", "MaxLineLength")
companion object {
/**
* Creates the [VaultIdentityItemTypeHandlers] using the [viewModel] to send desired actions.
*/
fun create(
viewModel: VaultItemViewModel,
): VaultIdentityItemTypeHandlers =
VaultIdentityItemTypeHandlers(
onCopyIdentityNameClick = {
viewModel.trySendAction(VaultItemAction.ItemType.Identity.CopyIdentityNameClick)
},
onCopyUsernameClick = {
viewModel.trySendAction(VaultItemAction.ItemType.Identity.CopyUsernameClick)
},
onCopyCompanyClick = {
viewModel.trySendAction(VaultItemAction.ItemType.Identity.CopyCompanyClick)
},
onCopySsnClick = {
viewModel.trySendAction(VaultItemAction.ItemType.Identity.CopySsnClick)
},
onCopyPassportNumberClick = {
viewModel.trySendAction(VaultItemAction.ItemType.Identity.CopyPassportNumberClick)
},
onCopyLicenseNumberClick = {
viewModel.trySendAction(VaultItemAction.ItemType.Identity.CopyLicenseNumberClick)
},
onCopyEmailClick = {
viewModel.trySendAction(VaultItemAction.ItemType.Identity.CopyEmailClick)
},
onCopyPhoneClick = {
viewModel.trySendAction(VaultItemAction.ItemType.Identity.CopyPhoneClick)
},
onCopyAddressClick = {
viewModel.trySendAction(VaultItemAction.ItemType.Identity.CopyAddressClick)
},
)
}
}

View file

@ -1,13 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="18dp"
android:height="18dp"
android:viewportHeight="18"
android:viewportWidth="18">
<group>
<clip-path android:pathData="M1.5,1.5h15v15h-15z" />
<path
android:fillColor="#175DDC"
android:fillType="evenOdd"
android:pathData="M7.125,4.313V5.25H10.875V4.313H7.125ZM6.188,3.844V5.25H1.969C1.71,5.25 1.5,5.46 1.5,5.719V15.094C1.5,15.353 1.71,15.563 1.969,15.563H16.031C16.29,15.563 16.5,15.353 16.5,15.094V5.719C16.5,5.46 16.29,5.25 16.031,5.25H11.813V3.844C11.813,3.585 11.603,3.375 11.344,3.375H6.656C6.397,3.375 6.188,3.585 6.188,3.844ZM15.563,7.125V6.188H2.438V7.125C2.438,8.161 3.277,9 4.313,9H7.125V8.531C7.125,8.272 7.335,8.063 7.594,8.063H10.406C10.665,8.063 10.875,8.272 10.875,8.531V9H13.688C14.723,9 15.563,8.161 15.563,7.125ZM10.875,9.938V10.406C10.875,10.665 10.665,10.875 10.406,10.875H7.594C7.335,10.875 7.125,10.665 7.125,10.406V9.938H4.313C3.592,9.938 2.935,9.667 2.438,9.221V14.625H15.563V9.221C15.065,9.667 14.408,9.938 13.688,9.938H10.875ZM8.063,9H9.938V9.938H8.063V9Z" />
</group>
</vector>

View file

@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="17dp"
android:height="16dp"
android:viewportWidth="17"
android:viewportHeight="16">
<path
android:fillColor="#175DDC"
android:fillType="evenOdd"
android:pathData="M9.434,1.577L11.649,2.5H13.314L15.317,1.948C15.954,1.772 16.583,2.251 16.583,2.912V8.667C16.583,9.491 16.012,10.183 15.244,10.368L14.883,10.85C14.615,11.207 14.195,11.417 13.749,11.417H13.433L13.356,11.701C13.199,12.288 12.685,12.705 12.086,12.747L12.055,12.868C11.866,13.627 11.096,14.089 10.337,13.899L6.567,12.957C5.851,12.778 5.188,12.435 4.628,11.955L0.94,8.794C0.607,8.509 0.416,8.093 0.416,7.655V2.913C0.416,2.251 1.049,1.771 1.687,1.951L3.831,2.554L7.621,1.471C8.219,1.3 8.859,1.337 9.434,1.577ZM8.033,2.913C8.302,2.836 8.59,2.852 8.849,2.958C8.622,3.089 8.409,3.247 8.215,3.43L5.259,6.215C4.61,6.827 4.635,7.866 5.311,8.446L5.771,8.84C6.763,9.69 8.217,9.725 9.249,8.923L10.467,7.975L12.005,9.341C12.258,9.567 12.536,9.759 12.831,9.917H12.282L11.924,11.25L10.914,11.25L10.62,12.424L6.931,11.501C6.441,11.379 5.987,11.144 5.604,10.816L1.916,7.655V3.573L3.834,4.113L8.033,2.913ZM13.703,3.949L15.083,3.568V8.667C15.083,8.805 14.971,8.917 14.833,8.917C14.158,8.917 13.506,8.669 13.001,8.22L10.531,6.025L8.328,7.738C7.859,8.103 7.198,8.087 6.747,7.701L6.288,7.307L9.243,4.522C9.599,4.187 10.069,4 10.558,4H13.326C13.453,4 13.58,3.983 13.703,3.949Z" />
<path
android:fillColor="#175DDC"
android:pathData="M3.154,12.097C2.84,11.828 2.366,11.864 2.097,12.179C1.827,12.493 1.864,12.967 2.178,13.236L3.887,14.701C4.408,15.148 5.052,15.427 5.734,15.503L7.917,15.745C8.328,15.791 8.699,15.495 8.745,15.083C8.791,14.671 8.494,14.3 8.082,14.255L5.899,14.012C5.517,13.97 5.156,13.813 4.863,13.562L3.154,12.097Z" />
</vector>

View file

@ -1,13 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M10.438,5.938C10.023,5.938 9.688,6.273 9.688,6.688C9.688,7.102 10.023,7.438 10.438,7.438H13.563C13.977,7.438 14.313,7.102 14.313,6.688C14.313,6.273 13.977,5.938 13.563,5.938H10.438Z"
android:fillColor="#175DDC"/>
<path
android:pathData="M4.5,4C4.5,2.895 5.395,2 6.5,2H17.5C18.605,2 19.5,2.895 19.5,4V20C19.5,21.105 18.605,22 17.5,22H6.5C5.395,22 4.5,21.105 4.5,20V4ZM6.5,3.5H17.5C17.776,3.5 18,3.724 18,4V20C18,20.276 17.776,20.5 17.5,20.5H6.5C6.224,20.5 6,20.276 6,20V4C6,3.724 6.224,3.5 6.5,3.5Z"
android:fillColor="#175DDC"
android:fillType="evenOdd"/>
</vector>

View file

@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="17dp"
android:height="16dp"
android:viewportWidth="17"
android:viewportHeight="16">
<path
android:fillColor="#175DDC"
android:pathData="M7.25,3C6.836,3 6.5,3.336 6.5,3.75C6.5,4.164 6.836,4.5 7.25,4.5H9.75C10.164,4.5 10.5,4.164 10.5,3.75C10.5,3.336 10.164,3 9.75,3H7.25Z" />
<path
android:fillColor="#175DDC"
android:fillType="evenOdd"
android:pathData="M2.5,2C2.5,0.895 3.395,0 4.5,0H12.5C13.605,0 14.5,0.895 14.5,2V14C14.5,15.105 13.605,16 12.5,16H4.5C3.395,16 2.5,15.105 2.5,14V2ZM4.5,1.5H12.5C12.776,1.5 13,1.724 13,2V14C13,14.276 12.776,14.5 12.5,14.5H4.5C4.224,14.5 4,14.276 4,14V2C4,1.724 4.224,1.5 4.5,1.5Z" />
</vector>

View file

@ -1,13 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="17dp"
android:viewportWidth="16"
android:viewportHeight="17">
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<group>
<clip-path
android:pathData="M0,0.333h16v16h-16z"/>
android:pathData="M0,0.333h24v24h-24z"/>
<path
android:pathData="M7.68,14.333V4.762L5.572,5.306V3.725L8.496,2.433H9.771V14.333H7.68Z"
android:pathData="M11.68,18.333V8.762L9.572,9.306V7.725L12.496,6.433H13.771V18.333H11.68Z"
android:fillColor="#175DDC"/>
</group>
</vector>

View file

@ -1,17 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="17dp"
android:viewportWidth="16"
android:viewportHeight="17">
<group>
<clip-path
android:pathData="M0,0.333h16v16h-16z"/>
<group>
<clip-path
android:pathData="M0,0.333h16v16h-16z"/>
<path
android:pathData="M4.012,14.333V12.854C4.772,12.253 5.497,11.653 6.188,11.052C6.88,10.451 7.503,9.856 8.058,9.267C8.614,8.678 9.05,8.1 9.367,7.533C9.685,6.966 9.843,6.422 9.843,5.901C9.843,5.561 9.781,5.244 9.656,4.949C9.532,4.654 9.333,4.416 9.061,4.235C8.801,4.054 8.449,3.963 8.007,3.963C7.577,3.963 7.208,4.059 6.902,4.252C6.608,4.445 6.387,4.705 6.239,5.034C6.092,5.351 6.018,5.714 6.018,6.122H4.046C4.069,5.261 4.256,4.541 4.607,3.963C4.959,3.385 5.435,2.954 6.035,2.671C6.636,2.376 7.31,2.229 8.058,2.229C8.863,2.229 9.549,2.376 10.115,2.671C10.682,2.966 11.118,3.379 11.424,3.912C11.73,4.445 11.883,5.074 11.883,5.799C11.883,6.332 11.781,6.859 11.577,7.38C11.385,7.89 11.113,8.389 10.761,8.876C10.41,9.352 10.013,9.817 9.571,10.27C9.141,10.712 8.693,11.137 8.228,11.545C7.764,11.942 7.316,12.31 6.885,12.65H12.206V14.333H4.012Z"
android:fillColor="#175DDC"/>
</group>
</group>
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M8.012,18.333V16.854C8.771,16.254 9.496,15.653 10.188,15.052C10.879,14.452 11.502,13.857 12.058,13.267C12.613,12.678 13.049,12.1 13.367,11.533C13.684,10.967 13.843,10.423 13.843,9.901C13.843,9.561 13.78,9.244 13.656,8.949C13.531,8.655 13.333,8.417 13.061,8.235C12.8,8.054 12.449,7.963 12.007,7.963C11.576,7.963 11.208,8.06 10.902,8.252C10.607,8.445 10.386,8.706 10.239,9.034C10.091,9.352 10.018,9.714 10.018,10.123H8.046C8.068,9.261 8.255,8.541 8.607,7.963C8.958,7.385 9.434,6.955 10.035,6.671C10.635,6.377 11.31,6.229 12.058,6.229C12.862,6.229 13.548,6.377 14.115,6.671C14.681,6.966 15.118,7.38 15.424,7.912C15.73,8.445 15.883,9.074 15.883,9.799C15.883,10.332 15.781,10.859 15.577,11.38C15.384,11.891 15.112,12.389 14.761,12.877C14.409,13.352 14.013,13.817 13.571,14.271C13.14,14.712 12.692,15.137 12.228,15.545C11.763,15.942 11.315,16.31 10.885,16.65H16.206V18.333H8.012Z"
android:fillColor="#175DDC"/>
</vector>

View file

@ -1,17 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="17dp"
android:viewportWidth="16"
android:viewportHeight="17">
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<group>
<clip-path
android:pathData="M0,0.333h16v16h-16z"/>
<group>
<clip-path
android:pathData="M0,0.333h16v16h-16z"/>
<path
android:pathData="M8.478,14.537C7.707,14.537 7.004,14.401 6.37,14.129C5.735,13.846 5.225,13.421 4.84,12.854C4.466,12.276 4.267,11.551 4.245,10.678H6.251C6.262,11.075 6.353,11.437 6.523,11.766C6.704,12.083 6.959,12.338 7.288,12.531C7.616,12.712 8.013,12.803 8.478,12.803C8.92,12.803 9.294,12.718 9.6,12.548C9.917,12.378 10.155,12.146 10.314,11.851C10.472,11.556 10.552,11.228 10.552,10.865C10.552,10.423 10.444,10.06 10.229,9.777C10.013,9.482 9.719,9.261 9.345,9.114C8.971,8.967 8.546,8.893 8.07,8.893H7.186V7.21H8.07C8.693,7.21 9.203,7.068 9.6,6.785C9.996,6.49 10.195,6.065 10.195,5.51C10.195,5.045 10.042,4.671 9.736,4.388C9.441,4.105 9.016,3.963 8.461,3.963C7.883,3.963 7.424,4.133 7.084,4.473C6.755,4.813 6.574,5.232 6.54,5.731H4.534C4.568,5.017 4.749,4.399 5.078,3.878C5.418,3.345 5.877,2.937 6.455,2.654C7.033,2.371 7.707,2.229 8.478,2.229C9.282,2.229 9.962,2.371 10.518,2.654C11.073,2.937 11.492,3.317 11.776,3.793C12.07,4.269 12.218,4.79 12.218,5.357C12.218,5.799 12.133,6.201 11.963,6.564C11.793,6.927 11.56,7.233 11.266,7.482C10.982,7.72 10.648,7.896 10.263,8.009C10.705,8.1 11.096,8.275 11.436,8.536C11.787,8.797 12.059,9.131 12.252,9.539C12.456,9.936 12.558,10.4 12.558,10.933C12.558,11.579 12.399,12.18 12.082,12.735C11.776,13.279 11.317,13.715 10.705,14.044C10.104,14.373 9.362,14.537 8.478,14.537Z"
android:fillColor="#175DDC"/>
</group>
android:pathData="M0,0.333h24v24h-24z"/>
<path
android:pathData="M12.477,18.538C11.707,18.538 11.004,18.402 10.369,18.129C9.734,17.846 9.224,17.421 8.839,16.854C8.465,16.277 8.267,15.551 8.244,14.679H10.25C10.262,15.075 10.352,15.438 10.522,15.767C10.703,16.084 10.958,16.339 11.287,16.531C11.616,16.713 12.012,16.803 12.477,16.803C12.919,16.803 13.293,16.719 13.599,16.549C13.917,16.378 14.155,16.146 14.313,15.851C14.472,15.557 14.551,15.228 14.551,14.866C14.551,14.424 14.443,14.061 14.228,13.778C14.013,13.483 13.718,13.262 13.344,13.115C12.97,12.967 12.545,12.894 12.069,12.894H11.185V11.21H12.069C12.693,11.21 13.203,11.069 13.599,10.785C13.996,10.491 14.194,10.066 14.194,9.51C14.194,9.046 14.041,8.672 13.735,8.388C13.441,8.105 13.016,7.963 12.46,7.963C11.882,7.963 11.423,8.133 11.083,8.473C10.755,8.813 10.573,9.233 10.539,9.731H8.533C8.567,9.017 8.748,8.4 9.077,7.878C9.417,7.346 9.876,6.938 10.454,6.654C11.032,6.371 11.707,6.229 12.477,6.229C13.282,6.229 13.962,6.371 14.517,6.654C15.073,6.938 15.492,7.317 15.775,7.793C16.07,8.269 16.217,8.791 16.217,9.357C16.217,9.799 16.132,10.202 15.962,10.564C15.792,10.927 15.56,11.233 15.265,11.483C14.982,11.72 14.648,11.896 14.262,12.009C14.704,12.1 15.095,12.276 15.435,12.536C15.786,12.797 16.059,13.132 16.251,13.54C16.455,13.936 16.557,14.401 16.557,14.934C16.557,15.58 16.399,16.18 16.081,16.736C15.775,17.279 15.316,17.716 14.704,18.045C14.104,18.373 13.361,18.538 12.477,18.538Z"
android:fillColor="#175DDC"/>
</group>
</vector>

View file

@ -1,17 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="17dp"
android:viewportWidth="16"
android:viewportHeight="17">
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<group>
<clip-path
android:pathData="M0,0.333h16v16h-16z"/>
<group>
<clip-path
android:pathData="M0,0.333h16v16h-16z"/>
<path
android:pathData="M9.71,14.333V12.072H3.811V10.44L9.421,2.433H11.733V10.287H13.348V12.072H11.733V14.333H9.71ZM6.004,10.287H9.829V4.677L6.004,10.287Z"
android:fillColor="#175DDC"/>
</group>
android:pathData="M0,0.333h24v24h-24z"/>
<path
android:pathData="M13.71,18.333V16.072H7.811V14.44L13.42,6.433H15.733V14.287H17.347V16.072H15.733V18.333H13.71ZM10.003,14.287H13.828V8.677L10.003,14.287Z"
android:fillColor="#175DDC"/>
</group>
</vector>

View file

@ -952,7 +952,7 @@ Wil u na die rekening omskakel?</string>
<string name="or_log_in_you_may_already_have_an_account">Or log in, you may already have an account.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Get emails from Bitwarden for announcements, advice, and research opportunities. Unsubscribe at any time.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Get advice, announcements, and research opportunities from Bitwarden in your inbox. Unsubscribe at any time.</string>
<string name="privacy_prioritized">Privacy, prioritized</string>
<string name="security_prioritized">Privacy, prioritized</string>
<string name="welcome_message_1">Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect whats important to you.</string>
<string name="welcome_message_2">Set up biometric unlock and autofill to log into your accounts without typing a single letter.</string>
<string name="quick_and_easy_login">Quick and easy login</string>

View file

@ -952,7 +952,7 @@
<string name="or_log_in_you_may_already_have_an_account">أو تسجيل الدخول، قد يكون لديك حساب بالفعل.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">الحصول على رسائل البريد الإلكتروني من Bitwarden للحصول على الإعلانات والنصائح وفرص البحث. إلغاء الاشتراك في أي وقت.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">احصل على المشورة والإعلانات وفرص البحث من Bitwarden في صندوق الوارد الخاص بك. قم بإلغاء الاشتراك في أي وقت.</string>
<string name="privacy_prioritized">الخصوصية، مرتبة حسب الأولوية</string>
<string name="security_prioritized">الخصوصية، مرتبة حسب الأولوية</string>
<string name="welcome_message_1">حفظ تسجيلات الدخول والبطاقات والهويات إلى خزانتك الآمنة. يستخدم Bitwarden المعرفة الصفرية، التشفير من النهاية إلى النهاية لحماية ما هو مهم بالنسبة لك.</string>
<string name="welcome_message_2">قم بإعداد فتح القفل الحيوي والتعبئة التلقائية لتسجيل الدخول إلى حساباتك دون كتابة حرف واحد.</string>
<string name="quick_and_easy_login">تسجيل دخول سريع وسهل</string>

View file

@ -951,7 +951,7 @@ Bu hesaba keçmək istəyirsiniz?</string>
<string name="or_log_in_you_may_already_have_an_account">Ya da bir hesabınız varsa giriş edin.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Elanlar, məsləhətlər və araşdırma fürsətləri üçün Bitwarden-dən e-poçt alın. İstənilən vaxt abunəlikdən çıxa bilərsiniz.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Gələn qutunuzda Bitwarden-dən məsləhət, elan və araşdırma imkanları ilə bağlı məktublar alın. İstənilən vaxt abunəlikdən çıxa bilərsiniz.</string>
<string name="privacy_prioritized">Məxfilik, prioritetdir</string>
<string name="security_prioritized">Məxfilik, prioritetdir</string>
<string name="welcome_message_1">Girişləri, kart və kimlik məlumatlarınızı güvənli seyfinizdə saxlayın. Bitwarden, sizin üçün mühüm olanları qorumaq üçün zero-knowledge və ucdan-uca şifrələmə istifadə edir.</string>
<string name="welcome_message_2">Tək bir hərf yazmadan hesablarınıza giriş etmək üçün biometrik kilid açma və avto-doldurma seçimlərini qurun.</string>
<string name="quick_and_easy_login">Cəld və asan giriş</string>

View file

@ -951,7 +951,7 @@
<string name="or_log_in_you_may_already_have_an_account">Or log in, you may already have an account.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Get emails from Bitwarden for announcements, advice, and research opportunities. Unsubscribe at any time.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Get advice, announcements, and research opportunities from Bitwarden in your inbox. Unsubscribe at any time.</string>
<string name="privacy_prioritized">Privacy, prioritized</string>
<string name="security_prioritized">Privacy, prioritized</string>
<string name="welcome_message_1">Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect whats important to you.</string>
<string name="welcome_message_2">Set up biometric unlock and autofill to log into your accounts without typing a single letter.</string>
<string name="quick_and_easy_login">Quick and easy login</string>

View file

@ -952,7 +952,7 @@
<string name="or_log_in_you_may_already_have_an_account">Или се впишете може вече да имате регистрация.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Получавайте е-писма от Битоурден за новини, съвети и възможности за проучвания. Можете да се отпишете по всяко време.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Получавайте съвети, обявления и предложения за участия в проучвания от Битоурден в е-пощата си. Можете да се отпишете по всяко време.</string>
<string name="privacy_prioritized">Поверителността е от първостепенна важност</string>
<string name="security_prioritized">Поверителността е от първостепенна важност</string>
<string name="welcome_message_1">Съхранявайте данни за вписване, карти и самоличности в своя защитен трезор. Битуорден използва шифроване от край до край за да пази това, което е важно за Вас.</string>
<string name="welcome_message_2">Настройте отключването чрез биометрични данни и автоматичното попълване, за да се вписвате в регистрациите си без да натискате и един клавиш.</string>
<string name="quick_and_easy_login">Бързо и лесно вписване</string>

View file

@ -952,7 +952,7 @@ Do you want to switch to this account?</string>
<string name="or_log_in_you_may_already_have_an_account">Or log in, you may already have an account.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Get emails from Bitwarden for announcements, advice, and research opportunities. Unsubscribe at any time.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Get advice, announcements, and research opportunities from Bitwarden in your inbox. Unsubscribe at any time.</string>
<string name="privacy_prioritized">Privacy, prioritized</string>
<string name="security_prioritized">Privacy, prioritized</string>
<string name="welcome_message_1">Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect whats important to you.</string>
<string name="welcome_message_2">Set up biometric unlock and autofill to log into your accounts without typing a single letter.</string>
<string name="quick_and_easy_login">Quick and easy login</string>

View file

@ -951,7 +951,7 @@ Skeniranje će biti izvršeno automatski.</string>
<string name="or_log_in_you_may_already_have_an_account">Or log in, you may already have an account.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Get emails from Bitwarden for announcements, advice, and research opportunities. Unsubscribe at any time.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Get advice, announcements, and research opportunities from Bitwarden in your inbox. Unsubscribe at any time.</string>
<string name="privacy_prioritized">Privacy, prioritized</string>
<string name="security_prioritized">Privacy, prioritized</string>
<string name="welcome_message_1">Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect whats important to you.</string>
<string name="welcome_message_2">Set up biometric unlock and autofill to log into your accounts without typing a single letter.</string>
<string name="quick_and_easy_login">Quick and easy login</string>

View file

@ -952,7 +952,7 @@ Voleu canviar a aquest compte?</string>
<string name="or_log_in_you_may_already_have_an_account">Or log in, you may already have an account.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Get emails from Bitwarden for announcements, advice, and research opportunities. Unsubscribe at any time.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Get advice, announcements, and research opportunities from Bitwarden in your inbox. Unsubscribe at any time.</string>
<string name="privacy_prioritized">Privacy, prioritized</string>
<string name="security_prioritized">Privacy, prioritized</string>
<string name="welcome_message_1">Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect whats important to you.</string>
<string name="welcome_message_2">Set up biometric unlock and autofill to log into your accounts without typing a single letter.</string>
<string name="quick_and_easy_login">Quick and easy login</string>

View file

@ -951,7 +951,7 @@ Chcete se přepnout na tento účet?</string>
<string name="or_log_in_you_may_already_have_an_account">Nebo se přihlaste, možná už máte účet.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Získejte e-maily od Bitwardenu pro oznámení, poradenství a výzkumné příležitosti. Můžete se kdykoli odhlásit.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Dostávejte do své e-mailové schránky rady, oznámení a příležitosti k výzkumu od společnosti Bitwarden. Odhlásit odběr můžete kdykoli.</string>
<string name="privacy_prioritized">Soukromí, upřednostněno</string>
<string name="security_prioritized">Soukromí, upřednostněno</string>
<string name="welcome_message_1">Uložte si přihlašovací údaje, karty a identity do zabezpečeného trezoru. Bitwarden používá šifrování end-to-end s nulovou znalostí, aby ochránil to, co je pro Vás důležité.</string>
<string name="welcome_message_2">Nastavte biometrické odemknutí a automatické vyplňování pro přihlášení k Vašim účtům bez zadání jediného písmene.</string>
<string name="quick_and_easy_login">Rychlé a snadné přihlášení</string>

View file

@ -952,7 +952,7 @@ Do you want to switch to this account?</string>
<string name="or_log_in_you_may_already_have_an_account">Or log in, you may already have an account.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Get emails from Bitwarden for announcements, advice, and research opportunities. Unsubscribe at any time.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Get advice, announcements, and research opportunities from Bitwarden in your inbox. Unsubscribe at any time.</string>
<string name="privacy_prioritized">Privacy, prioritized</string>
<string name="security_prioritized">Privacy, prioritized</string>
<string name="welcome_message_1">Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect whats important to you.</string>
<string name="welcome_message_2">Set up biometric unlock and autofill to log into your accounts without typing a single letter.</string>
<string name="quick_and_easy_login">Quick and easy login</string>

View file

@ -952,7 +952,7 @@ Skift til denne konto?</string>
<string name="or_log_in_you_may_already_have_an_account">Eller log ind, da en konto muligvis allerede eksisterer.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Få e-mails fra Bitwarden vedr. bekendtgørelser, råd og forskningsmuligheder. Afmeld når som helst.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Få råd, bekendtgørelser og forskningsmuligheder fra Bitwarden i indbakken. Afmeld til enhver tid.</string>
<string name="privacy_prioritized">Fortrolighed, prioriteret</string>
<string name="security_prioritized">Fortrolighed, prioriteret</string>
<string name="welcome_message_1">Gem logins, kort og identiteter i den sikre boks. Bitwarden bruger nul-viden, ende-til-ende kryptering til at beskytte brugerens vigtigt ting.</string>
<string name="welcome_message_2">Opsæt biometrisk oplåsning og autofyld for at logge ind på konti uden at skrive ét enkelt bogstav.</string>
<string name="quick_and_easy_login">Hurtig og nem indlogning</string>

View file

@ -951,7 +951,7 @@ Möchtest du zu diesem Konto wechseln?</string>
<string name="or_log_in_you_may_already_have_an_account">Oder melde dich an, du hast möglicherweise bereits ein Konto.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Erhalte E-Mails von Bitwarden für Ankündigungen, Ratschläge und Marktforschungsumfragen. Melde dich jederzeit wieder ab.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Erhalte Ratschläge, Ankündigungen und Marktforschungsumfragen von Bitwarden in deinem Posteingang. Melde dich jederzeit wieder ab.</string>
<string name="privacy_prioritized">Datenschutz, priorisiert</string>
<string name="security_prioritized">Datenschutz, priorisiert</string>
<string name="welcome_message_1">Speichere Zugangsdaten, Karten und Identitäten in deinem sicheren Tresor. Bitwarden verwendet Zero-Knowledge und Ende-zu-Ende-Verschlüsselung, um das zu schützen, was für dich wichtig ist.</string>
<string name="welcome_message_2">Richte biometrisches Entsperren und Auto-Ausfüllen ein, um dich ohne einen einzigen Buchstaben einzugeben bei deinen Konten anzumelden.</string>
<string name="quick_and_easy_login">Schnelle und einfache Anmeldung</string>

View file

@ -241,7 +241,7 @@
<string name="verification_code_totp">Κωδικός επαλήθευσης (TOTP)</string>
<string name="authenticator_key_added">Το κλειδί επαλήθευσης προστέθηκε.</string>
<string name="authenticator_key_read_error">Αδυναμία ανάγνωσης κλειδιού επαλήθευσης.</string>
<string name="point_your_camera_at_the_qr_code">Σημαδέψτε με την κάμερα σας τον κωδικό QR.
<string name="point_your_camera_at_the_qr_code">Σημαδέψτε με την κάμερα σας τον κωδικό QR.
Η σάρωση θα γίνει αυτόματα.</string>
<string name="scan_qr_title">Σάρωση κώδικα QR</string>
<string name="camera">Κάμερα</string>
@ -952,7 +952,7 @@
<string name="or_log_in_you_may_already_have_an_account">Ή συνδεθείτε, μπορεί να έχετε ήδη λογαριασμό.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Λάβετε μηνύματα ηλ. ταχυδρομείου από το Bitwarden για ανακοινώσεις, συμβουλές και ερευνητικές ευκαιρίες. Ακυρώστε τη συνδρομή σας ανα πάσα στιγμή.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Λάβετε συμβουλές, ανακοινώσεις και ευκαιρίες έρευνας από το Bitwarden στα εισερχόμενά σας. Μπορείτε να απεγγραφείτε ανα πάσα στιγμή.</string>
<string name="privacy_prioritized">Προταιρεότητα, η ιδιωτικότητα</string>
<string name="security_prioritized">Προταιρεότητα, η ιδιωτικότητα</string>
<string name="welcome_message_1">Αποθηκεύστε συνδέσεις, κάρτες και ταυτότητες στο ασφαλές θησαυ/κιό σας. Το Bitwarden χρησιμοποιεί κρυπτογράφηση από άκρο σε άκρο και μηδενικής γνώσης για να προστατεύσει ό,τι είναι σημαντικό για εσάς.</string>
<string name="welcome_message_2">Ρυθμίστε το βιομετρικό ξεκλείδωμα και την αυτόματη συμπλήρωση για σύνδεση στους λογαριασμούς σας χωρίς να πληκτρολογήσετε ούτε ένα γράμμα.</string>
<string name="quick_and_easy_login">Γρήγορη και εύκολη σύνδεση</string>

View file

@ -952,7 +952,7 @@ Do you want to switch to this account?</string>
<string name="or_log_in_you_may_already_have_an_account">Or log in, you may already have an account.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Get emails from Bitwarden for announcements, advice, and research opportunities. Unsubscribe at any time.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Get advice, announcements, and research opportunities from Bitwarden in your inbox. Unsubscribe at any time.</string>
<string name="privacy_prioritized">Privacy, prioritised</string>
<string name="security_prioritized">Privacy, prioritised</string>
<string name="welcome_message_1">Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect whats important to you.</string>
<string name="welcome_message_2">Set up biometric unlock and autofill to log into your accounts without typing a single letter.</string>
<string name="quick_and_easy_login">Quick and easy login</string>

View file

@ -952,7 +952,7 @@ Do you want to switch to this account?</string>
<string name="or_log_in_you_may_already_have_an_account">Or log in, you may already have an account.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Get emails from Bitwarden for announcements, advice, and research opportunities. Unsubscribe at any time.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Get advice, announcements, and research opportunities from Bitwarden in your inbox. Unsubscribe at any time.</string>
<string name="privacy_prioritized">Privacy, prioritised</string>
<string name="security_prioritized">Privacy, prioritised</string>
<string name="welcome_message_1">Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect whats important to you.</string>
<string name="welcome_message_2">Set up biometric unlock and autofill to log into your accounts without typing a single letter.</string>
<string name="quick_and_easy_login">Quick and easy login</string>

View file

@ -953,7 +953,7 @@ seleccione Agregar TOTP para almacenar la clave de forma segura</string>
<string name="or_log_in_you_may_already_have_an_account">Or log in, you may already have an account.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Get emails from Bitwarden for announcements, advice, and research opportunities. Unsubscribe at any time.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Get advice, announcements, and research opportunities from Bitwarden in your inbox. Unsubscribe at any time.</string>
<string name="privacy_prioritized">Privacy, prioritized</string>
<string name="security_prioritized">Privacy, prioritized</string>
<string name="welcome_message_1">Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect whats important to you.</string>
<string name="welcome_message_2">Set up biometric unlock and autofill to log into your accounts without typing a single letter.</string>
<string name="quick_and_easy_login">Quick and easy login</string>

View file

@ -952,7 +952,7 @@ Soovid selle konto peale lülituda?</string>
<string name="or_log_in_you_may_already_have_an_account">Või logi sisse, sul võib olla konto juba olemas.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Get emails from Bitwarden for announcements, advice, and research opportunities. Unsubscribe at any time.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Get advice, announcements, and research opportunities from Bitwarden in your inbox. Unsubscribe at any time.</string>
<string name="privacy_prioritized">Privacy, prioritized</string>
<string name="security_prioritized">Privacy, prioritized</string>
<string name="welcome_message_1">Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect whats important to you.</string>
<string name="welcome_message_2">Set up biometric unlock and autofill to log into your accounts without typing a single letter.</string>
<string name="quick_and_easy_login">Quick and easy login</string>

View file

@ -950,7 +950,7 @@ Kontu honetara aldatu nahi duzu?</string>
<string name="or_log_in_you_may_already_have_an_account">Or log in, you may already have an account.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Get emails from Bitwarden for announcements, advice, and research opportunities. Unsubscribe at any time.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Get advice, announcements, and research opportunities from Bitwarden in your inbox. Unsubscribe at any time.</string>
<string name="privacy_prioritized">Privacy, prioritized</string>
<string name="security_prioritized">Privacy, prioritized</string>
<string name="welcome_message_1">Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect whats important to you.</string>
<string name="welcome_message_2">Set up biometric unlock and autofill to log into your accounts without typing a single letter.</string>
<string name="quick_and_easy_login">Quick and easy login</string>

View file

@ -952,7 +952,7 @@
<string name="or_log_in_you_may_already_have_an_account">Or log in, you may already have an account.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Get emails from Bitwarden for announcements, advice, and research opportunities. Unsubscribe at any time.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Get advice, announcements, and research opportunities from Bitwarden in your inbox. Unsubscribe at any time.</string>
<string name="privacy_prioritized">Privacy, prioritized</string>
<string name="security_prioritized">Privacy, prioritized</string>
<string name="welcome_message_1">Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect whats important to you.</string>
<string name="welcome_message_2">Set up biometric unlock and autofill to log into your accounts without typing a single letter.</string>
<string name="quick_and_easy_login">Quick and easy login</string>

View file

@ -952,7 +952,7 @@ Haluatko vaihtaa tähän tiliin?</string>
<string name="or_log_in_you_may_already_have_an_account">Tai kirjaudu sisään. Sinulla saattaa jo olla tili.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Vastaanota Bitwardenilta uutiskirjeitä julkaisuista, tukiresursseista ja tutkimusmahdollisuuksista. Lopeta tilaus milloin tahansa.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Vastaanota Bitwardenilta postilaatikkoosi vinkkejä, uutisia ja tutkimusmahdollisuuksia. Lopeta tilaus milloin tahansa.</string>
<string name="privacy_prioritized">Yksityisyys etusijalla</string>
<string name="security_prioritized">Yksityisyys etusijalla</string>
<string name="welcome_message_1">Tallenna kirjautumistiedot, kortit and henkilöllisyydet suojattuun holviisi. Bitwarden suojaa tärkeät tietosi nollatietoisella päästä pähän -salauksella.</string>
<string name="welcome_message_2">Määritä biometrinen avaus ja automaattitäyttö kirjautuaksesi tileillesi kirjoittamatta yhtään kirjainta.</string>
<string name="quick_and_easy_login">Nopea ja helppo kirjautuminen</string>

View file

@ -952,7 +952,7 @@ Gusto mo bang pumunta sa account na ito?</string>
<string name="or_log_in_you_may_already_have_an_account">Or log in, you may already have an account.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Get emails from Bitwarden for announcements, advice, and research opportunities. Unsubscribe at any time.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Get advice, announcements, and research opportunities from Bitwarden in your inbox. Unsubscribe at any time.</string>
<string name="privacy_prioritized">Privacy, prioritized</string>
<string name="security_prioritized">Privacy, prioritized</string>
<string name="welcome_message_1">Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect whats important to you.</string>
<string name="welcome_message_2">Set up biometric unlock and autofill to log into your accounts without typing a single letter.</string>
<string name="quick_and_easy_login">Quick and easy login</string>

View file

@ -952,7 +952,7 @@ Voulez-vous basculer vers ce compte ?</string>
<string name="or_log_in_you_may_already_have_an_account">Or log in, you may already have an account.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Get emails from Bitwarden for announcements, advice, and research opportunities. Unsubscribe at any time.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Get advice, announcements, and research opportunities from Bitwarden in your inbox. Unsubscribe at any time.</string>
<string name="privacy_prioritized">Privacy, prioritized</string>
<string name="security_prioritized">Privacy, prioritized</string>
<string name="welcome_message_1">Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect whats important to you.</string>
<string name="welcome_message_2">Set up biometric unlock and autofill to log into your accounts without typing a single letter.</string>
<string name="quick_and_easy_login">Connexion rapide et facile</string>

View file

@ -952,7 +952,7 @@ Do you want to switch to this account?</string>
<string name="or_log_in_you_may_already_have_an_account">Or log in, you may already have an account.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Get emails from Bitwarden for announcements, advice, and research opportunities. Unsubscribe at any time.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Get advice, announcements, and research opportunities from Bitwarden in your inbox. Unsubscribe at any time.</string>
<string name="privacy_prioritized">Privacy, prioritized</string>
<string name="security_prioritized">Privacy, prioritized</string>
<string name="welcome_message_1">Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect whats important to you.</string>
<string name="welcome_message_2">Set up biometric unlock and autofill to log into your accounts without typing a single letter.</string>
<string name="quick_and_easy_login">Quick and easy login</string>

View file

@ -951,7 +951,7 @@ Do you want to switch to this account?</string>
<string name="or_log_in_you_may_already_have_an_account">Or log in, you may already have an account.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Get emails from Bitwarden for announcements, advice, and research opportunities. Unsubscribe at any time.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Get advice, announcements, and research opportunities from Bitwarden in your inbox. Unsubscribe at any time.</string>
<string name="privacy_prioritized">Privacy, prioritized</string>
<string name="security_prioritized">Privacy, prioritized</string>
<string name="welcome_message_1">Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect whats important to you.</string>
<string name="welcome_message_2">Set up biometric unlock and autofill to log into your accounts without typing a single letter.</string>
<string name="quick_and_easy_login">Quick and easy login</string>

View file

@ -950,7 +950,7 @@
<string name="or_log_in_you_may_already_have_an_account">Ili se prijavi, ako već imaš račun.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Primaj e-poštu od Bitwardena s najavamam savjetima i mogućnostima istraživanja. Otkaži pretplatu u bilo kojem trenutku.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Primaj savjete, najave i mogućnosti istraživanja od Bitwardena u svoju Ulaznu poštu. Otkaži pretplatu u bilo kojem trenutku.</string>
<string name="privacy_prioritized">Privatnost na prvom mjestu</string>
<string name="security_prioritized">Privatnost na prvom mjestu</string>
<string name="welcome_message_1">Spremi prijave, kartice i identitete u svoj sigurni trezor. Bitwarden koristi end-to-end enkripciju bez znanja kako bi zaštitio ono što ti je važno.</string>
<string name="welcome_message_2">Uključi biometrijsko otključavanje i auto-ispunu za prijavu bez utipkavanja ijednog slova.</string>
<string name="quick_and_easy_login">Brza i jednostavna prijava</string>

View file

@ -691,7 +691,7 @@
<string name="enter_key_manually">Kód megadása manuálisan</string>
<string name="add_totp">TOTP hozzáadása</string>
<string name="setup_totp">TOTP beállítása</string>
<string name="once_the_key_is_successfully_entered">A kulcs sikeres megadása után válasszuk ki a
<string name="once_the_key_is_successfully_entered">A kulcs sikeres megadása után válasszuk ki a
TOTP hozzáadása a kulcs biztonságos tárolásához lehetőséget.</string>
<string name="never_lock_warning">Ha a zárolási lehetőségeket \"Soha” értékre állítjuk, akkor a széf bárki számára elérhető lesz, aki hozzáfér az eszközhöz. Ha ezt az opciót használjuk, akkor gondoskodni kell arról, hogy az eszköz megfelelően védett legyen.</string>
<string name="environment_page_urls_error">A beírt webcímek közül egy vagy több érvénytelen. Vizsgáljuk át és próbáljuk meg újra elmenteni.</string>
@ -951,7 +951,7 @@ Szeretnénk átváltani erre a fiókra?</string>
<string name="or_log_in_you_may_already_have_an_account">Vagy Bejelentkezés, ha már van fiók.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Emaileket kaphatunk a Bitwardentől bejelentésekről, tanácsokról és kutatási lehetőségekről. Bármikor leiratkozhatunk.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Tanácsokat, bejelentéseket és kutatási lehetőségeket kaphatunk a Bitwardentől a postaládába. Bármikor leiratkozhatunk.</string>
<string name="privacy_prioritized">Adatvédelem, prioritás</string>
<string name="security_prioritized">Adatvédelem, prioritás</string>
<string name="welcome_message_1">Mentsük el a bejelentkezési adatokat, kártyákat és azonosításokat a biztonságos széfbe. A Bitwarden tudás nélküli, végpontok közötti titkosítást használ a felhasználók számára fontos dolgok védelmére.</string>
<string name="welcome_message_2">Állítsuk be a biometrikus feloldást és az automatikus kitöltést, hogy egyetlen betű beírása nélkül jelentkezzünk be a fiókokba.</string>
<string name="quick_and_easy_login">Gyors és könnyű bejelentkezés</string>

View file

@ -952,7 +952,7 @@ Do you want to switch to this account?</string>
<string name="or_log_in_you_may_already_have_an_account">Or log in, you may already have an account.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Get emails from Bitwarden for announcements, advice, and research opportunities. Unsubscribe at any time.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Get advice, announcements, and research opportunities from Bitwarden in your inbox. Unsubscribe at any time.</string>
<string name="privacy_prioritized">Privacy, prioritized</string>
<string name="security_prioritized">Privacy, prioritized</string>
<string name="welcome_message_1">Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect whats important to you.</string>
<string name="welcome_message_2">Set up biometric unlock and autofill to log into your accounts without typing a single letter.</string>
<string name="quick_and_easy_login">Quick and easy login</string>

View file

@ -951,7 +951,7 @@ Vuoi passare a questo account?</string>
<string name="or_log_in_you_may_already_have_an_account">Oppure effettua l\'accesso se potresti avere già un account.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Ricevi email da Bitwarden per annunci, consigli e opportunità di ricerca. Disiscriviti in qualsiasi momento.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Ottieni consigli, annunci e opportunità di ricerca da Bitwarden nella tua casella di posta. Disiscriviti in qualsiasi momento.</string>
<string name="privacy_prioritized">Privacy, al primo posto</string>
<string name="security_prioritized">Privacy, al primo posto</string>
<string name="welcome_message_1">Salva login, carte e identità nella tua cassaforte sicura. Bitwarden usa la crittografia end-to-end e zero-knowledge per proteggere ciò che è importante.</string>
<string name="welcome_message_2">Imposta lo sblocco biometrico e il riempimento automatico per accedere ai tuoi account senza digitare una sola lettera.</string>
<string name="quick_and_easy_login">Accesso facile e veloce</string>

View file

@ -207,7 +207,7 @@
<string name="off" tools:override="true">כבוי</string>
<string name="on" tools:override="true">פעיל</string>
<string name="status">סטטוס</string>
<string name="bitwarden_autofill_service_alert2">הדרך הקלה ביותר להוספת סיסמאות לכספת היא דרך שירות ההשלמה האוטומטי של Bitwarden. למד עוד אודות השימוש ביכולת ההשלמה האוטומטית של
<string name="bitwarden_autofill_service_alert2">הדרך הקלה ביותר להוספת סיסמאות לכספת היא דרך שירות ההשלמה האוטומטי של Bitwarden. למד עוד אודות השימוש ביכולת ההשלמה האוטומטית של
Bitwarden בעזרת פתיחת חלון \"הגדרות\".</string>
<string name="autofill">השלמה אוטומטית</string>
<string name="autofill_or_view">האם ברצונך להפעיל את ההשלמה האוטומטית או לצפות בפריט זה?</string>
@ -955,7 +955,7 @@ Do you want to switch to this account?</string>
<string name="or_log_in_you_may_already_have_an_account">Or log in, you may already have an account.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Get emails from Bitwarden for announcements, advice, and research opportunities. Unsubscribe at any time.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Get advice, announcements, and research opportunities from Bitwarden in your inbox. Unsubscribe at any time.</string>
<string name="privacy_prioritized">Privacy, prioritized</string>
<string name="security_prioritized">Privacy, prioritized</string>
<string name="welcome_message_1">Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect whats important to you.</string>
<string name="welcome_message_2">Set up biometric unlock and autofill to log into your accounts without typing a single letter.</string>
<string name="quick_and_easy_login">Quick and easy login</string>

View file

@ -952,7 +952,7 @@
<string name="or_log_in_you_may_already_have_an_account">またはログインしてください。すでにアカウントを持っている可能性があります。</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Bitwarden からメールでお知らせやアドバイス、アンケートを受け取ります。配信停止はいつでもできます。</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Bitwarden からメールでアドバイスや告知、アンケートを受け取りましょう。配信停止はいつでもできます。</string>
<string name="privacy_prioritized">プライバシーが最優先</string>
<string name="security_prioritized">プライバシーが最優先</string>
<string name="welcome_message_1">ログイン情報、カード、ID を安全な保管庫に保存します。Bitwarden はゼロ知識、エンドツーエンドの暗号化を使用して、あなたにとって重要なものを保護します。</string>
<string name="welcome_message_2">生体認証のロック解除と自動入力を設定して、文字を何も入力せずにアカウントにログインします。</string>
<string name="quick_and_easy_login">すばやく簡単にログイン</string>

View file

@ -952,7 +952,7 @@ Do you want to switch to this account?</string>
<string name="or_log_in_you_may_already_have_an_account">Or log in, you may already have an account.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Get emails from Bitwarden for announcements, advice, and research opportunities. Unsubscribe at any time.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Get advice, announcements, and research opportunities from Bitwarden in your inbox. Unsubscribe at any time.</string>
<string name="privacy_prioritized">Privacy, prioritized</string>
<string name="security_prioritized">Privacy, prioritized</string>
<string name="welcome_message_1">Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect whats important to you.</string>
<string name="welcome_message_2">Set up biometric unlock and autofill to log into your accounts without typing a single letter.</string>
<string name="quick_and_easy_login">Quick and easy login</string>

View file

@ -952,7 +952,7 @@ Do you want to switch to this account?</string>
<string name="or_log_in_you_may_already_have_an_account">Or log in, you may already have an account.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Get emails from Bitwarden for announcements, advice, and research opportunities. Unsubscribe at any time.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Get advice, announcements, and research opportunities from Bitwarden in your inbox. Unsubscribe at any time.</string>
<string name="privacy_prioritized">Privacy, prioritized</string>
<string name="security_prioritized">Privacy, prioritized</string>
<string name="welcome_message_1">Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect whats important to you.</string>
<string name="welcome_message_2">Set up biometric unlock and autofill to log into your accounts without typing a single letter.</string>
<string name="quick_and_easy_login">Quick and easy login</string>

View file

@ -952,7 +952,7 @@
<string name="or_log_in_you_may_already_have_an_account">Or log in, you may already have an account.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Get emails from Bitwarden for announcements, advice, and research opportunities. Unsubscribe at any time.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Get advice, announcements, and research opportunities from Bitwarden in your inbox. Unsubscribe at any time.</string>
<string name="privacy_prioritized">Privacy, prioritized</string>
<string name="security_prioritized">Privacy, prioritized</string>
<string name="welcome_message_1">Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect whats important to you.</string>
<string name="welcome_message_2">Set up biometric unlock and autofill to log into your accounts without typing a single letter.</string>
<string name="quick_and_easy_login">Quick and easy login</string>

View file

@ -952,7 +952,7 @@ Ar norite pereiti prie šios paskyros?</string>
<string name="or_log_in_you_may_already_have_an_account">Or log in, you may already have an account.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Get emails from Bitwarden for announcements, advice, and research opportunities. Unsubscribe at any time.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Get advice, announcements, and research opportunities from Bitwarden in your inbox. Unsubscribe at any time.</string>
<string name="privacy_prioritized">Privacy, prioritized</string>
<string name="security_prioritized">Privacy, prioritized</string>
<string name="welcome_message_1">Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect whats important to you.</string>
<string name="welcome_message_2">Set up biometric unlock and autofill to log into your accounts without typing a single letter.</string>
<string name="quick_and_easy_login">Quick and easy login</string>

View file

@ -952,7 +952,7 @@ Vai pārslēgties uz šo kontu?</string>
<string name="or_log_in_you_may_already_have_an_account">Vai jāmēģina pieteikties, varbūt Tev jau ir konts.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Saņemt e-pasta ziņojumus no Bitwarden par paziņojumiem, padomiem un izpētes iespējām. Abonēšanu atteikt var jebkurā brīdī.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Iegūt savā iesūtnē padomus, paziņojumus un izpētes iespējas no Bitwarden. Atrakstīties var jebkurā brīdī.</string>
<string name="privacy_prioritized">Privātums pirmajā vietā</string>
<string name="security_prioritized">Privātums pirmajā vietā</string>
<string name="welcome_message_1">Pieteikšanās vienumu, karšu un identitāšu glabāšana savā drošajā glabātavā. Bitwarden izmanto nulles zināšanu pilnīgu šifrēšanu, lai aizsargātu to, kas Tev ir svarīgs.</string>
<string name="welcome_message_2">Iestati biometrisko atslēgšanu un automātiski aizpildi, lai pieteiktos savos kontos bez neviena burta ievadīšanas.</string>
<string name="quick_and_easy_login">Ātra un vienkārša pieteikšanās</string>

View file

@ -952,7 +952,7 @@ Do you want to switch to this account?</string>
<string name="or_log_in_you_may_already_have_an_account">Or log in, you may already have an account.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Get emails from Bitwarden for announcements, advice, and research opportunities. Unsubscribe at any time.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Get advice, announcements, and research opportunities from Bitwarden in your inbox. Unsubscribe at any time.</string>
<string name="privacy_prioritized">Privacy, prioritized</string>
<string name="security_prioritized">Privacy, prioritized</string>
<string name="welcome_message_1">Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect whats important to you.</string>
<string name="welcome_message_2">Set up biometric unlock and autofill to log into your accounts without typing a single letter.</string>
<string name="quick_and_easy_login">Quick and easy login</string>

View file

@ -952,7 +952,7 @@ Do you want to switch to this account?</string>
<string name="or_log_in_you_may_already_have_an_account">Or log in, you may already have an account.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Get emails from Bitwarden for announcements, advice, and research opportunities. Unsubscribe at any time.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Get advice, announcements, and research opportunities from Bitwarden in your inbox. Unsubscribe at any time.</string>
<string name="privacy_prioritized">Privacy, prioritized</string>
<string name="security_prioritized">Privacy, prioritized</string>
<string name="welcome_message_1">Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect whats important to you.</string>
<string name="welcome_message_2">Set up biometric unlock and autofill to log into your accounts without typing a single letter.</string>
<string name="quick_and_easy_login">Quick and easy login</string>

View file

@ -952,7 +952,7 @@ Do you want to switch to this account?</string>
<string name="or_log_in_you_may_already_have_an_account">Or log in, you may already have an account.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Get emails from Bitwarden for announcements, advice, and research opportunities. Unsubscribe at any time.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Get advice, announcements, and research opportunities from Bitwarden in your inbox. Unsubscribe at any time.</string>
<string name="privacy_prioritized">Privacy, prioritized</string>
<string name="security_prioritized">Privacy, prioritized</string>
<string name="welcome_message_1">Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect whats important to you.</string>
<string name="welcome_message_2">Set up biometric unlock and autofill to log into your accounts without typing a single letter.</string>
<string name="quick_and_easy_login">Quick and easy login</string>

View file

@ -952,7 +952,7 @@ Vil du bytte til denne kontoen?</string>
<string name="or_log_in_you_may_already_have_an_account">Or log in, you may already have an account.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Get emails from Bitwarden for announcements, advice, and research opportunities. Unsubscribe at any time.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Get advice, announcements, and research opportunities from Bitwarden in your inbox. Unsubscribe at any time.</string>
<string name="privacy_prioritized">Privacy, prioritized</string>
<string name="security_prioritized">Privacy, prioritized</string>
<string name="welcome_message_1">Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect whats important to you.</string>
<string name="welcome_message_2">Set up biometric unlock and autofill to log into your accounts without typing a single letter.</string>
<string name="quick_and_easy_login">Quick and easy login</string>

View file

@ -952,7 +952,7 @@ Do you want to switch to this account?</string>
<string name="or_log_in_you_may_already_have_an_account">Or log in, you may already have an account.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Get emails from Bitwarden for announcements, advice, and research opportunities. Unsubscribe at any time.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Get advice, announcements, and research opportunities from Bitwarden in your inbox. Unsubscribe at any time.</string>
<string name="privacy_prioritized">Privacy, prioritized</string>
<string name="security_prioritized">Privacy, prioritized</string>
<string name="welcome_message_1">Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect whats important to you.</string>
<string name="welcome_message_2">Set up biometric unlock and autofill to log into your accounts without typing a single letter.</string>
<string name="quick_and_easy_login">Quick and easy login</string>

View file

@ -952,7 +952,7 @@ Wilt u naar dit account wisselen?</string>
<string name="or_log_in_you_may_already_have_an_account">Of ga naar inloggen, je hebt mogelijk al een account.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Ontvang e-mailberichten van Bitwarden voor aankondigingen, advies en onderzoeksmogelijkheden. Afmelden kan op ieder moment.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Ontvang advies, aankondigingen en onderzoeksmogelijkheden van Bitwarden in je inbox. Je kunt je op ieder moment uitschrijven.</string>
<string name="privacy_prioritized">Privacy, geprioriteerd</string>
<string name="security_prioritized">Privacy, geprioriteerd</string>
<string name="welcome_message_1">Logins, kaarten en identiteiten in je beveiligde kluis opslaan. Bitwarden gebruikt zero-knowledge, end-to-end versleuteling om te beschermen wat belangrijk voor jou is.</string>
<string name="welcome_message_2">Biometrische ontgrendelen en automatisch invullen instellen zodat je kunt inloggen op je accounts zonder één letter te typen.</string>
<string name="quick_and_easy_login">Snel en eenvoudig inloggen</string>

View file

@ -952,7 +952,7 @@ Do you want to switch to this account?</string>
<string name="or_log_in_you_may_already_have_an_account">Eller logg inn, det kan hende du allereie har ein konto.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Få e-post frå Bitwarden for kunngjeringar, råd og forskingsmoglegheiter. Slutt å abonnere på det når som helst.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Get advice, announcements, and research opportunities from Bitwarden in your inbox. Unsubscribe at any time.</string>
<string name="privacy_prioritized">Privacy, prioritized</string>
<string name="security_prioritized">Privacy, prioritized</string>
<string name="welcome_message_1">Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect whats important to you.</string>
<string name="welcome_message_2">Set up biometric unlock and autofill to log into your accounts without typing a single letter.</string>
<string name="quick_and_easy_login">Quick and easy login</string>

View file

@ -952,7 +952,7 @@ Do you want to switch to this account?</string>
<string name="or_log_in_you_may_already_have_an_account">Or log in, you may already have an account.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Get emails from Bitwarden for announcements, advice, and research opportunities. Unsubscribe at any time.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Get advice, announcements, and research opportunities from Bitwarden in your inbox. Unsubscribe at any time.</string>
<string name="privacy_prioritized">Privacy, prioritized</string>
<string name="security_prioritized">Privacy, prioritized</string>
<string name="welcome_message_1">Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect whats important to you.</string>
<string name="welcome_message_2">Set up biometric unlock and autofill to log into your accounts without typing a single letter.</string>
<string name="quick_and_easy_login">Quick and easy login</string>

View file

@ -952,7 +952,7 @@ Czy chcesz przełączyć się na to konto?</string>
<string name="or_log_in_you_may_already_have_an_account">Lub zaloguj się, jeśli już posiadasz konto.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Otrzymuj wiadomości e-mail od Bitwarden z ogłoszeniami, poradami i możliwościami badawczymi. Możesz anulować subskrypcję w dowolnym momencie.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Otrzymuj porady, ogłoszenia i możliwości badawcze od Bitwarden w swojej skrzynce odbiorczej. Możesz anulować subskrypcję w dowolnym momencie.</string>
<string name="privacy_prioritized">Privacy, prioritized</string>
<string name="security_prioritized">Privacy, prioritized</string>
<string name="welcome_message_1">Zapisz dane logowania, karty i tożsamości w bezpiecznym sejfie. Bitwarden używa szyfrowania end-to-end w celu ochrony tego, co jest dla Ciebie ważne.</string>
<string name="welcome_message_2">Skonfiguruj odblokowanie i autouzupełnianie biometryczne, aby zalogować się na swoje konta bez wpisywania nawet pojedynczej litery.</string>
<string name="quick_and_easy_login">Szybkie i łatwe logowanie</string>

View file

@ -952,7 +952,7 @@ Você deseja mudar para esta conta?</string>
<string name="or_log_in_you_may_already_have_an_account">Ou faça o login, você pode já ter uma conta.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Obtenha e-mails do Bitwarden para anúncios, conselhos e oportunidades de pesquisa. Cancele a inscrição a qualquer momento.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Receba conselhos, anúncios e oportunidades de pesquisa da Bitwarden na sua caixa de entrada. Cancele a assinatura a qualquer momento.</string>
<string name="privacy_prioritized">Privacidade, priorizado</string>
<string name="security_prioritized">Privacidade, priorizado</string>
<string name="welcome_message_1">Salve suas credenciais, cartões e identidades no seu cofre seguro. O Bitwarden usa criptografia de zero conhecimento, de ponta a ponta para proteger o que é importante para você.</string>
<string name="welcome_message_2">Configure o desbloqueio biométrico e preenchimento automático para acessar suas contas sem digitar uma única letra.</string>
<string name="quick_and_easy_login">Login rápido e fácil</string>

View file

@ -952,7 +952,7 @@ Pretende mudar para esta conta?</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Receba e-mails do Bitwarden com anúncios, conselhos e oportunidades de investigação.
Anule a subscrição em qualquer altura.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Receba conselhos, anúncios e oportunidades de investigação do Bitwarden na sua caixa de entrada. Anule a subscrição a qualquer altura.</string>
<string name="privacy_prioritized">Privacidade, priorizada</string>
<string name="security_prioritized">Privacidade, priorizada</string>
<string name="welcome_message_1">Guarde credenciais, cartões e identidades no seu cofre seguro. O Bitwarden utiliza encriptação de conhecimento zero e de ponto a ponto para proteger o que é importante para si.</string>
<string name="welcome_message_2">Configure o desbloqueio biométrico e o preenchimento automático para iniciar sessão nas suas contas sem escrever uma única letra.</string>
<string name="quick_and_easy_login">Início de sessão rápido e fácil</string>

View file

@ -952,7 +952,7 @@ Doriți să comutați la acest cont?</string>
<string name="or_log_in_you_may_already_have_an_account">Or log in, you may already have an account.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Get emails from Bitwarden for announcements, advice, and research opportunities. Unsubscribe at any time.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Get advice, announcements, and research opportunities from Bitwarden in your inbox. Unsubscribe at any time.</string>
<string name="privacy_prioritized">Privacy, prioritized</string>
<string name="security_prioritized">Privacy, prioritized</string>
<string name="welcome_message_1">Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect whats important to you.</string>
<string name="welcome_message_2">Set up biometric unlock and autofill to log into your accounts without typing a single letter.</string>
<string name="quick_and_easy_login">Autentificare rapidă și ușoară</string>

View file

@ -954,7 +954,7 @@
<string name="or_log_in_you_may_already_have_an_account">Или авторизуйтесь, возможно, у вас уже есть аккаунт.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Получайте электронные письма от Bitwarden с анонсами, советами и возможностями для исследований. Отписаться можно в любое время.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Получайте советы, объявления и исследования от Bitwarden в свой почтовый ящик. Отписаться можно в любое время.</string>
<string name="privacy_prioritized">Конфиденциальность, приоритет</string>
<string name="security_prioritized">Конфиденциальность, приоритет</string>
<string name="welcome_message_1">Сохраняйте логины, карты и личные данные в своем защищенном хранилище. Bitwarden использует сквозное шифрование, чтобы защитить то, что для вас важно.</string>
<string name="welcome_message_2">Настройте биометрическую разблокировку и автозаполнение, чтобы входить в свои аккаунты, не набирая ни одной буквы.</string>
<string name="quick_and_easy_login">Быстрая и простая авторизация</string>

View file

@ -952,7 +952,7 @@ Do you want to switch to this account?</string>
<string name="or_log_in_you_may_already_have_an_account">Or log in, you may already have an account.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Get emails from Bitwarden for announcements, advice, and research opportunities. Unsubscribe at any time.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Get advice, announcements, and research opportunities from Bitwarden in your inbox. Unsubscribe at any time.</string>
<string name="privacy_prioritized">Privacy, prioritized</string>
<string name="security_prioritized">Privacy, prioritized</string>
<string name="welcome_message_1">Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect whats important to you.</string>
<string name="welcome_message_2">Set up biometric unlock and autofill to log into your accounts without typing a single letter.</string>
<string name="quick_and_easy_login">Quick and easy login</string>

View file

@ -952,7 +952,7 @@ Chcete prepnúť na tento účet?</string>
<string name="or_log_in_you_may_already_have_an_account">Alebo sa prihláste, možno už účet máte.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Dostávať e-maily od Bitwardenu s oznámeniami, radami a možnosťami výskumu. Odhlásiť dá môžete kedykoľvek.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Dostávajte do schránky rady, oznámenia a príležitosti na výskum od spoločnosti Bitwarden. Kedykoľvek sa môžete odhlásiť z odberu.</string>
<string name="privacy_prioritized">Súkromie na prvom mieste</string>
<string name="security_prioritized">Súkromie na prvom mieste</string>
<string name="welcome_message_1">Ukladajte prihlasovacie údaje, karty a identity do zabezpečeného trezoru. Bitwarden používa šifrovanie s nulovou znalosťou od začiatku do konca na ochranu toho, čo je pre vás dôležité.</string>
<string name="welcome_message_2">Nastavte si odomykanie biometrickými údajmi a automatické vypĺňanie na prihlasovanie do účtov bez zadávania jediného písmena.</string>
<string name="quick_and_easy_login">Rýchle a jednoduché prihlásenie</string>

View file

@ -952,7 +952,7 @@ Do you want to switch to this account?</string>
<string name="or_log_in_you_may_already_have_an_account">Or log in, you may already have an account.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Get emails from Bitwarden for announcements, advice, and research opportunities. Unsubscribe at any time.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Get advice, announcements, and research opportunities from Bitwarden in your inbox. Unsubscribe at any time.</string>
<string name="privacy_prioritized">Privacy, prioritized</string>
<string name="security_prioritized">Privacy, prioritized</string>
<string name="welcome_message_1">Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect whats important to you.</string>
<string name="welcome_message_2">Set up biometric unlock and autofill to log into your accounts without typing a single letter.</string>
<string name="quick_and_easy_login">Quick and easy login</string>

View file

@ -953,7 +953,7 @@
<string name="or_log_in_you_may_already_have_an_account">Или пријавите се, можда већ имате налог.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Добијајте имјл од Bitwarden-а за најаве, савете и могућности истраживања. Откажите претплату у било ком тренутку.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Добијајте савете, најаве и могућности истраживања од Bitwarden-а у пријемном сандучету. Откажите претплату у било ком тренутку.</string>
<string name="privacy_prioritized">Приватност, приоритет</string>
<string name="security_prioritized">Приватност, приоритет</string>
<string name="welcome_message_1">Сачувајте пријаве, картице и идентитете у свој безбедни сеф. Bitwarden користи шифровање од почетка-до-краја да заштити оно што вам је важно.</string>
<string name="welcome_message_2">Подесите биометријско откључавање и аутоматско попуњавање да бисте се пријавили на своје налоге без уноса ниједног слова.</string>
<string name="quick_and_easy_login">Брза и лака пријава</string>

View file

@ -221,7 +221,7 @@
<string name="enter_verification_code_app">Ange den 6-siffriga verifieringskoden från din autentiseringsapp.</string>
<string name="enter_verification_code_email">Ange den 6-siffriga verifieringskoden som skickades till %1$s.</string>
<string name="login_unavailable">Inloggning ej tillgänglig</string>
<string name="no_two_step_available">Detta konto har tvåstegsverifiering aktiverat, men ingen av de konfigurerade metoderna stöds av den här enheten.
<string name="no_two_step_available">Detta konto har tvåstegsverifiering aktiverat, men ingen av de konfigurerade metoderna stöds av den här enheten.
Vänligen använd en enhet som stöds och/eller lägg till fler metoder som har bättre stöd bland enheter (t.ex. en autentiseringsapp).</string>
<string name="recovery_code_title">Återställningskod</string>
<string name="remember_me">Kom ihåg mig</string>
@ -953,7 +953,7 @@ Vill du byta till detta konto?</string>
<string name="or_log_in_you_may_already_have_an_account">Eller logga in, du kanske redan har ett konto.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Get emails from Bitwarden for announcements, advice, and research opportunities. Unsubscribe at any time.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Get advice, announcements, and research opportunities from Bitwarden in your inbox. Unsubscribe at any time.</string>
<string name="privacy_prioritized">Privacy, prioritized</string>
<string name="security_prioritized">Privacy, prioritized</string>
<string name="welcome_message_1">Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect whats important to you.</string>
<string name="welcome_message_2">Set up biometric unlock and autofill to log into your accounts without typing a single letter.</string>
<string name="quick_and_easy_login">Quick and easy login</string>

View file

@ -952,7 +952,7 @@
<string name="or_log_in_you_may_already_have_an_account">Or log in, you may already have an account.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Get emails from Bitwarden for announcements, advice, and research opportunities. Unsubscribe at any time.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Get advice, announcements, and research opportunities from Bitwarden in your inbox. Unsubscribe at any time.</string>
<string name="privacy_prioritized">Privacy, prioritized</string>
<string name="security_prioritized">Privacy, prioritized</string>
<string name="welcome_message_1">Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect whats important to you.</string>
<string name="welcome_message_2">Set up biometric unlock and autofill to log into your accounts without typing a single letter.</string>
<string name="quick_and_easy_login">Quick and easy login</string>

View file

@ -952,7 +952,7 @@ Do you want to switch to this account?</string>
<string name="or_log_in_you_may_already_have_an_account">Or log in, you may already have an account.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Get emails from Bitwarden for announcements, advice, and research opportunities. Unsubscribe at any time.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Get advice, announcements, and research opportunities from Bitwarden in your inbox. Unsubscribe at any time.</string>
<string name="privacy_prioritized">Privacy, prioritized</string>
<string name="security_prioritized">Privacy, prioritized</string>
<string name="welcome_message_1">Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect whats important to you.</string>
<string name="welcome_message_2">Set up biometric unlock and autofill to log into your accounts without typing a single letter.</string>
<string name="quick_and_easy_login">Quick and easy login</string>

View file

@ -952,7 +952,7 @@ Do you want to switch to this account?</string>
<string name="or_log_in_you_may_already_have_an_account">Or log in, you may already have an account.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Get emails from Bitwarden for announcements, advice, and research opportunities. Unsubscribe at any time.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Get advice, announcements, and research opportunities from Bitwarden in your inbox. Unsubscribe at any time.</string>
<string name="privacy_prioritized">Privacy, prioritized</string>
<string name="security_prioritized">Privacy, prioritized</string>
<string name="welcome_message_1">Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect whats important to you.</string>
<string name="welcome_message_2">Set up biometric unlock and autofill to log into your accounts without typing a single letter.</string>
<string name="quick_and_easy_login">Quick and easy login</string>

View file

@ -951,7 +951,7 @@ Bu hesaba geçmek ister misiniz?</string>
<string name="or_log_in_you_may_already_have_an_account">Veya zaten hesabınız varsa giriş yapın.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Bitwarden\'dan duyurular, öneriler ve araştırmalarla ilgili e-postalar alın. İstediğiniz zaman aboneliğinizi iptal edebilirsiniz.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Bitwarden\'dan öneriler, duyurular ve araştırma fırsatları e-posta adresinize gelsin. İstediğiniz zaman aboneliğinizi iptal edebilirsiniz.</string>
<string name="privacy_prioritized">Önce gizlilik</string>
<string name="security_prioritized">Önce gizlilik</string>
<string name="welcome_message_1">Hesaplarınızı, kartlarınızı ve kimliklerinizi güvenli kasanıza kaydedin. Bitwarden\'ın sıfır bilgi ispatlı uçtan uca şifrelemesi sizin için önemli olan her şeyi korur.</string>
<string name="welcome_message_2">Hesaplarınıza parola yazmadan giriş yapmak için biyometrik kilit açmayı ayarlayabilirsiniz.</string>
<string name="quick_and_easy_login">Hızlı ve kolay giriş</string>

View file

@ -952,7 +952,7 @@
<string name="or_log_in_you_may_already_have_an_account">Або увійдіть, якщо вже маєте обліковий запис.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Отримуйте електронні листи від Bitwarden з оголошеннями, порадами та інформацією про нові можливості. Відписатися можна будь-коли.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Отримуйте поради, оголошення та інформацію щодо можливості участі в дослідженнях від Bitwarden у вашій поштовій скриньці. Відпишіться коли завгодно.</string>
<string name="privacy_prioritized">Приватність понад усе</string>
<string name="security_prioritized">Приватність понад усе</string>
<string name="welcome_message_1">Зберігайте записи входу, картки та посвідчення в захищеному сховищі. Для захисту ваших даних Bitwarden використовує наскрізне шифрування з нульовим рівнем доступу.</string>
<string name="welcome_message_2">Налаштуйте біометричне розблокування та автозаповнення, щоб миттєво входити в облікові записи.</string>
<string name="quick_and_easy_login">Швидкий і легкий вхід</string>

View file

@ -952,7 +952,7 @@ Bạn có muốn chuyển sang tài khoản này không?</string>
<string name="or_log_in_you_may_already_have_an_account">Hoặc đăng nhập, nếu bạn đã có tài khoản.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Nhận email từ Bitwarden để nhận thông báo, đề xuất và cơ hội nghiên cứu. Hủy đăng ký bất cứ lúc nào.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Nhận đề xuất, thông báo và cơ hội nghiên cứu từ Bitwarden trong hộp thư đến của bạn. Hủy đăng ký bất cứ lúc nào.</string>
<string name="privacy_prioritized">Bảo mật, riêng tư</string>
<string name="security_prioritized">Bảo mật, riêng tư</string>
<string name="welcome_message_1">Lưu thông tin đăng nhập, thẻ tín dụng và danh tính vào kho lưu trữ an toàn của bạn. Bitwarden sử dụng mã hóa đầu cuối không cần kiến thức để bảo vệ những gì quan trọng với bạn.</string>
<string name="welcome_message_2">Thiết lập mở khóa sinh trắc học và tự động điền để đăng nhập vào tài khoản của bạn mà không cần nhập tay.</string>
<string name="quick_and_easy_login">Đăng nhập nhanh và dễ dàng</string>

View file

@ -952,7 +952,7 @@
<string name="or_log_in_you_may_already_have_an_account">或者登录,您可能已经有一个账户了。</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">获取来自 Bitwarden 的建议、公告和调研电子邮件。随时退订。</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">获取来自 Bitwarden 的建议、公告和调研电子邮件。随时退订。</string>
<string name="privacy_prioritized">隐私优先</string>
<string name="security_prioritized">隐私优先</string>
<string name="welcome_message_1">将登录、支付卡和身份保存到您的安全密码库。Bitwarden 使用零知识、端到端的加密来保护您的重要信息。</string>
<string name="welcome_message_2">设置生物识别解锁和自动填充,无需输入任何字符即可登录您的账户。</string>
<string name="quick_and_easy_login">快速便捷的登录</string>

View file

@ -952,7 +952,7 @@
<string name="or_log_in_you_may_already_have_an_account">Or log in, you may already have an account.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Get emails from Bitwarden for announcements, advice, and research opportunities. Unsubscribe at any time.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Get advice, announcements, and research opportunities from Bitwarden in your inbox. Unsubscribe at any time.</string>
<string name="privacy_prioritized">Privacy, prioritized</string>
<string name="security_prioritized">Privacy, prioritized</string>
<string name="welcome_message_1">Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect whats important to you.</string>
<string name="welcome_message_2">Set up biometric unlock and autofill to log into your accounts without typing a single letter.</string>
<string name="quick_and_easy_login">Quick and easy login</string>

View file

@ -41,7 +41,6 @@
<string name="invalid_master_password">Invalid master password. Try again.</string>
<string name="invalid_pin">Invalid PIN. Try again.</string>
<string name="launch">Launch</string>
<string name="log_in">Log In</string>
<string name="log_in_verb">Log in</string>
<string name="log_in_noun">Login</string>
<string name="log_out">Log out</string>
@ -961,7 +960,7 @@ Do you want to switch to this account?</string>
<string name="or_log_in_you_may_already_have_an_account">Or log in, you may already have an account.</string>
<string name="get_emails_from_bitwarden_for_announcements_advices_and_research_opportunities_unsubscribe_any_time">Get emails from Bitwarden for announcements, advice, and research opportunities. Unsubscribe at any time.</string>
<string name="get_advice_announcements_and_research_opportunities_from_bitwarden_in_your_inbox_unsubscribe_any_time">Get advice, announcements, and research opportunities from Bitwarden in your inbox. Unsubscribe at any time.</string>
<string name="privacy_prioritized">Privacy, prioritized</string>
<string name="security_prioritized">Security, prioritized</string>
<string name="welcome_message_1">Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect whats important to you.</string>
<string name="welcome_message_2">Set up biometric unlock and autofill to log into your accounts without typing a single letter.</string>
<string name="quick_and_easy_login">Quick and easy login</string>
@ -1097,4 +1096,12 @@ Do you want to switch to this account?</string>
<string name="skip_for_now">Skip for now</string>
<string name="done_text">Done</string>
<string name="page_number_x_of_y">%1$s of %2$s</string>
<string name="copy_identity_name">Copy identity name</string>
<string name="copy_company">Copy company</string>
<string name="copy_ssn">Copy social security number</string>
<string name="copy_passport_number">Copy passport number</string>
<string name="copy_license_number">Copy license number</string>
<string name="copy_email">Copy email</string>
<string name="copy_phone">Copy phone number</string>
<string name="copy_address">Copy address</string>
</resources>

View file

@ -13,6 +13,7 @@ import com.x8bit.bitwarden.data.auth.datasource.network.model.RegisterFinishRequ
import com.x8bit.bitwarden.data.auth.datasource.network.model.RegisterRequestJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.RegisterResponseJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.SendVerificationEmailRequestJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.SendVerificationEmailResponseJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.TrustedDeviceUserDecryptionOptionsJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.TwoFactorAuthMethod
import com.x8bit.bitwarden.data.auth.datasource.network.model.UserDecryptionOptionsJson
@ -370,14 +371,19 @@ class IdentityServiceTest : BaseServiceTest() {
runTest {
server.enqueue(MockResponse().setResponseCode(200).setBody(EMAIL_TOKEN))
val result = identityService.sendVerificationEmail(SEND_VERIFICATION_EMAIL_REQUEST)
assertEquals(JsonPrimitive(EMAIL_TOKEN).content.asSuccess(), result)
assertEquals(
SendVerificationEmailResponseJson
.Success(JsonPrimitive(EMAIL_TOKEN).content)
.asSuccess(),
result,
)
}
@Test
fun `sendVerificationEmail should return null when response is empty success`() = runTest {
server.enqueue(MockResponse().setResponseCode(204))
val result = identityService.sendVerificationEmail(SEND_VERIFICATION_EMAIL_REQUEST)
assertEquals(null.asSuccess(), result)
assertEquals(SendVerificationEmailResponseJson.Success(null).asSuccess(), result)
}
@Test
@ -422,7 +428,6 @@ class IdentityServiceTest : BaseServiceTest() {
)
}
@Suppress("MaxLineLength")
@Test
fun `verifyEmailToken should return Invalid when response message is non expired error`() =
runTest {

View file

@ -38,6 +38,7 @@ import com.x8bit.bitwarden.data.auth.datasource.network.model.RegisterResponseJs
import com.x8bit.bitwarden.data.auth.datasource.network.model.ResendEmailRequestJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.ResetPasswordRequestJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.SendVerificationEmailRequestJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.SendVerificationEmailResponseJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.SetPasswordRequestJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.TrustedDeviceUserDecryptionOptionsJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.TwoFactorAuthMethod
@ -6043,7 +6044,7 @@ class AuthRepositoryTest {
receiveMarketingEmails = true,
),
)
} returns EMAIL_VERIFICATION_TOKEN.asSuccess()
} returns SendVerificationEmailResponseJson.Success(EMAIL_VERIFICATION_TOKEN).asSuccess()
val result = repository.sendVerificationEmail(
email = EMAIL,
@ -6056,6 +6057,32 @@ class AuthRepositoryTest {
)
}
@Test
fun `sendVerificationEmail success with invalid email should return error`() = runTest {
val errorMessage = "Failure"
coEvery {
identityService.sendVerificationEmail(
SendVerificationEmailRequestJson(
email = EMAIL,
name = NAME,
receiveMarketingEmails = true,
),
)
} returns SendVerificationEmailResponseJson
.Invalid(invalidMessage = errorMessage, validationErrors = null)
.asSuccess()
val result = repository.sendVerificationEmail(
email = EMAIL,
name = NAME,
receiveMarketingEmails = true,
)
assertEquals(
SendVerificationEmailResult.Error(errorMessage = errorMessage),
result,
)
}
@Test
fun `sendVerificationEmail failure should return success if body null`() = runTest {
coEvery {
@ -6066,7 +6093,7 @@ class AuthRepositoryTest {
receiveMarketingEmails = true,
),
)
} returns null.asSuccess()
} returns SendVerificationEmailResponseJson.Success(null).asSuccess()
val result = repository.sendVerificationEmail(
email = EMAIL,
@ -6089,7 +6116,7 @@ class AuthRepositoryTest {
receiveMarketingEmails = true,
),
)
} returns EMAIL_VERIFICATION_TOKEN.asSuccess()
} returns SendVerificationEmailResponseJson.Success(EMAIL_VERIFICATION_TOKEN).asSuccess()
val result = repository.sendVerificationEmail(
email = EMAIL,

Some files were not shown because too many files have changed in this diff Show more