Compare commits

...

1337 Commits

Author SHA1 Message Date
Álison Fernandes
bf2ac7cac9 Add pyproject.toml 2025-03-03 16:57:12 +00:00
Álison Fernandes
5bbbf7c5e4 Add script and tests for linked issues, removing method from the release notes script 2025-03-03 16:52:43 +00:00
Álison Fernandes
39d10fa77d Add release notes processing script and unit tests 2025-03-03 15:44:11 +00:00
Álison Fernandes
f0f240f8e5 Update gitignore for python 2025-03-03 15:43:27 +00:00
aj-rosado
ac6ff98041 [PM-14435] Accessibility enabled settings changes to address older and custom Android phone versions (#4756) 2025-02-28 22:25:11 +00:00
David Perez
ec030f2c2e Update AGP to 8.8.2 (#4809) 2025-02-28 18:39:52 +00:00
Patrick Honkonen
be08c1a536 Refactor .editorconfig to focus on Kotlin and common file types (#4808) 2025-02-28 16:16:28 +00:00
bw-ghapp[bot]
84edf4ead0 Autosync Crowdin Translations (#4806)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2025-02-28 14:34:04 +00:00
aj-rosado
915aac561c [PM-17215] Remove get_login_creds from Fido2OriginManagerImpl.filterMatchingAppStatementsOrNull (#4804) 2025-02-28 10:46:04 +00:00
Patrick Honkonen
2027a66f02 [PM-18714] Display Card brand icon when it is known (#4805) 2025-02-27 21:57:28 +00:00
David Perez
ef6d9bc68c PM-18677: Policies for disabled organizations apply (#4801) 2025-02-27 21:54:47 +00:00
Dave Severns
3ceda9e40a PM-18388 add hyphens on segmented button labels (#4777) 2025-02-27 21:50:37 +00:00
Phil Cappelli
3f1a6e97fd PM-17568 - Authenticator Sync: Sometimes synced verification codes only display the TOTP Key, not Issuer/username (#4783) 2025-02-27 21:42:38 +00:00
André Bispo
4448ab05ce [PM-17739] Show password history (#4803) 2025-02-27 19:49:57 +00:00
aj-rosado
d584391843 [PM-8223] 🍒 New device verification continue button enabled at 8 digit (#4802) 2025-02-27 19:48:24 +00:00
Patrick Honkonen
e0d91d7682 [PM-18067] Consolidate item name fields into ItemHeader (#4766) 2025-02-27 17:31:39 +00:00
Patrick Honkonen
e8a98dd3ed Add spacers to VaultItemIdentityContent, VaultItemSecureNoteContent, and VaultItemCardContent 2025-02-27 12:05:09 -05:00
Patrick Honkonen
b6163cf53c Fix item key in VaultItemCardContent for security code field 2025-02-27 11:14:40 -05:00
Patrick Honkonen
a24c6f2719 Update ic_organization.xml vector drawable 2025-02-27 11:13:04 -05:00
Patrick Honkonen
b3219d4040 Use CardStyle.Bottom when last item is drawn 2025-02-27 11:05:06 -05:00
Patrick Honkonen
27043e28a8 Revert formatting changes 2025-02-27 10:30:41 -05:00
Patrick Honkonen
7c36b7cb82 [PM-14303] Update Bitwarden SDK and load bitwarden_uniffi on older Android versions (#4793) 2025-02-27 15:23:55 +00:00
Patrick Honkonen
fcfcf48cee Uncomment & update previews 2025-02-27 09:17:50 -05:00
Patrick Honkonen
757994ec18 Merge remote-tracking branch 'origin/main' into PM-18067/view-item-favicon 2025-02-27 09:17:16 -05:00
Álison Fernandes
548de56d60 [PM-18434] Welcome Authenticator app! (#4798) 2025-02-27 12:54:51 +00:00
Patrick Honkonen
71cd917328 Merge branch 'main' into PM-14303/update-bitwarden-sdk 2025-02-26 17:15:35 -05:00
Álison Fernandes
01188c21b2 Update BWA secret names 2025-02-26 22:14:56 +00:00
Patrick Honkonen
5c076871ab Implement NativeLibraryManager and NativeLibraryManagerImpl for loading native libraries
This commit introduces the `NativeLibraryManager` interface and its implementation, `NativeLibraryManagerImpl`.
- `NativeLibraryManager` defines a method `loadLibrary` for loading native libraries.
- `NativeLibraryManagerImpl` uses `System.loadLibrary` to load libraries and handles potential `UnsatisfiedLinkError`.
- `PlatformManagerModule` is updated to provide `NativeLibraryManager` instance and to inject it into `SdkClientManager`.
2025-02-26 17:14:51 -05:00
Álison Fernandes
dca7284230 Merge remote-tracking branch 'bwa-android/main' into bwa-monorepo
# Conflicts:
#	.checkmarx/config.yml
#	.github/CODEOWNERS
#	.github/ISSUE_TEMPLATE/bug.yml
#	.github/ISSUE_TEMPLATE/config.yml
#	.github/renovate.json
#	.github/workflows/build-authenticator.yml
#	.github/workflows/crowdin-pull-authenticator.yml
#	.github/workflows/crowdin-push-authenticator.yml
#	.github/workflows/scan-authenticator.yml
#	.github/workflows/test-authenticator.yml
#	.gitignore
#	Gemfile
#	Gemfile.lock
#	README.md
#	build.gradle.kts
#	fastlane/Fastfile
#	gradle.properties
#	gradle/libs.versions.toml
#	gradle/wrapper/gradle-wrapper.properties
#	gradlew.bat
#	settings.gradle.kts
2025-02-26 22:13:24 +00:00
Patrick Honkonen
07d3849c4b Add keys and animation to all content items 2025-02-26 17:10:10 -05:00
David Perez
33c3fd28e9 itemHeader as LazyListScope extension 2025-02-26 14:45:25 -06:00
Patrick Honkonen
88609c2f5b Update OrganizationType.OWNER mock data in VaultItemViewModelTest.kt 2025-02-26 14:45:25 -06:00
Patrick Honkonen
af8cfcd2f0 Move expansion indicator outside of crossfade animation 2025-02-26 14:45:25 -06:00
Patrick Honkonen
7cc8108498 Adjust ItemHeader expanding header fill the available width 2025-02-26 14:45:25 -06:00
Patrick Honkonen
a31c499b15 Remove unnecessary mockkStatic call in CipherViewExtensionsTest.kt 2025-02-26 14:45:24 -06:00
Patrick Honkonen
d7d099477f Refactor ItemHeader to use LazyColumn and Crossfade for smoother transitions
- Migrates `ItemHeader` to `LazyColumn` to improve performance.
- Introduces `Crossfade` for animating title changes in `BitwardenExpandingHeader`.
- Adjusts icon sizing in `ItemHeaderIcon`.
- Removes unnecessary column scope and animated visibility from `ExpandingItemLocationContent`.
- Refactors to use `LazyItemScope` and adds `animateItem()` to `ItemLocationListItem`.
- Adds conditional handling for expanding the item locations list.
2025-02-26 14:45:24 -06:00
Patrick Honkonen
0ba240852f Refactor ExpandingItemLocationContent to use ColumnScope 2025-02-26 14:45:24 -06:00
Patrick Honkonen
727d943fae Use persistentListOfNotNull instead of buildList and toImmutableList 2025-02-26 14:45:24 -06:00
Patrick Honkonen
234f49a92c Replace HorizontalDivider with BitwardenHorizontalDivider and add Spacer in ItemHeader.kt 2025-02-26 14:45:24 -06:00
Patrick Honkonen
4f49d3d504 Reduce Spacer height in VaultItemLoginContent.kt from 24.dp to 12.dp 2025-02-26 14:45:24 -06:00
Patrick Honkonen
aba8344df1 Revert unintentional change 2025-02-26 14:45:23 -06:00
Patrick Honkonen
6da8e2c47b Adjust height of Spacer in BitwardenTextField based on cardStyle presence 2025-02-26 14:45:23 -06:00
Patrick Honkonen
78d5965271 Refactor ItemHeader to use LazyColumn for overflow locations 2025-02-26 14:45:23 -06:00
Patrick Honkonen
6953d5e132 Migrate VaultItem related locations to ImmutableList 2025-02-26 14:45:23 -06:00
Patrick Honkonen
7073124495 Make cardStyle parameter optional in BitwardenTextField 2025-02-26 14:45:23 -06:00
Patrick Honkonen
0cc7067808 Add divider to ItemHeader in vault item view 2025-02-26 14:45:23 -06:00
Patrick Honkonen
9e920f1cf5 Refactor ItemHeader to use cardStyle and remove custom card styling. 2025-02-26 14:45:22 -06:00
Patrick Honkonen
537e743891 Replaced standardHorizontalMargin with explicit horizontal padding 2025-02-26 14:45:22 -06:00
Patrick Honkonen
60da236f3e Add illustration colors 2025-02-26 14:45:22 -06:00
Patrick Honkonen
7804d8430f [PM-18067] Consolidate item name fields into ItemHeader
This commit introduces `ItemHeader`, a new composable that replaces `ItemNameField` to display the item name, favorite status, and related details like organization, collections, and folder.

Key changes:
- Removes `ItemNameField`
- Adds `ItemHeader` for displaying item name and favorite status, along with item location information.
- Introduces a new `ic_organization` icon.
- Adds the logic for showing item locations (organization, collections, folders) in a collapsible view.
- Removes `ItemNameField` from `VaultItemLoginContent`, `VaultItemIdentityContent`, `VaultItemSecureNoteContent`, `VaultItemCardContent`, `VaultItemSshKeyContent` and replace it with `ItemHeader`
- Adds the logic to fetch and display the item icon in `ItemHeader` based on item type
- Adds an `ItemLocationListItem` for displaying location details.
- Adds a `VaultItemLocation` data class for representing item locations.
- Adds new `baseIconUrl` and `isIconLoadingDisabled` variables to the `VaultItemState` to handle icon display.
- Updates `CipherView.toIconData` to handle the item icon.
- Adds new `show_more`, `no_folder` and `show_less` string resources.
- Updates the `BitwardenShapes` to include `favicon` shapes.
- Updates the `BitwardenColorScheme` to include `faviconForeground` and `faviconBackground`.
- Updates `BitwardenExpandingHeader` to include expandedText, collapsedText and showExpansionIndicator properties.
2025-02-26 14:45:22 -06:00
Dave Severns
2893c3871f PM-18636 Hide coach mark card if any login ciphers exist (#4787)
Co-authored-by: Patrick Honkonen <1883101+SaintPatrck@users.noreply.github.com>
Co-authored-by: Philip Cappelli <phil@livefront.com>
2025-02-26 18:48:10 +00:00
André Bispo
d04ac5e672 [PM-18451] Elevated privileges do not exempt from remove pin unlock policy (#4791) 2025-02-26 16:48:56 +00:00
Álison Fernandes
55e03565a6 [PM-18655] sync with bitwarden/template (#4795) 2025-02-26 15:24:00 +00:00
Álison Fernandes
768f7a3fd9 [PM-16534] Monorepo prep - Update checkmarx, renovate and gitignore (#4794) 2025-02-26 15:23:01 +00:00
Álison Fernandes
1d02737093 [PM-18651] Add Bitwarden Authenticator issue template and update existing bug template (#4792) 2025-02-26 15:22:44 +00:00
Patrick Honkonen
dab06b0ed4 [PM-14303] Update Bitwarden SDK and load bitwarden_uniffi on older Android versions
The Bitwarden SDK dependency was updated to version 1.0.0-20250225.125021-120.

The SDK requires access to Android APIs that were made public in API 31 in order to generate email aliases. To address this limitation for devices with earlier API versions, the `bitwarden_uniffi` library is now loaded manually before initializing any `Client` instance.
2025-02-26 10:04:24 -05:00
Álison Fernandes
fb792a668b [PM-17412] Retrieve firebase files from container and remove ui-test version ref (#357)
Co-authored-by: Patrick Honkonen <1883101+SaintPatrck@users.noreply.github.com>
2025-02-26 08:59:37 -05:00
Álison Fernandes
64da29ffaa [PM-16534] Merge authenticator-android libs and fastlane files (#4782) 2025-02-25 22:49:26 +00:00
Bernd Schoolmann
675cbb7c4f [PM-15149] Remove ssh feature flag (#4761) 2025-02-25 22:33:36 +00:00
Patrick Honkonen
6b63218839 [PM-17142] Remove ExampleInstrumentedTest (#358) 2025-02-25 22:21:41 +00:00
André Bispo
30a1bba796 [PM-15873] Fix PTR in sends listing page (#4784) 2025-02-25 19:06:45 +00:00
David Perez
c2d9e4858b Standardize all compose tests with theme and back handling (#4779) 2025-02-25 12:34:10 -06:00
André Bispo
d8e42083b7 [PM-18451] Validate remove pin policy against user privileges (#4774)
Co-authored-by: Dave Severns <149429124+dseverns-livefront@users.noreply.github.com>
2025-02-25 16:14:27 +00:00
André Bispo
ac7fbfd129 [PM-15873] Fix PTR on item listing page (#4778) 2025-02-25 16:14:18 +00:00
Peter Dave Hello
25dfa74bdf [BWA-153] Fix the GitHub Workflow badge in README.md (#351) 2025-02-25 10:33:29 -05:00
renovate[bot]
85a98e86c4 [deps]: Lock file maintenance (#352)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-25 10:33:03 -05:00
Álison Fernandes
078d80d3f6 [PM-17412] Rename debug keystore (#356) 2025-02-25 10:30:14 -05:00
David Perez
00eb78f02e Simplify the RegisterResponseJson error models (#4776) 2025-02-24 15:32:41 -06:00
David Perez
eadfac5ea8 Simplify error response models (#4775) 2025-02-24 14:52:00 -06:00
David Perez
a651d9b1fc Update Kotlin and ksp to latest versions (#4773) 2025-02-24 13:13:14 -06:00
Álison Fernandes
6308aed34a [PM-17412] Update libs.versions.toml ahead of repo merge (#349) 2025-02-24 12:22:27 -06:00
Dave Severns
011d637f7c PM-18129 add authenticator illustration for 2fa screen (#4763) 2025-02-24 09:51:54 -05:00
David Perez
0b03d2c0d5 Update hilt v2.55 (#4769) 2025-02-23 11:28:40 -06:00
David Perez
bb7e4061cc Update firebase (#4765) 2025-02-22 13:20:53 -06:00
David Perez
d1308cb936 Update Compose BOM to 2025.02.00 (#4764) 2025-02-21 15:12:35 -06:00
Dave Severns
892f817b2a PM-18315 add UI when 3pa is available for each chrome channel which s… (#4758) 2025-02-21 15:09:57 -05:00
David Perez
86e5789f30 Add NetworkErrorCode enum to make error parsing more readable (#4762) 2025-02-21 13:02:47 -06:00
David Perez
80bd1bfde2 PM-18496: Propagate prevalidateSso API error message (#4759) 2025-02-21 08:34:18 -06:00
bw-ghapp[bot]
4943df24b3 Autosync Crowdin Translations (#4760)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2025-02-21 08:32:04 -06:00
Dave Severns
b7464b87d9 PM-18314 & PM-18450 Check for Chrome browser 3rd party autofill. (#4752) 2025-02-20 15:59:39 -05:00
David Perez
3fb7904a36 PM-18480 Update BitwardenSwitch padding (#4757) 2025-02-20 14:57:13 -06:00
David Perez
9d9f9e3e72 PM-18121: Use correct cipher type for edit screen (#4755) 2025-02-20 12:11:49 -06:00
André Bispo
a061cbb1d3 [PM-15873] Add delay to PTR to remove the spinning wheel (#4750) 2025-02-20 17:49:00 +00:00
David Perez
ad03f8c996 PM-18452: Update BitwardenMultiSelectionButton (#4754) 2025-02-20 11:12:42 -06:00
André Bispo
aac2345a64 [PM-18545] Hide section when no unlock option are available (#4751) 2025-02-20 14:30:39 +00:00
David Perez
61c48bf673 PM-18121, PM-18294: Add, Edit, and View cipher screens require cipher type for top app bar title (#4746) 2025-02-19 14:56:55 -05:00
Phil Cappelli
77b631b021 PM-18292 - Swap "Notes" title with "Additional Options" (#4749) 2025-02-19 14:35:59 -05:00
Phil Cappelli
c59a28a9df PM 18033 - Only show Setup Unlock and Autofill Setup onboarding steps after new account creation (#4748) 2025-02-19 14:35:46 -05:00
Dave Severns
1349165156 PM-18421 Remove adding a folder option from within folder view. (#4747) 2025-02-19 12:55:54 -05:00
Patrick Honkonen
65cc0a0dd8 [PM-3553] Support SimpleLogin self hosted servers (#4723) 2025-02-19 10:20:28 -05:00
Dave Severns
0ba67f5887 PM-18032 Adding a new folder while adding or editing an item. (#4731) 2025-02-18 17:25:51 -05:00
David Perez
87f64d7aba PM-18370: Update space between label and tooltip (#4744) 2025-02-18 15:03:26 -06:00
David Perez
063003b4aa PM-18410: Remove cipher type dropdown from add item screen (#4743) 2025-02-18 14:27:36 -06:00
André Bispo
f2eb524da4 [PM-18281] Change cipher key encryption flag default value to false (#4742) 2025-02-18 20:07:45 +00:00
David Perez
e929ca8a7d PM-18370: Allow selecting type of cipher to add from collection list (#4741) 2025-02-18 10:59:31 -06:00
André Bispo
acc5e30b7a [PM-17882] Cannot select autofill after creating new login (#4728) 2025-02-18 15:13:29 +00:00
David Perez
26d4a397a6 Update to gradle plugin 8.8.1 (#4740) 2025-02-18 08:35:18 -06:00
Álison Fernandes
ba9a0d8884 [PM-17412] Renamed crowdin.yml to crowdin-bwa.yml (#348) 2025-02-18 09:33:05 -05:00
Patrick Honkonen
bb2e98eac6 [PM-14936] Add AnonAddy self-hosted server URL support (#4708) 2025-02-18 08:57:47 -05:00
Álison Fernandes
133d8548e8 [PM-18384] Add placeholder workflows for the Authenticator (#4736) 2025-02-17 22:17:49 +00:00
David Perez
9f19a99eb9 PM-18275: Add totp tooltip on view item screen (#4732) 2025-02-17 15:44:55 -06:00
David Perez
22931bbd38 Improve the error messaging when an enum is not parsed correctly (#4730) 2025-02-17 15:03:05 -06:00
David Perez
359dedc9d7 Fix minor typo (#4734) 2025-02-17 20:37:06 +00:00
Phil Cappelli
be416f87de PM-18292 - Update section headers for all items to align with V3 Design (#4729) 2025-02-17 14:09:51 -05:00
Phil Cappelli
6a3a534304 PM-17566 - Authenticator Sync: In Dark theme, the Action card in the Authenticator is too dark (#347) 2025-02-17 13:42:42 -05:00
Patrick Honkonen
09254a2285 Update Bitwarden SDK and use sdk-android-temp (#346) 2025-02-14 15:44:04 +00:00
aj-rosado
f0d6599eb3 [PM-8223] Add new device verification when no OTP (#4712) 2025-02-14 14:03:15 +00:00
bw-ghapp[bot]
d7a50b092b Autosync Crowdin Translations (#4725) 2025-02-14 09:01:57 -05:00
Dave Severns
9f616b67c9 PM-18123 Update the reset password screen. (#4719) 2025-02-13 16:07:17 -05:00
Dave Severns
1198de2a74 PM-17766 add new strings for ssh keys empty item (#4722) 2025-02-13 16:07:01 -05:00
Patrick Honkonen
3db7b17e3a [PM-3553] Add SimpleLogin self-hosted alias feature flag (#4715) 2025-02-13 12:51:07 -05:00
Álison Fernandes
631be3fca5 [PM-16534] Update gradle invocations to specify app module (#4720)
Co-authored-by: Patrick Honkonen <1883101+SaintPatrck@users.noreply.github.com>
2025-02-12 20:01:02 -05:00
Patrick Honkonen
e8e6040318 Rename CI workflows for Authenticator (#333)
Co-authored-by: Álison Fernandes <vvolkgang@users.noreply.github.com>
2025-02-13 00:12:21 +00:00
Patrick Honkonen
5790397a27 [PM-16534] Update gradle invocations to specify authenticator module (#344) 2025-02-12 23:41:31 +00:00
Álison Fernandes
8b98e8f461 [PM-16534] Update fastfile check lane (#342)
Co-authored-by: Patrick Honkonen <1883101+SaintPatrck@users.noreply.github.com>
2025-02-12 18:21:13 -05:00
Álison Fernandes
f3482bd3e2 [PM-16534] Update test lane name (#343) 2025-02-12 18:18:28 -05:00
Álison Fernandes
14ef7351bd [PM-16534] Fix fastfile typo (#341) 2025-02-12 23:00:34 +00:00
Patrick Honkonen
0820061466 [PM-11886] Update handling of unprivileged apps and improve error messaging (#4694) 2025-02-12 17:52:12 -05:00
Álison Fernandes
c5616b9e38 [PM-16534] Fix Fastfile lanes (#340) 2025-02-12 22:51:13 +00:00
Patrick Honkonen
0538becf7f Update output filenames (#335)
Co-authored-by: Álison Fernandes <vvolkgang@users.noreply.github.com>
2025-02-12 22:31:20 +00:00
Patrick Honkonen
2ae3d5e100 Rename Fastfile lanes to be Authenticator-specific (#334)
Co-authored-by: Álison Fernandes <vvolkgang@users.noreply.github.com>
2025-02-12 17:24:45 -05:00
André Bispo
2aa371a972 [PM-18050] Remove pin policy (#4718) 2025-02-12 22:16:35 +00:00
Patrick Honkonen
72ac8d3699 Rename app package to authenticator (#305)
Co-authored-by: Álison Fernandes <vvolkgang@users.noreply.github.com>
2025-02-12 22:13:07 +00:00
Dave Severns
00f30c922d PM-18058 and PM-18059 Choose which type of vault item to add from Vault screen and inside a Folder. (#4703) 2025-02-12 09:21:15 -05:00
Dave Severns
a68b370cba PM-18083 Ensure segmented buttons on generator fill entire width evenly. (#4713) 2025-02-11 18:08:35 -05:00
Patrick Honkonen
60a6b2a545 [PM-14936] Add AnonAddySelfHostAlias feature flag (#4711) 2025-02-11 18:06:45 -05:00
Patrick Honkonen
2c63c1ab94 [PM-14936] Move prefixHttpsIfNecessaryOrNull to StringExtensions (#4709) 2025-02-11 18:06:17 -05:00
André Bispo
fdc92712c4 [PM-17368] After cut, update text and clear selection. (#4714) 2025-02-11 23:02:08 +00:00
Phil Cappelli
4eb4d5f256 PM-17566 - Authenticator Sync: In Dark theme, the Action card in the Authenticator is too dark (#337) 2025-02-11 11:41:54 -05:00
Álison Fernandes
6fdb39026f [PM-18193] Remove scan.yml from Merge Queue status check and update test.yml report job skip (#4710) 2025-02-10 23:31:01 +00:00
David Perez
ac6c90eb7a PM-18013: Update the View Item screens (#4699) 2025-02-10 13:59:44 -05:00
Phil Cappelli
eb3bc838d6 PM-17838 - Add help button for authenticator key (#4697) 2025-02-10 18:58:26 +00:00
Dave Severns
30e882d7d1 PM-17769 add thinner version of vault icon for the settings (#4704) 2025-02-10 13:58:02 -05:00
Patrick Honkonen
3adc80fdf8 [PM-18082] Force incognito keyboard on input fields (#4700) 2025-02-10 13:38:29 -05:00
bw-ghapp[bot]
e70b21c951 Autosync Crowdin Translations (#4702) 2025-02-10 13:37:58 -05:00
rohm1
571b8368e1 [PM-16157] Support self-host servers using TLS with Client Authentication (mTLS) (#4486) 2025-02-10 18:33:28 +00:00
Patrick Honkonen
fd26472f71 [PM-17405] Configure mutual-tls FlagKey as remotely configured (#4701) 2025-02-10 13:09:16 -05:00
bw-ghapp[bot]
6ffe9df353 Autosync Crowdin Translations (#336) 2025-02-07 09:34:52 -05:00
David Perez
7e0fc07a7c PM-17968: Create unique secret keys per user and handle decoding error (#4696) 2025-02-06 15:38:12 +00:00
David Perez
d27ab1d31a Apply formatter to the entire app (#4698) 2025-02-06 14:52:09 +00:00
Matt Andreko
7b9cbb7bef Enabled SonarQube scanning for PRs (#332) 2025-02-05 13:06:08 -05:00
Dave Severns
a1a3d55656 PM-17848 update copy on generator modal (#4691) 2025-02-05 14:32:33 +00:00
Patrick Honkonen
c672bff18c [PM-17694] Only update FIDO2 user verification status during single-tap sign-in (#4680) 2025-02-05 13:46:52 +00:00
ifernandezdiaz
7ab5972893 QA-1056: Adding testTag to Stepper value text (#4690) 2025-02-05 13:45:45 +00:00
ifernandezdiaz
13aa3251d5 QA-1061: Adding testTags for new WelcomePage (#4695) 2025-02-05 13:45:40 +00:00
Dave Severns
a5f6864512 PM-17847 update text style for add account label (#4693) 2025-02-05 13:11:19 +00:00
David Perez
c3506c1c25 PM-17841: Hide additional options behind expandable section (#4687) 2025-02-04 22:43:27 +00:00
Lucas
1710b563c0 [PM-16862] FIDO2 Community: Remove DivestOS-developed browsers (#4533) 2025-02-04 22:30:18 +00:00
Matt Andreko
01b646afa7 Enabled SonarQube scanning for PRs (#4692) 2025-02-04 20:22:47 +00:00
Álison Fernandes
445bd90f67 [PM-17962] Exclude generated Hilt .java files from code coverage (#4689) 2025-02-04 17:37:38 +00:00
David Perez
de7416d96e PM-17958: Remove language supporting text (#4688) 2025-02-04 17:22:23 +00:00
Álison Fernandes
5e29df5f30 [PM-10515] fix: Missing build information in About screen version copy (#4679) 2025-02-04 15:58:27 +00:00
David Perez
5f48d7bebd PM-17958: Update appearance text (#4686) 2025-02-04 15:52:25 +00:00
Álison Fernandes
b342f21cbb [PM-17939] Restrict test.yml coverage upload to On Push and Pull Request triggers (#4681) 2025-02-03 23:03:55 +00:00
Patrick Honkonen
4b3ec1d918 [PM-17930] Remove default arguments from CoachMarkHighlight (#4677) 2025-02-03 22:18:16 +00:00
Dave Severns
5f52c49a68 PM-17769 Icons added to the settings menu rows (#4673) 2025-02-03 20:18:32 +00:00
David Perez
efe1475fbf PM-17851: Update manual code entry screen (#4676) 2025-02-03 19:40:27 +00:00
Patrick Honkonen
ffe5ddb4a6 [PM-16136] Update Bitwarden SDK (#4675) 2025-02-03 18:38:35 +00:00
Dave Severns
6f82251332 PM-17766 Updated empty states for grouped types and send types. (#4667) 2025-02-03 18:33:40 +00:00
David Perez
76e780f813 PM-17839 PM-17827 PM-17824 PM-17832 PM-17836 PM-17840: VaultAddEditScreen and VaultMoveToOrganizationScreen (#4668) 2025-02-03 17:19:25 +00:00
Patrick Honkonen
161d8517a4 [PM-9535] Show toast when copying values prior to Android 13 (#4654) 2025-02-03 16:59:44 +00:00
Dave Severns
0786ab98a7 PM-17910 Prevent back events from system when coach mark tour is in progress. (#4674) 2025-02-03 16:46:41 +00:00
bw-ghapp[bot]
3d12c98969 Autosync Crowdin Translations (#330) 2025-02-03 11:24:51 -05:00
Phil Cappelli
07fe6e53ea PM-17845 PM-17718 - Enable Remote Configuration for the import flow & Rename Authenticator Sync Feature Flag Name (#4666) 2025-02-03 15:00:14 +00:00
Phil Cappelli
2bbadf8726 BWA-144 - Consolidate feature flags for sync between the Password Manager Authenticator (#331) 2025-02-03 10:00:05 -05:00
Dave Severns
f004e10d41 PM-17801 and PM-17791 updates some string resources related to coach marks and Autofill casing. (#4664) 2025-02-03 14:34:14 +00:00
David Perez
38c9d6cfbc Fix vault favorites spacing (#4665) 2025-01-31 18:15:26 +00:00
David Perez
62d26491d5 Update TOTP coachmark layout (#4663) 2025-01-31 17:52:57 +00:00
Dave Severns
925db01b44 PM-17797 and PM-17798 set onboarding features to be remotely configurable (#4662) 2025-01-31 15:49:56 +00:00
Dave Severns
2b79cc9a17 PM-17765 & PM-17767 Adjust spacing in vault screen and adjust account switcher icon size and minimum row height (#4661) 2025-01-31 15:23:10 +00:00
David Perez
f141465b41 Simplify modifier extensions (#4657) 2025-01-31 15:03:03 +00:00
Phil Cappelli
ecc5d4ce30 PM-16861 - Update Behavior When Tapping Same Generator Tab Already Viewing (#4653) 2025-01-31 15:02:17 +00:00
bw-ghapp[bot]
de558bf94d Autosync Crowdin Translations (#4656)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2025-01-31 00:42:43 +00:00
David Perez
9b3bb32c87 PM-17376, PM-17380, PM-17385: Update card padding and layout (#4652) 2025-01-30 21:21:14 +00:00
Dave Severns
6f5cb0df96 PM-17764 update the email verification to completely match new design. (#4655) 2025-01-30 21:04:11 +00:00
mpbw2
2195d07f78 [PM-13351] Prevent editing of TOTP key in 'can edit except passwords' collection (#4583) 2025-01-30 20:12:28 +00:00
Phil Cappelli
c09b02f1d0 PM-17384 PM-17386 - Create Account Design Audit (#4647) 2025-01-29 21:33:15 +00:00
Dave Severns
76c7f8c41d PM-17388 Update existing and v3 email verification screen to match design audit (#4645) 2025-01-29 20:41:44 +00:00
David Perez
6a1f37b243 PM-17721: Update app dropdown menus (#4646) 2025-01-29 20:26:50 +00:00
Dave Severns
590fc21820 PM-16625 PM-16626 PM-16627 Coach marks 4-6 on generator screen (#4640) 2025-01-29 17:57:56 +00:00
Patrick Honkonen
4575fa96c1 [deps]: Update AndroidX library versions (#324) 2025-01-29 11:31:22 -05:00
David Perez
1a7ddbef7a PM-17205: Check accessibility service status on start up (#4644) 2025-01-29 15:46:07 +00:00
Patrick Honkonen
555d30645f [deps]: Update Hilt (#325) 2025-01-29 09:41:00 -06:00
Patrick Honkonen
80d04fdf9c [deps]: Update ProtoBufJava (#326) 2025-01-29 09:40:20 -06:00
Patrick Honkonen
4ea92223c0 [deps]: Update Google Guava (#327) 2025-01-29 09:22:38 -06:00
Patrick Honkonen
f8e41caaf2 [deps]: Update Firebase BoM (#328) 2025-01-29 09:19:48 -06:00
Patrick Honkonen
3963623407 [deps]: Update JUnit 5 (#323) 2025-01-29 09:18:54 -06:00
renovate[bot]
bbb2d8dc05 [deps]: Update androidx.compose:compose-bom to v2025 (#319) 2025-01-29 10:10:42 -05:00
bw-ghapp[bot]
db035bbd7d Autosync Crowdin Translations (#322) 2025-01-29 09:23:48 -05:00
David Perez
69f33ddca9 PM-17680: Overwrite the expiration date to the deletion date (#4642) 2025-01-28 22:20:47 +00:00
David Perez
2eca28d571 PM-17684: Update the cursor color throughout the app (#4643) 2025-01-28 22:17:30 +00:00
David Perez
d9ac445149 Fix minor formatting issues in Authenticator Bridge Readme (#4641) 2025-01-28 20:55:07 +00:00
aj-rosado
fe06bf48e7 [PM-13626] Remember last opened view for 5 minutes (#4574)
Signed-off-by: Andre Rosado <arosado@bitwarden.com>
Co-authored-by: Dave Severns <dseverns@livefront.com>
2025-01-28 19:41:11 +00:00
Robyn MacCallum
3f1f9983e3 Update SingleTapPasskeyAuthentication and SingleTapPassskeyCreation to be remote flags (#4639) 2025-01-28 18:37:12 +00:00
Dave Severns
a681402956 PM-16622 PM-16623 and PM-16624 Add the first three coach marks to the generator tour (#4613) 2025-01-28 18:33:19 +00:00
Phil Cappelli
3c7262d2b3 PM-17382 - Update “Logging in as…” text and link style on log in screen (#4638) 2025-01-28 17:18:43 +00:00
Dave Severns
7a25aafc23 PM-17650 Implement custom tool tip state to prevent tool tips from dismissing. (#4637) 2025-01-28 15:20:15 +00:00
Dave Severns
b2c4fbb593 Back port Reverts PM-14995 (#4633) (#4635) 2025-01-28 14:49:33 +00:00
David Perez
e2dec1f2fe PM-17638: Add card background for the manual totp screen (#4634) 2025-01-27 22:39:26 +00:00
David Perez
5f1ef71b3b PM-17378: Update remember me text (#4624) 2025-01-24 22:47:39 +00:00
David Perez
b3550bc933 Fix the login test tag (#4625) 2025-01-24 22:43:25 +00:00
David Perez
09b898d655 PM-17377: Update text, formatting, and style for the environment selector (#4623) 2025-01-24 21:34:42 +00:00
Patrick Honkonen
92b92403c6 [PM-17531] Add dialog for client certificate import (#4622) 2025-01-24 21:08:21 +00:00
Phil Cappelli
b84d393208 [PM-17374] [PM-17375] [PM-17379] - LandingScreen Design Audit (#4611) 2025-01-24 21:02:21 +00:00
Patrick Honkonen
464f8de5f5 [PM-17424] Implement KeyManager for handling private keys (#4608) 2025-01-24 20:55:33 +00:00
David Perez
3a6db38172 Update BitwardenPasswordField TestTags (#4621) 2025-01-24 17:08:33 +00:00
Dave Severns
dbefcfe342 PM-16630 PM-16621 Add logins action card and add explore generator card to be able to trigger coach marks (#4616) 2025-01-24 16:19:13 +00:00
bw-ghapp[bot]
e2d2d7fd7d Autosync Crowdin Translations (#4619)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2025-01-24 14:08:06 +00:00
David Perez
31ccf490ae PM-17409: Allow nullable labels text fields (#4617) 2025-01-23 23:07:23 +00:00
David Perez
50ae0902f0 PM-14179: Update internal placement of test tags for the BitwardenTextField (#4612) 2025-01-23 22:10:18 +00:00
David Perez
873f416fec PM-15804, PM-17130: Add logic to monitor when the screen on state to ensure the vault locks properly (#4610) 2025-01-23 21:58:11 +00:00
David Perez
70e72da404 PM-17410: Update password hint font (#4614) 2025-01-23 21:54:07 +00:00
Phil Cappelli
d573ce6e10 PM-17074-PM-17802 - Send Screen Design Updates (#4604) 2025-01-23 17:23:24 +00:00
Patrick Honkonen
e9159cc8c1 [PM-15906] Implement single tap passkey flows (#4547) 2025-01-23 16:38:36 +00:00
David Perez
bf60f8f9e3 PM-17404: Set app delegate on theme change (#4605) 2025-01-22 20:02:18 +00:00
Patrick Honkonen
2787edbf45 [PM-17405] Add mutual TLS feature flag (#4606) 2025-01-22 14:41:57 +00:00
SymphonicDeviation
bb5aeaaf15 [PM-17099] Re-Sort Quetta Browser Alphabetically (#4562) 2025-01-21 21:52:08 +00:00
ifernandezdiaz
f68f44615c [QA-980] Adding missing testTags for Custom fields (#4569) 2025-01-21 21:47:07 +00:00
renovate[bot]
66ff5942e4 [deps]: Update gh minor (#4591)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-21 19:48:48 +00:00
renovate[bot]
a11d8eff4a [deps]: Update kotlin (#309) 2025-01-21 19:46:30 +00:00
Patrick Honkonen
b233505c24 [PM-16391] Update Gradle and Android Gradle Plugin (#321) 2025-01-21 14:41:30 -05:00
renovate[bot]
ad564f98ef [deps]: Update gh minor (#318) 2025-01-21 19:38:39 +00:00
renovate[bot]
d488e7d5dd [deps]: Lock file maintenance (#320) 2025-01-21 14:36:35 -05:00
bw-ghapp[bot]
2d66fb5702 Autosync Crowdin Translations (#317) 2025-01-21 14:19:45 -05:00
Dave Severns
2b94e01c56 PM-16631 Applying CoachMarkContainer to the AddLoginItem content. (#4571) 2025-01-21 16:31:45 +00:00
David Perez
08e51fde98 Update the AndroidX Activity library to 1.10.0 (#4599) 2025-01-20 22:17:00 +00:00
David Perez
e25743e3f0 Update Firebase to the latest version v33.8.0 (#4598) 2025-01-20 20:28:28 +00:00
Phil Cappelli
055c598491 PM-16850-PM-16851-PM-16852 - Updating full screen loading indicator (#4581) 2025-01-20 19:24:55 +00:00
renovate[bot]
a185a94d56 [deps]: Update androidx.compose:compose-bom to v2025 (#4593)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-20 16:02:49 +00:00
renovate[bot]
f1ee9c89c0 [deps]: Lock file maintenance (#4594)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-20 15:03:00 +00:00
renovate[bot]
5b81c4dc7c [deps]: Update org.jetbrains.kotlinx.kover to v0.9.1 (#4592)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-20 15:02:34 +00:00
David Perez
e54d9ab5a9 Remove outer box on EnvironmentSelector (#4577) 2025-01-17 15:07:11 +00:00
David Perez
f9fc61ecf5 Add spacer between type and name when creating a login cipher (#4579) 2025-01-17 15:06:54 +00:00
bw-ghapp[bot]
a0eadc282b Autosync Crowdin Translations (#4580)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2025-01-17 15:05:32 +00:00
David Perez
412649ed9e Add correct card padding to BitwardenHiddenPasswordField (#4576) 2025-01-16 16:52:42 +00:00
André Bispo
be4014962c [PM-16905] Add back button to new device notice (#4570) 2025-01-16 15:05:36 +00:00
David Perez
5840bcdf85 PM-14179: Create and apply card style to UI (#4567) 2025-01-15 22:51:14 +00:00
ifernandezdiaz
2672f426dc [QA-969] Adding missing testTag for Folder Name textfield (#4564) 2025-01-15 18:59:37 +00:00
ifernandezdiaz
20f9421ea4 [QA-968] Adding missing testTag for MP hint email field (#4565) 2025-01-15 18:59:00 +00:00
Álison Fernandes
c1bb58cf17 [PM-17119] Add domains to network config (#4568) 2025-01-15 16:54:20 +00:00
Matt Andreko
f92d748de3 Update SonarQube GitHub Action (#316) 2025-01-14 09:48:46 -05:00
Phil Cappelli
21597ba746 PM-16830 - Update global loading screen component to new reskinned version (#4558) 2025-01-13 19:09:29 +00:00
Patrick Honkonen
efbb959ecc [PM-17011] Move network managers to network package (#4559) 2025-01-13 18:59:21 +00:00
David Perez
b128d5de0a Update AGP to v8.8.0 (#4557) 2025-01-13 16:08:44 +00:00
Álison Fernandes
41d9e96406 [PM-16827] Only report coverage when tests pass (#4550) 2025-01-10 20:20:58 +00:00
renovate[bot]
ac6bb35d76 [deps]: Update gh minor (#4551)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-10 19:26:56 +00:00
Patrick Honkonen
1316882ef4 [BWA-141] Use files instead of file in codecov action (#315) 2025-01-10 10:55:07 -05:00
renovate[bot]
7fdb669786 [deps]: Update sonarsource/sonarcloud-github-action action to v4 (#297) 2025-01-10 15:37:03 +00:00
Phil Cappelli
f595cee7f6 BWA-106 - Import process failures with limited error feedback (#313) 2025-01-10 10:32:34 -05:00
bw-ghapp[bot]
43844739a2 Autosync Crowdin Translations (#314) 2025-01-10 09:54:23 -05:00
SymphonicDeviation
a3096c04f1 [PM-14240] Add Quetta Browser to Privileged Apps (#4189) 2025-01-10 14:49:24 +00:00
Patrick Honkonen
0684011bda [PM-15918] Update bitwarden SDK (#4529) 2025-01-10 14:39:04 +00:00
bw-ghapp[bot]
eef0b1cbbb Autosync Crowdin Translations (#4546)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2025-01-10 14:30:06 +00:00
celenityy
542d2ad1e9 [PM-16870] Add support for IronFox (#4534)
Co-authored-by: Patrick Honkonen <1883101+SaintPatrck@users.noreply.github.com>
2025-01-10 14:24:47 +00:00
André Bispo
e63a549485 [PM-16808] Add question mark to copy (#4544) (#4545) 2025-01-10 09:44:08 +00:00
André Bispo
3e552564dc [PM-16670] Add check for 2fa status #4542 (#4543) 2025-01-09 22:44:06 +00:00
Patrick Honkonen
0a8d1fa0f5 [PM-9439] Use passkey icon for items with FIDO2 credentials in search results (#4541) 2025-01-09 21:10:02 +00:00
David Perez
f2c87d1f66 PM-15356: Resolve biometrics bypass (#4448) 2025-01-09 20:45:14 +00:00
mpbw2
2f2db1a03f [PM-13349] Hide Edit option in cipher list item overflow when editing not permitted (#4539) 2025-01-09 20:29:08 +00:00
Álison Fernandes
0493710cb4 [PM-16827] Fix test.yml sdk package access and refactor test jobs (#4538) 2025-01-09 20:17:04 +00:00
aj-rosado
b5d73c98fe [PM-16695] Learn more new device verification (#4527)
Co-authored-by: André Bispo <abispo@bitwarden.com>
2025-01-09 14:40:19 +00:00
André Bispo
6b6e95aa3f [PM-16670] Force app to sync after 2FA notice (#4525) (#4536) 2025-01-09 00:25:38 +00:00
André Bispo
f35ee76c95 [PM-16809] Fix remind me later date (#4526) (#4535) 2025-01-08 22:57:10 +00:00
David Perez
bb66150b5c PM-14179: Update generator screen copy button (#4530) 2025-01-08 19:14:00 +00:00
Patrick Honkonen
9c2a902b51 [PM-16120] Defer passkey authentication until vault data is loaded (#4524) 2025-01-07 21:00:49 +00:00
renovate[bot]
69da467b7c [deps]: Lock file maintenance (#4502)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-07 20:58:20 +00:00
renovate[bot]
c8d3f341a8 [deps]: Update gh minor (#4496)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Patrick Honkonen <1883101+SaintPatrck@users.noreply.github.com>
2025-01-07 20:26:31 +00:00
David Perez
3717e33d00 PM-16821: remove padding on right side of the vault screen dividers (#4528) 2025-01-07 16:54:22 +00:00
Dave Severns
7ab72543a3 PM-14333 fix case of crowdin translation not adding annotations on string with format args (#4505) 2025-01-07 15:30:34 +00:00
Dave Severns
80f31cdff9 PM-16474 Adding custom field issues when another text field holds focus (#4511) 2025-01-07 14:52:12 +00:00
bw-ghapp[bot]
40056f3181 Autosync Crowdin Translations (#306) 2025-01-07 13:58:44 +00:00
renovate[bot]
b0e9703d9f [deps]: Update kotlin (#4501)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-06 22:03:10 +00:00
Phil Cappelli
0ca97de1b2 BWA-118 Tutorial text cut off in landscape mode (#312) 2025-01-06 14:55:21 -05:00
mpbw2
b958734946 [PM-13349] Hide edit button unless item is in at least one non-readOnly collection (#4430) 2025-01-06 17:59:30 +00:00
renovate[bot]
2acede98f3 [deps]: Lock file maintenance (#310) 2025-01-06 17:57:59 +00:00
renovate[bot]
fb2edf43be [deps]: Update gh minor (#307) 2025-01-06 17:56:49 +00:00
bw-ghapp[bot]
484faedcc5 Autosync Crowdin Translations (#4503)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
Co-authored-by: Patrick Honkonen <1883101+SaintPatrck@users.noreply.github.com>
2025-01-06 17:31:37 +00:00
André Bispo
8bde8741dd [PM-8217] Add local feature flag to ignore environment validation (#4521) 2025-01-06 15:32:53 +00:00
André Bispo
d5a02e6285 [PM-15969] Users with Can Edit access cannot assign collections (#4522) 2025-01-06 15:11:16 +00:00
André Bispo
a35ec8cf3c [PM-8217] New device two factor notice (#4508)
Co-authored-by: Federico Maccaroni <fedemkr@gmail.com>
2024-12-27 15:03:33 +00:00
Dave Severns
ae8db9256c Update the text field to not use passed in modifier. (#4506) 2024-12-23 20:51:11 +00:00
André Bispo
688dd3a39b [PM-8217] Add creationDate and isTwoFactorEnable properties (#4504) 2024-12-23 18:56:55 +00:00
Dave Severns
6223f362c3 PM-16062 Prevent account locks for ongoing autofill requests (#4498) 2024-12-20 22:05:30 +00:00
Dave Severns
1148e4821c PM-14333 Complete fix for crash caused by spannable text creation (#4479) 2024-12-20 21:45:55 +00:00
Patrick Honkonen
f32eecc0d7 [PM-15864] Add copy private key action for SSH keys (#4462) 2024-12-20 19:44:31 +00:00
renovate[bot]
2ba516f50f [deps]: Lock file maintenance (#4497)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-20 19:20:14 +00:00
André Bispo
c4c7af54ff [PM-8217] New device notice two factor UI (#4401) 2024-12-20 18:08:23 +00:00
Patrick Honkonen
ae0bf6318d [PM-15176] Update script path for CI build info (#4493) 2024-12-20 18:06:56 +00:00
Patrick Honkonen
3be2242431 [PM-15643] Show FAB in empty item type filters (#4490) 2024-12-20 17:52:04 +00:00
Patrick Honkonen
d9c0911238 [PM-12391] Respect PIN unlock setting during FIDO user verification (#4483) 2024-12-20 17:51:29 +00:00
Patrick Honkonen
5aa8369ac5 [PM-15863] Request master password before revealing private SSH key (#4481) 2024-12-20 17:48:01 +00:00
Patrick Honkonen
35e8cecdcf [PM-15970] Allow assigning collections if user has correct permissions (#4461) 2024-12-20 17:33:09 +00:00
André Bispo
a7939414ae [PM-8217] New device notice email access UI (#4400) 2024-12-20 16:53:30 +00:00
Dave Severns
6c355ae5b7 PM-15383 PM-15381 - Show the google play review prompt (#4455)
Co-authored-by: Patrick Honkonen <1883101+SaintPatrck@users.noreply.github.com>
2024-12-20 15:30:39 +00:00
Álison Fernandes
843247b02d [PM-16211] chore(ci): Fix hotfix branch creation workflow by retrieving the last tag across all branches (#4491) 2024-12-20 14:30:46 +00:00
Patrick Honkonen
efbb8446e3 [PM-15057] Update AndroidX Credentials to 1.5.0-alpha04 (#4447) 2024-12-20 14:27:41 +00:00
bw-ghapp[bot]
a279a2b1a3 Autosync Crowdin Translations (#4494)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2024-12-20 14:19:32 +00:00
Lucas
3329dfaf20 [PM-15912] Fix alphabetical order in FIDO2 privileged browser community list (#4451) 2024-12-19 18:22:07 +00:00
Álison Fernandes
b615bfa664 [PM-16208] chore(ci): Split scan workflow for protected branches and migrate to new sonarqube action (#4489) 2024-12-18 23:49:41 +00:00
Álison Fernandes
f6bd467ec8 [PM-16207] chore(ci): Fix codecov usage and remove secrets from test.yml (#4488) 2024-12-18 21:48:12 +00:00
Dave Severns
8548c74d58 PM-16058 add test tag parameter to be applied to the text field (#4487) 2024-12-18 18:01:40 +00:00
Dave Severns
e2b93ec08c Add Phil to CODEOWNERS (#4480) 2024-12-17 19:07:27 +00:00
Dave Severns
e565a5a118 PM-15890 TLS related error propagation (#4454) 2024-12-17 17:56:29 +00:00
aj-rosado
3a41138f39 [PM-10515] CI build info on version copy (#4456)
Co-authored-by: Álison Fernandes <vvolkgang@users.noreply.github.com>
2024-12-17 17:36:46 +00:00
Dave Severns
889457ae96 PM-15037 Correct the text for the confirm error dialog on import logins screen (#4478) 2024-12-16 18:27:06 +00:00
Patrick Honkonen
be88cdf42e [PM-15176] Rename bundle and apk files to match applicationId and flavor (#4474) 2024-12-14 14:36:01 +00:00
David Perez
e37cefeb1d PM-16058 - Add default environments via autocomplete dropdown (#4473) 2024-12-13 23:04:02 +00:00
Phil Cappelli
ae20e55b1a PM-16053 - Text in Prompt to Restart App After Changing Language in Settings (#4472) 2024-12-13 22:26:00 +00:00
Patrick Honkonen
bd29e1738c [PM-16052] Add CI_INFO build config field (#4471) 2024-12-13 20:49:09 +00:00
David Perez
f28f5ee688 Update camera libraries (#4468) 2024-12-13 20:39:13 +00:00
David Perez
c92c334e03 Update the Firebase libraries (#4469) 2024-12-13 19:36:05 +00:00
David Perez
fb8f260a94 Update the Compose BOM (#4470) 2024-12-13 19:17:03 +00:00
Patrick Honkonen
9635bd9b43 [BWA-33]: Publish release bundles to Play Store when requested (#303) 2024-12-13 13:36:54 -05:00
Álison Fernandes
9f5e97b8c9 [PM-15176] chore(ci): Fix fastlane build artifacts names and filepaths (#4458) 2024-12-13 18:25:42 +00:00
bw-ghapp[bot]
8dd9ba65d0 Autosync Crowdin Translations (#302) 2024-12-13 12:48:37 -05:00
Patrick Honkonen
1aec94ee7d [PM-15176] Rename AAB outputs to match APK naming convention (#4467) 2024-12-13 16:43:49 +00:00
David Perez
d4b153107a Update to Hilt 2.53.1 (#4466) 2024-12-13 16:34:59 +00:00
Phil Cappelli
d405a0d04b PM-15976 - App crashes when non-english language user tries to create account (#4460) 2024-12-13 16:24:35 +00:00
David Perez
86587258c9 Remove unused google-services.json.enc (#4465) 2024-12-13 15:57:42 +00:00
bw-ghapp[bot]
7571d35fb3 Autosync Crowdin Translations (#4463)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2024-12-13 14:50:33 +00:00
André Bispo
c7bef56639 [PM-15553] Add remote flag to control cipher key encryption. (#4457) 2024-12-12 22:08:18 +00:00
Lucas
d5a75c2d53 [PM-15911] Add Firefox Nightly to FIDO2 community list (#4450) 2024-12-12 16:53:05 +00:00
Phil Cappelli
ad90785c39 BWA-124 - 'Copy' Option Missing from Long-Press Menu (#300) 2024-12-12 00:28:59 -05:00
Patrick Honkonen
e11b0c7839 [PM-15862] Remove Linked Fields option from SSH keys (#4453) 2024-12-12 00:11:12 +00:00
David Perez
a6929f2d8d Ensure DebugTree is only planted once (#4452) 2024-12-11 21:33:01 +00:00
Dave Severns
9b064eea90 PM-15380 Track user interactions which would trigger a potential showing of the app review prompt. (#4415) 2024-12-11 18:32:15 +00:00
Patrick Honkonen
d9ef87e21f [PM-15609] Move FIDO2 origin validation logic to Fido2OriginManager (#4426) 2024-12-11 18:17:51 +00:00
Patrick Honkonen
7b3ad98698 [PM-15176] Update build output filenames (#4446) 2024-12-11 17:20:40 +00:00
Patrick Honkonen
ea1a4e4710 Update CODEOWNERS (#301) 2024-12-11 10:31:45 -05:00
Phil Cappelli
2f678ba32e BWA-118 - Tutorial text cut off in landscape mode (#299) 2024-12-11 10:13:51 -05:00
David Perez
c00cdc7407 Run formatter on the app (#4444) 2024-12-09 22:21:49 +00:00
renovate[bot]
4bab5a59fc [deps]: Update sonarsource/sonarcloud-github-action action to v4 (#4434)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-09 21:47:32 +00:00
Dave Severns
4932353003 PM-15037 Add missing title to empty sync import logins error dialog (#4443) 2024-12-09 19:31:38 +00:00
David Perez
5997579330 PM-15599: Allow for custom TextToolbars (#4440) 2024-12-09 19:22:44 +00:00
renovate[bot]
7abb52b42d [deps]: Lock file maintenance (#4435)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-09 18:36:49 +00:00
renovate[bot]
5b0b3b6c70 [deps]: Update gradle minor (#295) 2024-12-09 13:35:35 -05:00
renovate[bot]
65d361625e [deps]: Lock file maintenance (#298) 2024-12-09 18:33:21 +00:00
renovate[bot]
8d09d9d604 [deps]: Update gh minor (#296) 2024-12-09 13:32:25 -05:00
Andrew Haisting
41cf116e6d BITAU-217 Update "Move to Bitwarden" copy to "Copy to Bitwarden" (#283) 2024-12-09 18:31:30 +00:00
Phil Cappelli
ddfd9bd0d8 PM-15831 - Enable remote configuration of enable-authenticator-sync-android feature flag (#4441) 2024-12-09 18:19:25 +00:00
renovate[bot]
5abdf1e4b0 [deps]: Update gh minor (#4433)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-09 14:55:41 +00:00
aj-rosado
4234008337 [PM-11139] Setting icon on passkeys (#4409) 2024-12-09 12:51:40 +00:00
Dave Severns
7b7c2da67c PM-15624 Align handling of no network states with iOS app. (#4431) 2024-12-06 22:24:38 +00:00
Patrick Honkonen
12dd865cec [PM-15116] Add common fields to SSH Key add/edit screen (#4428) 2024-12-06 21:49:16 +00:00
github-actions[bot]
ff09bdd110 Autosync Crowdin Translations (#293) 2024-12-06 12:04:08 -05:00
Andy Pixley
ec788f2472 [BRE-471] Update to use app generated token (#294) 2024-12-06 11:57:33 -05:00
bw-ghapp[bot]
0c53fa6c0b Autosync Crowdin Translations (#4427)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2024-12-06 14:28:32 +00:00
aj-rosado
b2eae2c33f [PM-13513] Keeping "androidapp" scheme on uri when saving from Android Apps (#4420) 2024-12-06 10:14:53 +00:00
Patrick Honkonen
7da1e48aa5 [PM-15057] Rename toFido2RequestOrNull to toFido2CreateRequestOrNull (#4425) 2024-12-05 18:20:29 +00:00
Álison Fernandes
10b6f533b2 [PM-9328] Mobile team owns changes to the .github folder (#4423) 2024-12-05 17:54:23 +00:00
David Perez
6a77dbe8b5 PM-15599: Update copy toast to not display copied value (#4424) 2024-12-05 17:00:53 +00:00
Álison Fernandes
6f7aedbcd2 [PM-15583] chore: Adds Autofill failure report form to GitHub issues menu (#4422) 2024-12-05 16:45:02 +00:00
Dave Severns
97285f463e PM-15514 add feature flag key for app review prompt (#4414) 2024-12-03 20:49:37 +00:00
renovate[bot]
6e643cb43b [deps]: Update kotlin (#285) 2024-12-03 12:41:34 -05:00
renovate[bot]
6cb734fb94 [deps]: Update gradle minor (#286) 2024-12-03 11:52:32 -05:00
Phil Cappelli
df846374f5 PM-15147 - MasterPasswordGuidanceScreen PR Cleanup (#4411) 2024-12-03 16:35:15 +00:00
Patrick Honkonen
65ff843ada [PM-15057] Add utility for loading FIDO2 icons (#4371) 2024-12-03 16:04:08 +00:00
renovate[bot]
26a7876525 [deps]: Update org.sonarqube to v6 (#4381)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-03 16:03:12 +00:00
renovate[bot]
718cece22e [deps]: Update kotlin (#4378)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: David Perez <david@livefront.com>
2024-12-03 15:37:26 +00:00
github-actions[bot]
00ce3c038b Autosync Crowdin Translations (#282) 2024-12-03 15:30:29 +00:00
renovate[bot]
d4e7211156 [deps]: Update org.sonarqube to v6 (#288) 2024-12-03 15:29:53 +00:00
renovate[bot]
1b3e254a3f [deps]: Lock file maintenance (#289) 2024-12-03 10:28:15 -05:00
renovate[bot]
52748ba66f [deps]: Update codecov/codecov-action action to v5 (#287) 2024-12-03 10:26:28 -05:00
André Bispo
86057b5923 [BWA-110] Retrofit ProGuard missing rule (#291) 2024-12-03 15:24:47 +00:00
Dave Severns
ef8223bd8b PM-15431 allow background activities to start by NFC manager for the … (#4410) 2024-12-03 15:24:36 +00:00
renovate[bot]
7d1e2fec90 [deps]: Update gh minor (#284) 2024-12-03 15:23:04 +00:00
David Perez
382597f356 Update Dagger Hilt library (#4406) 2024-12-02 23:29:19 +00:00
Phil Cappelli
45200d0480 PM-15067 - Replace "account" with "vault" in subtitle (#4402) 2024-12-02 22:25:53 +00:00
David Perez
1534fb598b Update to latest AGP (#4404) 2024-12-02 20:33:03 +00:00
Dave Severns
819cc625a1 PM-14995 Hide TOTP for non premium org items even if individual user has premium account (#4390) 2024-12-02 20:06:11 +00:00
Patrick Honkonen
7e82b6e400 [PM-15116] Add common vault item content to SSH keys (#4365) 2024-12-02 19:51:59 +00:00
renovate[bot]
02c44f514a [deps]: Update codecov/codecov-action action to v5 (#4380)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-02 19:51:08 +00:00
renovate[bot]
6ef5d4b6aa [deps]: Lock file maintenance (#4382)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-02 19:47:15 +00:00
David Perez
cb8c1341e2 Update to Robolectric 4.14.1 (#4403) 2024-12-02 19:46:23 +00:00
Phil Cappelli
b2391dd66a PM-15147 - Design Audit - Master Password Guidance Screen (#4383) 2024-12-02 19:38:45 +00:00
bw-ghapp[bot]
bca9f5e859 Autosync Crowdin Translations (#4396)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2024-12-02 16:49:41 +00:00
renovate[bot]
b654ef1b43 [deps]: Update gh minor (#4379)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-02 16:48:58 +00:00
Opeyemi
348abcefe9 [BRE-443] - Fix bwwl Linting pre Deployment (#4384) 2024-11-28 11:28:19 +00:00
Dave Severns
a96fcd944e PM-15412 Pull-to-refresh operations should not invoke a forced sync. (#4388) 2024-11-26 21:00:26 +00:00
David Perez
05aa52b032 Remove unused lastDatabaseSchemeChangeInstant from settings disk source (#4374) 2024-11-25 22:59:17 +00:00
David Perez
cce9befe8c Ensure lastSyncTime is updated before resyncing the vault (#4375) 2024-11-25 15:03:58 +00:00
David Perez
8e7ec7af4c PM-15177: Improve destructive fallback logic (#4373) 2024-11-22 22:21:15 +00:00
Dave Severns
2e1845887c PM-15022 Auto login when user completes a YubiKey login trigger. (#4368) 2024-11-22 18:01:49 +00:00
David Perez
c1be5be188 M-15177: All user input syncs should be forced (#4369) 2024-11-22 17:40:40 +00:00
Patrick Honkonen
76b6853f90 [PM-15113] Disable add button in SSH Keys screen (#4364) 2024-11-22 17:31:47 +00:00
Patrick Honkonen
89935ac42b [PM-15054] Add API for importing ciphers (#4339) 2024-11-22 17:30:59 +00:00
Phil Cappelli
050b3b3007 PM-15067 - Design Audit - Prevent Account Lockout Screen (#4361) 2024-11-22 17:14:18 +00:00
Patrick Honkonen
249dbdaaf8 [PM-15057] Rename Fido2CredentialRequest to Fido2CreateCredentialRequest (#4362) 2024-11-22 15:49:00 +00:00
Patrick Honkonen
dbb006d745 [PM-15064] Add feature flags for CXP import and export (#4337) 2024-11-22 15:22:14 +00:00
Patrick Honkonen
5d4197076c [PM-15050] Track vault registration for CXP export in settings (#4335) 2024-11-22 15:10:00 +00:00
Dave Severns
1e223b1a2a PM-15109 only accept numeric values for account pin lock value (#4359) 2024-11-22 13:59:01 +00:00
bw-ghapp[bot]
b19e7e1495 Autosync Crowdin Translations (#4363)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2024-11-22 01:54:52 +00:00
David Perez
1ef7e2173b Remove the BasicDialogState (#4360) 2024-11-21 21:19:12 +00:00
David Perez
bef6ffc094 Remove unused constant (#4358) 2024-11-21 20:50:37 +00:00
Dave Severns
06b08d595b Refactor usage of the ContentCard to always use the ContentBlock component. (#4357) 2024-11-21 20:27:18 +00:00
David Perez
4fb031d76c Simplify the usage of the BitwardenLoadingDialog (#4356) 2024-11-21 20:16:02 +00:00
David Perez
c4f13fc8bd Share the environment flow and provide better default (#4355) 2024-11-21 20:15:44 +00:00
David Perez
8a534d11d2 Simplify url check in BaseUrlInterceptor (#4354) 2024-11-21 20:15:24 +00:00
David Perez
57ea58fc3c Log vault deserialization errors (#4353) 2024-11-21 19:35:57 +00:00
David Perez
245fcd7502 PM-14963: Add toast when login via device succeeds (#4351) 2024-11-21 15:42:24 +00:00
Dave Severns
dbeb00ba1c PM-15036 Show visual feedback for the send code on export vault. (#4346) 2024-11-21 15:25:44 +00:00
David Perez
cbfd7ad1b1 Simplify the usage of basic dialogs (#4347) 2024-11-21 15:23:40 +00:00
Álison Fernandes
d4033a7705 [PM-11598] GitHub Release - Improve tag name and refactor inputs casing (#4349) 2024-11-21 12:52:59 +00:00
David Perez
96bd25eae5 PM-12733: Add error dialog to be displayed if TOTP code is blank (#4345) 2024-11-20 22:00:08 +00:00
Dave Severns
ec8e934bf4 PM-15062 Checking if the user has a no longer supported biometric as their only way of unlocking their account. (#4338) 2024-11-20 20:45:26 +00:00
David Perez
3092ba1fc6 PM-15110: Ensure all network requests always use the current environment data (#4344) 2024-11-20 19:36:43 +00:00
David Perez
5ea17700b3 PM-15025: Update sendVerificationEmail to handle error responses (#4336) 2024-11-19 20:03:07 +00:00
aj-rosado
d418444dc0 [PM-13831] Add copy button identity and note fields (#4302) 2024-11-19 16:31:00 +00:00
Dave Severns
531b003347 PM-15049 PW strength indicator design audit (#4334) 2024-11-19 15:16:27 +00:00
Dave Severns
dca88a58e7 PM-15037 Update Import Logins for design audit (#4333) 2024-11-19 15:16:16 +00:00
David Perez
da878a9fab PM-15041: Update stepper buttons (#4330) 2024-11-19 15:04:41 +00:00
David Perez
95552a7a55 PM-15040: Update Login screen button icons (#4329) 2024-11-19 15:04:16 +00:00
David Perez
90b638eff0 PM-15039: Update welcome screen for design audit (#4328) 2024-11-19 15:03:51 +00:00
David Perez
ccd4fd9aba PM-15038: Update custom switches to use standard component (#4327) 2024-11-19 15:03:23 +00:00
github-actions[bot]
5e94b1b689 Autosync Crowdin Translations (#277) 2024-11-18 22:43:19 +00:00
André Bispo
f3f51cf244 [BWA-86] Debug Menu #4 (#276) 2024-11-18 22:39:03 +00:00
André Bispo
5f109b5085 [BWA-86] Debug Menu #3 - feature flag service (#275) 2024-11-18 22:24:06 +00:00
David Perez
2d15c4864f Log JWT parsing errors (#4326) 2024-11-18 22:13:55 +00:00
ifernandezdiaz
b183f7af42 QA-999: Adding testTags for account switching options (#4324) 2024-11-18 22:03:19 +00:00
Dave Severns
2ece0856d4 PM-12761 Talkback UI Focus misalignment bug. (#4325) 2024-11-18 21:41:50 +00:00
David Perez
429c76ce03 PM-14200: Add count to sends type header (#4323) 2024-11-18 21:35:38 +00:00
André Bispo
a0cc8a8a3d [BWA-86] Debug Menu #2 - config service (#274) 2024-11-18 21:31:25 +00:00
André Bispo
5b53b50b01 [BWA-86] Debug Menu #1 - network layer (#272) 2024-11-18 21:11:09 +00:00
bw-ghapp[bot]
506d0f13c7 Autosync Crowdin Translations (#4322)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2024-11-18 18:22:19 +00:00
Vince Grassia
6a0a7d70bc BRE-438 - Update Crowdin workflow to use app token (#4321) 2024-11-18 17:52:04 +00:00
David Perez
3742940290 Update the Firebase BOM (#4317) 2024-11-18 15:06:08 +00:00
David Perez
1cb647b7ae Update compose BOM to 2024.11.0 (#4316) 2024-11-18 15:05:51 +00:00
David Perez
ffeae93728 PM-12733: Trim totp codes before saving them (#4315) 2024-11-18 15:05:00 +00:00
Patrick Honkonen
e90bd136f6 [PM-10483] Fix collection manage check for delete permission (#4313) 2024-11-18 14:26:58 +00:00
David Perez
30eb11b85e PM-14409: Add realtime check for when the accessibility service is enabled or disabled (#4314) 2024-11-15 22:15:19 +00:00
github-actions[bot]
a04598c77a Autosync Crowdin Translations (#4307)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2024-11-15 20:32:21 +00:00
David Perez
cad2df79b6 PM-14934: Allow accessibility autofill to fill just a username or just a password (#4312) 2024-11-15 20:15:02 +00:00
David Perez
089136552b PM-12259: Use validatePin SDK to validate the users pin (#4311) 2024-11-15 19:56:55 +00:00
Dave Severns
1b0bc13903 Fix typos in generator actions (#4310) 2024-11-15 16:32:09 +00:00
Patrick Honkonen
d125fab0b7 [PM-14843] Allow deletion of items in collections with manage permission (#4299) 2024-11-15 16:10:32 +00:00
Dave Severns
13210343db PM-14429 Set the min and max range of the slider to match the restrictions not update the min with the computed min. (#4305) 2024-11-14 20:36:01 +00:00
Patrick Honkonen
3c4ac8b01a [PM-14596] Sync on database scheme change (#4304) 2024-11-14 19:18:25 +00:00
Patrick Honkonen
0a888a72c8 [PM-14553] Make canManage property of collections optional (#4284) 2024-11-14 19:18:04 +00:00
André Bispo
40f33dff89 [PM-11304] Ownership Not Defaulting To Org and Collection (#4254) 2024-11-14 08:15:01 +00:00
Álison Fernandes
5938e38070 [PM-11598] GitHub Release Workflow (#4285) 2024-11-13 22:34:36 +00:00
Álison Fernandes
31bc171d6b [PM-14879] Release Branch creation workflow (#4294) 2024-11-13 22:23:48 +00:00
David Perez
0967234ad8 PM-14411: Autofill logic to work better with QuickTile (#4300) 2024-11-13 21:38:08 +00:00
David Perez
911c9e4704 Update androidx dependecies and target API (#4212) 2024-11-13 16:22:55 +00:00
Dave Severns
072c3a992c PM-14414 hides autofill card for all users if autofill service is enabled. (#4297) 2024-11-13 15:41:14 +00:00
Álison Fernandes
1e0e4831b8 [PM-14897] Enhance build.yml run summary and fix f-droid distribution (#4296) 2024-11-13 13:27:56 +00:00
David Perez
e804dbd48e PM-14851: Blank names should be considered null (#4292) 2024-11-12 21:30:07 +00:00
Dave Severns
9a5aa217e6 PM-14352 Dismiss Snackbar when user clicks it as a default unless the specific dismiss action is present. (#4291) 2024-11-12 18:39:30 +00:00
Andrew Haisting
c6beaec102 BITAU-200 Log non-fatal authenticator bridge errors (#4228)
Co-authored-by: Patrick Honkonen <phonkonen@bitwarden.com>
2024-11-12 16:15:21 +00:00
renovate[bot]
5a9944f79d [deps]: Update gh minor (#4279)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-12 15:52:20 +00:00
David Perez
89c267aa5d PM-14854: Keep NetworkResult to avoid obfuscation crash in release (#4289) 2024-11-12 15:38:49 +00:00
David Perez
f33296b44f PM-14805: Use network result in all Retrofit API requests (#4286) 2024-11-11 22:17:57 +00:00
David Perez
a8416b073e Improve accessibility autofill performance (#4276) 2024-11-11 21:08:05 +00:00
Dave Severns
fd4a7c5716 PM-14597 remove notification if device login is decleined (#4256) 2024-11-11 21:02:35 +00:00
David Perez
771e719963 PM-14805: Ensure results cannot be double wrapped from 'asSuccess' (#4283) 2024-11-11 20:46:55 +00:00
renovate[bot]
abbf6565d4 [deps]: Update gradle minor (#280) 2024-11-11 19:48:34 +00:00
renovate[bot]
5263329ab5 [deps]: Lock file maintenance (#281) 2024-11-11 14:28:49 -05:00
renovate[bot]
c3d2c17830 [deps]: Update kotlin (#279) 2024-11-11 14:27:56 -05:00
renovate[bot]
29213421ec [deps]: Update gh minor (#278) 2024-11-11 14:27:07 -05:00
Patrick Honkonen
c5293715e1 [PM-14526] Add JsonNames annotation to SyncResponseJson (#4269)
Co-authored-by: David Perez <david@livefront.com>
2024-11-11 17:56:27 +00:00
Patrick Honkonen
2c40a7f105 [PM-14589] Prevent SSH key item creation (#4251) 2024-11-11 16:52:53 +00:00
André Bispo
a3ed2bc068 [PM-11303] Add button missing for folders (#4250) 2024-11-11 16:26:04 +00:00
David Perez
16cc70f344 Clean up the generator screen and handlers (#4270) 2024-11-11 16:07:16 +00:00
Dave Severns
6dd783051f PM-13803 Check to see if an existing admin request is pending before … (#4271) 2024-11-11 15:53:11 +00:00
renovate[bot]
1bb85d0fa0 [deps]: Update com.google.devtools.ksp to v2.0.21-1.0.27 (#4278)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-11 15:51:29 +00:00
Dave Severns
dfeb87be10 PM-13988 Hide the action card if the user makes a selection but does not click continue on setup unlock (#4249) 2024-11-11 15:31:21 +00:00
renovate[bot]
dae50a7b88 [deps]: Lock file maintenance (#4280)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-11 15:19:22 +00:00
David Perez
63324fcec1 PM-14458: Fix notifications prompt on first use (#4275) 2024-11-08 23:02:58 +00:00
Patrick Honkonen
49642f5a1d [PM-14656] Add default value to BaseEnumeratedIntSerializer (#4272) 2024-11-08 22:21:16 +00:00
David Perez
016d0f889c PM-14411: Allow accessibility autofill to run when app is already in background (#4255) 2024-11-08 21:30:14 +00:00
Andrew Haisting
5184be0e98 BITAU-185 Show "Local codes" header on item list screen (#269) 2024-11-08 15:30:10 -06:00
Andrew Haisting
0643ecc00b BITAU-195 Allow issuer to be null for shared items (#268) 2024-11-08 15:03:19 -06:00
Andrew Haisting
7e5dcd3814 BITAU-197 Update copy in all Save to Bitwarden scenarios (#271) 2024-11-08 14:47:37 -06:00
Patrick Honkonen
fe84feb184 PM-14433: Null domain data (#4268)
Co-authored-by: Dave Severns <149429124+dseverns-livefront@users.noreply.github.com>
Co-authored-by: David Perez <david@livefront.com>
2024-11-08 20:18:18 +00:00
aj-rosado
54d3b34876 [PM-11753] Listening to vaultUnlock state on mutableCiphers, folders, collections and send state flow (#4214) 2024-11-08 18:33:49 +00:00
Patrick Honkonen
b6dfc3d17b PM-14433 update flow type to nullable so we can handle gracefully and avoid crash (#4263)
Co-authored-by: Dave Severns <149429124+dseverns-livefront@users.noreply.github.com>
2024-11-08 18:23:39 +00:00
github-actions[bot]
96c6b9c214 Autosync Crowdin Translations (#4260)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
Co-authored-by: Patrick Honkonen <1883101+SaintPatrck@users.noreply.github.com>
2024-11-08 17:47:22 +00:00
David Perez
27666c193e PM-14644: Segmented control should be conditionally displayed for modal generator screen (#4262) 2024-11-08 17:03:54 +00:00
Dave Severns
b76f7202a4 PM-14621 update the copy for step three instruction and cta button (#4259) 2024-11-08 14:36:54 +00:00
Patrick Honkonen
7ccba88780 [PM-13360] Respect manage permission to assign collections (#4190) 2024-11-07 20:47:22 +00:00
Patrick Honkonen
87d324b063 [PM-12922] Disable delete if user can't manage collection (#4179) 2024-11-06 23:42:06 +00:00
Dave Severns
e397c036e4 PM-14353 : Clean up consumed snackbar on quick resubmission due to state based nav. (#4235) 2024-11-06 19:39:55 +00:00
David Perez
29384596d4 PM-14410: App restart timeout action (#4237) 2024-11-06 17:40:54 +00:00
github-actions[bot]
88a741c93a Autosync Crowdin Translations (#4217)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
Co-authored-by: Patrick Honkonen <1883101+SaintPatrck@users.noreply.github.com>
2024-11-06 17:26:48 +00:00
David Perez
db3490f61a PM-14480: Update IntentManager to be able to launch apps (#4233) 2024-11-05 17:36:10 +00:00
David Perez
4930c1032e PM-14458: Update notifications permissions request (#4229) 2024-11-05 17:16:58 +00:00
Dave Severns
202b4de5ca PM-13848 Handle URIs with ports and host matching (#4203) 2024-11-05 15:29:05 +00:00
Andrew Haisting
6763bfd997 BITAU-198 Update some copy on the manual entry screen (#273) 2024-11-05 08:54:59 -06:00
github-actions[bot]
aeba03a769 Autosync Crowdin Translations (#267)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2024-11-05 13:52:59 +00:00
Andrew Haisting
8f9585e4bc Bump authenticatorbridge sdk version to 1.0.0 (#4221) 2024-11-04 14:24:36 +00:00
André Bispo
e5e0464929 [PM-12406] Introduce new endpoint and replace SSO details response flow (#4177) 2024-11-04 10:53:57 +00:00
Andrew Haisting
7f25fa07a4 Use authenticatorbridge version 1.0.0 (#270) 2024-11-01 16:41:40 -05:00
David Perez
c2537f329d PM-14036: Add extra slider padding (#4220) 2024-11-01 19:12:55 +00:00
ifernandezdiaz
b7ffa3966d QA-970: Adding testTags for radiobutton and floating options elements (#4188)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Dave Severns <149429124+dseverns-livefront@users.noreply.github.com>
Co-authored-by: David Perez <david@livefront.com>
Co-authored-by: Patrick Honkonen <1883101+SaintPatrck@users.noreply.github.com>
Co-authored-by: Álison Fernandes <vvolkgang@users.noreply.github.com>
2024-11-01 19:03:44 +00:00
David Perez
9240fb82e4 PM-14379: Stop storing 'null' in as the word separator (#4219) 2024-11-01 19:03:03 +00:00
David Perez
2eb41e932b PM-14044: Fix line-breaking logic (#4218) 2024-11-01 16:21:48 +00:00
David Perez
51e299998f Update to AGP 8.7.2 (#4216) 2024-11-01 15:19:03 +00:00
Andrew Haisting
8b00773c84 BITAU-193 Make first time sync snackbar correct in dark theme (#266) 2024-10-31 16:54:58 -05:00
Andrew Haisting
b42ec0ae13 BITAU-89 Have SettingsViewModel obsererve DefaultSaveOption (#265)
Co-authored-by: Patrick Honkonen <1883101+SaintPatrck@users.noreply.github.com>
2024-10-31 21:33:02 +00:00
Andrew Haisting
78d7865207 BITAU-178 Show shared codes on the search screen (#264)
Co-authored-by: Patrick Honkonen <1883101+SaintPatrck@users.noreply.github.com>
2024-10-31 21:32:52 +00:00
Patrick Honkonen
2f6578fd5a [PM-14273] Add copy functionality for SSH key fields (#4204) 2024-10-31 20:41:13 +00:00
Patrick Honkonen
0844939eca [PM-14271] Disable editing SSH key fields in edit mode (#4201) 2024-10-31 20:40:33 +00:00
Patrick Honkonen
8f2d55c146 [PM-14346] Run alias generation on the IO dispatcher (#4215) 2024-10-31 20:39:11 +00:00
David Perez
3e5e6ce3ab Update compose BOM to 2024.10.01 (#4213) 2024-10-31 20:11:31 +00:00
David Perez
4831750ffd PM-14255: Remove accessibility logic to improve overall performance (#4206) 2024-10-31 18:05:33 +00:00
David Perez
7d7380d622 Update genrator icons on bottom nav (#4211) 2024-10-31 17:29:41 +00:00
David Perez
a0b9e92ae9 Update the camera library (#4210) 2024-10-31 16:27:28 +00:00
Álison Fernandes
ce180f1bbb [PM-14261] Update README and bugs template to remove Beta references (#4198) 2024-10-31 10:43:41 +00:00
David Perez
c99e5ce2de PM-13842: Hide ownership when the user has no organizations (#4199) 2024-10-30 20:13:15 +00:00
Andrew Haisting
5ac5e31dd2 BITAU-184 Allow user to save to Bitwarden when adding a code manually (#263) 2024-10-30 15:12:54 -05:00
Patrick Honkonen
eaa7923d1f [PM-14186] Update SDK to make SSH key properties required (#4200) 2024-10-30 18:42:33 +00:00
Andrew Haisting
bcc7e6756e BITAU-84 Show Snackbar the first time a user syncs accounts (#259) 2024-10-30 11:12:47 -05:00
Patrick Honkonen
56367cc14e [PM-13900] Update Bitwarden SDK to add canManage to Collection objects (#4169) 2024-10-30 15:53:30 +00:00
Dave Severns
6e0ce3b742 PM-13155 add shortcuts file to beta source set for beta app id (#4196) 2024-10-30 15:53:12 +00:00
Andrew Haisting
aa42e0ad18 BITAU-189 BITAU-188 Only show default save option row when sync is en… (#261) 2024-10-30 10:32:57 -05:00
Andrew Haisting
c0abc1d647 BITAU-76 Update copy on download Bitwarden action card (#260) 2024-10-30 10:06:34 -05:00
Andrew Haisting
5de6dc3473 BITAU-89 Show save location dialog on the QR scan screen (#258) 2024-10-30 10:02:03 -05:00
Patrick Honkonen
fab018782c [PM-14254] Keep Android verifier for JNI usage (#4197) 2024-10-30 14:48:49 +00:00
aj-rosado
0211729525 [PM-14241] Backport Timber hotfix (#4195) 2024-10-30 12:49:25 +00:00
ifernandezdiaz
540ece5a40 QA-954: Add testtags to Send screen elements (#4162) 2024-10-29 23:21:08 +00:00
Patrick Honkonen
bb6255b6a4 Disable ExtraTranslation lint check (#262) 2024-10-29 18:12:21 -04:00
Patrick Honkonen
78e7adfbc1 [PM-10405] Add SSH key cipher type (#4158) 2024-10-29 21:40:20 +00:00
David Perez
6f26ae50ea PM-14044: Update generator line breaks to account for padding on both sides (#4187) 2024-10-29 21:20:44 +00:00
Álison Fernandes
a5e57f1836 [PM-14224] Automate Play Store prod variant publishing (#4183) 2024-10-29 18:33:21 +00:00
David Perez
9e5fefa3ee Update copy and generate icons (#4185) 2024-10-29 18:31:12 +00:00
Dave Severns
8b16135955 PM-11188 show snackbar after import success. PM-13943 add relay for snackbar events across screen contexts. (#4152) 2024-10-29 18:23:00 +00:00
David Perez
a1108889cb PM-14200: Update the eyebrows throughout the app (#4181) 2024-10-29 13:57:16 +00:00
David Perez
150c8e0312 PM-14201: Update the default divider thickness (#4182) 2024-10-29 13:56:57 +00:00
Dave Severns
f3916b4ef6 PM-13988 observe changes to unlock status on settings screen (#4180) 2024-10-29 13:27:46 +00:00
ifernandezdiaz
8df4292e08 QA-957: Adding missing testTag for collection list container (#4178) 2024-10-29 12:12:07 +00:00
Dave Severns
05c768610e PM-13908 fixing copy on step2 and step3 and making vault url dynamic (#4154) 2024-10-28 19:11:25 +00:00
Dave Severns
21a5242abe PM-14009 complete fix importlogins card show logic (#4175) 2024-10-28 18:22:30 +00:00
Patrick Honkonen
deb9eb8d9b [PM-13908] Disable ExtraTranslation lint warning (#4176) 2024-10-28 17:47:27 +00:00
David Perez
4a91d87d9d PM-14184: Update the switch thoughout the app (#4170) 2024-10-28 17:09:29 +00:00
renovate[bot]
408d01d546 [deps]: Update com.google.devtools.ksp to v2.0.21-1.0.26 (#254) 2024-10-28 12:43:00 -04:00
renovate[bot]
3b9e42a256 [deps]: Update gradle minor (#256) 2024-10-28 14:46:02 +00:00
github-actions[bot]
6d500e52e7 Autosync Crowdin Translations (#253)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2024-10-28 14:43:02 +00:00
renovate[bot]
3f72b49286 [deps]: Lock file maintenance (#257) 2024-10-28 14:42:34 +00:00
renovate[bot]
8b9f13e9e7 [deps]: Update gh minor (#255) 2024-10-28 10:38:52 -04:00
Dave Severns
064db9fb6a PM-13698 only dismiss the card if the user dismisses or completes the… (#4165) 2024-10-28 14:38:17 +00:00
ifernandezdiaz
c47f8606cd QA-953: Adding testTag to elements in Add TOTP screen (#4160) 2024-10-28 14:28:07 +00:00
renovate[bot]
3e2f10a5b9 [deps]: Update com.google.devtools.ksp to v2.0.21-1.0.26 (#4172)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-28 14:27:53 +00:00
renovate[bot]
b060b70a6b [deps]: Update gh minor (#4173)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-28 14:26:16 +00:00
renovate[bot]
7ea7d78e66 [deps]: Lock file maintenance (#4174)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-28 14:19:02 +00:00
David Perez
b64175ff6e Update fab design (#4168) 2024-10-25 21:29:16 +00:00
Andrew Haisting
164cc09f19 BITAU-182 BITAU-107 Don't show authetnicator sync toggle below API 31 (#4156) 2024-10-25 21:27:59 +00:00
David Perez
0960f61c37 Simplify usages of turbineScope (#4167) 2024-10-25 19:50:43 +00:00
github-actions[bot]
f8bf864fc9 Autosync Crowdin Translations (#4159)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
Co-authored-by: Patrick Honkonen <1883101+SaintPatrck@users.noreply.github.com>
2024-10-25 19:44:01 +00:00
David Perez
93aece75cf PM-14036: Update the slider UI (#4164) 2024-10-25 18:11:54 +00:00
Andrew Haisting
5159258de5 Make isBuildVersionBelow in authenticatorbridge internal (#4157) 2024-10-25 16:39:53 +00:00
ifernandezdiaz
68a834ac14 QA-955: Adding testTag to About screen rows (#4163) 2024-10-25 16:32:27 +00:00
ifernandezdiaz
33a430419c QA-952: Adding test tags for Toggle items (#4153) 2024-10-25 15:53:48 +00:00
Dave Severns
eb4ffebba0 PM-14009 Refactor storing first time values to the first time action manager (#4161) 2024-10-25 15:40:18 +00:00
David Perez
53d4c4c03e Remove query params from network logging (#4155) 2024-10-24 20:18:20 +00:00
David Perez
e80585f77e PM-13937: Update button padding, remove unused buttons, and rename button (#4151) 2024-10-24 18:21:38 +00:00
ifernandezdiaz
0ff2fe6d6a QA-951: Adding missing IDs for Attachment rows (#4148) 2024-10-24 17:31:56 +00:00
Dave Severns
b0885ff60a PM-13886 show dialog when no logins were imported (#4139) 2024-10-24 17:06:30 +00:00
David Perez
a55fbca16a Update Firebase BOM to 33.5.1 (#4150) 2024-10-24 15:59:51 +00:00
ifernandezdiaz
fcd69e3e6f QA-950: Adding testTag for VaultUnlockedNavBar component (#4146) 2024-10-24 15:42:21 +00:00
David Perez
28e87fe216 PM-13937: Consolidate button UI and logic (#4149) 2024-10-24 15:27:06 +00:00
Andrew Haisting
1d2095b0b3 BITAU-181 Allow user to update default save options from settings (#252) 2024-10-24 09:49:07 -05:00
Dave Severns
1c10a94109 PM-11187 show import success bottom sheet after success import sync (#4125) 2024-10-24 14:44:14 +00:00
David Perez
6f535c0abe PM-13937: Replace tonal buttons with outline buttons (#4147) 2024-10-24 13:58:40 +00:00
Andrew Haisting
5fdfb26950 BITAU-180 Show "Move to Bitwarden" long press action (#250) 2024-10-24 08:38:55 -05:00
Patrick Honkonen
bdb6136d36 [PM-13980] Add SSH Key Cipher Item Types feature flag (#4144) 2024-10-24 13:16:31 +00:00
Patrick Honkonen
2d9451cc34 [PM-13900] Track last database scheme change (#4124) 2024-10-24 13:15:54 +00:00
ifernandezdiaz
6217532237 QA-948: Adding missing testTags on SSO/TDE views (#4145) 2024-10-23 19:28:03 +00:00
David Perez
ef1e8403e1 PM-13939: Remove hyphen from auto-fill (#4141) 2024-10-23 17:58:28 +00:00
Patrick Honkonen
24c8406ed8 Upload test reports on test and build workflow failures (#4143) 2024-10-23 16:53:20 +00:00
David Perez
51c87625cb Ensure unmockk static is called in test teardown (#4142) 2024-10-23 16:18:45 +00:00
Andrew Haisting
fa248243b6 BITAU-112 Support deep link into add item flow from Authenticator app (#4128) 2024-10-23 16:17:31 +00:00
rad
f1d7d1a530 [PM-13857] Add Iceraven to privlieged browsers (#4122)
Co-authored-by: Patrick Honkonen <1883101+SaintPatrck@users.noreply.github.com>
2024-10-23 15:14:46 +00:00
David Perez
79ebd2ba33 User TImber instead of LogsManager directly (#4140) 2024-10-23 15:11:31 +00:00
Andrew Haisting
5d7656323b Add queries to AndroidManifest (#251) 2024-10-23 09:53:16 -05:00
Dave Severns
a23fc319de PM-13943 : PT1 Custom snackbar UI (#4135) 2024-10-23 14:44:59 +00:00
vphan916
932c26dfc6 QA Automation - Locators for Android (#214) 2024-10-23 13:48:22 +00:00
renovate[bot]
5c38522ec6 [deps]: Update kotlin (#235) 2024-10-23 09:39:59 -04:00
David Perez
c5a266dfc0 PM-13020: During totp flow master password reprompt should be honored (#4136) 2024-10-23 12:51:28 +00:00
David Perez
fca00d38f5 PM-13024: After saving cipher in totp flow, app should not close (#4137) 2024-10-22 22:12:36 +00:00
David Perez
65380095f0 Update Compose BOM and Androidx activity libs (#4134) 2024-10-22 19:37:55 +00:00
David Perez
002fd06b72 This PR adds Timber to the app (#4116) 2024-10-22 17:37:03 +00:00
David Perez
5d85060260 Update Firebase BOM to 33.5.0 (#4133) 2024-10-22 16:26:56 +00:00
David Perez
4dfee643a0 Update Junit 5 (5.11.3) (#4132) 2024-10-22 16:25:04 +00:00
David Perez
7aab846244 Apply the formatter to the entire app (#4129) 2024-10-22 14:00:10 +00:00
Andrew Haisting
ab4d9b9984 BITAU-78 Show SyncWithBitwarden action card (#248) 2024-10-21 17:21:26 -05:00
github-actions[bot]
74b1bc8303 Autosync Crowdin Translations (#247) 2024-10-21 22:07:01 +00:00
Patrick Honkonen
25e01c86bc Mark IntentManagerImpl as not covered by code coverage (#249) 2024-10-21 16:25:14 -05:00
Dave Severns
c704cd2eca PM-13627 show action card on vault settings if applicable (#4101) 2024-10-21 20:51:49 +00:00
David Perez
09c11f4890 Fix authenticator test (#4127) 2024-10-21 20:46:30 +00:00
David Perez
df6e842201 Create single helper method to clean up the MainViewModelTest (#4126) 2024-10-21 20:42:11 +00:00
David Perez
b82614e5fa PM-13847: Totp click on search should go directly to edit screen (#4123) 2024-10-21 19:48:54 +00:00
David Perez
27beb25bf7 PM-13690: Add dialog before switching account during passwordless login (#4114) 2024-10-21 19:35:19 +00:00
Andrew Haisting
d1f13e49a4 Use array to define knownCerts for authenticator bridge permission (#4103) 2024-10-21 18:47:40 +00:00
David Perez
36a718753d PM-13021: Update no item found copy for totp (#4115) 2024-10-21 14:00:22 +00:00
Patrick Honkonen
be0ebb9b3f [PM-13396] Add support for legacy error response model in getToken (#4112) 2024-10-21 13:23:49 +00:00
Dave Severns
4fc01c77d1 PM-11186 Sync in progress for import logins and full screen loading. (#4117) 2024-10-18 18:37:06 +00:00
github-actions[bot]
258f25cd37 Autosync Crowdin Translations (#4118)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
Co-authored-by: Patrick Honkonen <1883101+SaintPatrck@users.noreply.github.com>
2024-10-18 18:18:01 +00:00
Patrick Honkonen
98c3ced191 [PM-13825] Update Google sourced FIDO 2 privileged app list (#4121) 2024-10-18 17:15:11 +00:00
Dave Severns
c26a7cdf28 PM-13464 show notification badge for vault settings if the showImport… (#4096) 2024-10-18 17:13:23 +00:00
Andrew Haisting
b127021701 Distribute Firebase builds to livefront group. (#243) 2024-10-17 15:25:00 -05:00
Andrew Haisting
123d227c13 Add closing paren (#245) 2024-10-17 15:24:46 -05:00
Andrew Haisting
88b96812de BITAU-82 Show shared codes on the item listing screen (#241) 2024-10-17 15:24:21 -05:00
Opeyemi
083578ec2b [BRE-372] - Clean up document start (#4111) 2024-10-17 18:39:12 +00:00
Patrick Honkonen
f73ce842fc [PM-13315] Prevent account switching during FIDO 2 unlock (#4054) 2024-10-17 18:20:49 +00:00
Dave Severns
56ad1ef05b PM-13464 and PM-13627 support (#4107) 2024-10-17 17:30:13 +00:00
Andrew Haisting
8abe62e53e Remove Firebase APK distribution (#244) 2024-10-17 11:51:57 -05:00
Patrick Honkonen
5faa30e2f2 [PM-13396] Show error when logging into an unofficial Bitwarden server (#4088) 2024-10-17 15:11:13 +00:00
David Perez
a9b6f296d8 Allow CrashLogsManager to handle generic Throwables (#4106) 2024-10-17 13:55:41 +00:00
David Perez
655beb9dd6 PM-13688: Remove race condition from AuthTokenInterceptor (#4108) 2024-10-16 22:01:05 +00:00
David Perez
0d6a8513b2 Update Turbine to 1.2.0 (#4104) 2024-10-16 18:17:04 +00:00
Dave Severns
ab9d57b4f2 PM-11182 PM-11183 PM-11184 Add the instruction steps to logins import flow (#4089) 2024-10-16 18:15:13 +00:00
Dave Severns
c382227b6a PM-13648 Nav to new create account when email verification is on (#4092) 2024-10-16 17:51:23 +00:00
David Perez
cf3624264e PM-13726: Process cipher notifications without organizationIds or collectionIds (#4102) 2024-10-16 16:43:46 +00:00
Dave Severns
62cfd5e746 PM-13382 show contextual message for the level of Biometrics available (#4099) 2024-10-16 16:10:37 +00:00
Andrew Haisting
1446e43c46 BITAU-105 Add support for deep link to account security (#4063) 2024-10-16 14:45:10 +00:00
David Perez
43dc2f8116 Update PendingRequestsScreen image size (#4098) 2024-10-15 21:33:45 +00:00
David Perez
8eb408b140 Pin the segmented control to toolbar in AddSendScreen (#4093) 2024-10-15 21:13:29 +00:00
Andrew Haisting
d07a9dcf81 BITAU-90 Add "Sync with Bitwarden App" row to settings (#239) 2024-10-15 15:38:53 -05:00
Andrew Haisting
1820073b65 BITAU-68 Specify correct authenticatorbridge connection type (#240)
Co-authored-by: Patrick Honkonen <1883101+SaintPatrck@users.noreply.github.com>
2024-10-15 15:32:50 -05:00
Andrew Haisting
1669fa4044 Only run debug test variant on CI (#242) 2024-10-15 15:31:31 -05:00
Dave Severns
970a1e14cd PM-13609 Navigate to new import flow from Vault settings when feature is enabled. (#4090) 2024-10-15 20:12:29 +00:00
David Perez
736912bd6c Remove launch icon and update BitwardenActionCard (#4097) 2024-10-15 19:41:19 +00:00
renovate[bot]
d3c1f8e26a [deps]: Update gh minor (#234) 2024-10-15 15:17:03 -04:00
renovate[bot]
a78f81014e [deps]: Lock file maintenance (#236) 2024-10-15 15:13:52 -04:00
David Perez
ec47cb9ee2 AGP update v8.7.1 (#4095) 2024-10-15 17:52:52 +00:00
renovate[bot]
690de93e63 [deps]: Update gh minor (#4084)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-15 15:24:00 +00:00
renovate[bot]
9adb106a12 [deps]: Update kotlin (#4083)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-15 15:23:43 +00:00
David Perez
499ab2d2d0 PM-12296: Only match port when present on both uris (#4091) 2024-10-15 13:56:11 +00:00
Víctor
12afbea83e [PM-13387] Skip unneeded confirmation button when using passive biometrics such as face unlock (#4064) 2024-10-15 13:52:15 +00:00
David Perez
efbf84238d PM-11176: Update generator to use segmented control (#4075) 2024-10-14 20:43:17 +00:00
Andrew Haisting
2b87cdac9e BITAU-176 Filter out deleted ciphers from syncAccounts call (#4078) 2024-10-14 20:19:07 +00:00
David Perez
8eab74d458 PM-13635, PM-13636, PM-13637: Update icons (#4087) 2024-10-14 18:23:03 +00:00
github-actions[bot]
4c74f720eb Autosync Crowdin Translations (#233) 2024-10-14 17:28:29 +00:00
Andrew Haisting
03251abe88 Update authenticatorbridge .aar after removing lastSyncTime (#237) 2024-10-14 11:56:46 -05:00
Andrew Haisting
b465cc5078 BITAU-175 Remove lastSyncTime property from SharedAccountData (#4077) 2024-10-14 16:56:18 +00:00
aj-rosado
9b5c88e990 [PM-11982] On Passwordless flow switch activeAccount to match PasswordlessRequest userId (#4066) 2024-10-14 15:31:20 +00:00
Dave Severns
4756040c4a PM-13471 Remove instances deprecated ClickableText (#4076) 2024-10-14 14:26:11 +00:00
Dave Severns
bde47d7919 PM-11179 PM-11180 PM-11181 Add import logins screen and dialogs. (#4067) 2024-10-11 19:09:57 +00:00
David Perez
86db9bd3fa PM-12668: Update TopAppBars accross the app (#4074) 2024-10-11 19:05:24 +00:00
github-actions[bot]
cd9f4e8723 Autosync Crowdin Translations (#4070)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
Co-authored-by: Patrick Honkonen <1883101+SaintPatrck@users.noreply.github.com>
2024-10-11 16:32:29 +00:00
renovate[bot]
879c2b9107 [deps]: Lock file maintenance (#4072)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-11 16:14:43 +00:00
David Perez
cdb03f5649 Add enum for better control of TopAppBar divider (#4073) 2024-10-11 15:59:58 +00:00
Dave Severns
ba8e3a6c51 PM-11174 Action card for import logins flow (#4057) 2024-10-11 14:49:34 +00:00
David Perez
028242c4be Update the search top app bar divider thickness (#4069) 2024-10-11 13:57:20 +00:00
David Perez
3296477932 Fix dark mode toggle color (#4068) 2024-10-11 13:57:02 +00:00
David Perez
c3af26d83f PM-13286: Update segmented control to match the TopAppBar (#4058) 2024-10-10 21:14:13 +00:00
Andrew Haisting
43fb630393 BITAU-76 Show download Bitwarden action card (#229) 2024-10-10 15:22:54 -05:00
David Perez
3e9e45ba2f Simplify text field color and textstyles (#4065) 2024-10-10 20:06:10 +00:00
David Perez
22c0745993 PM-12668: Update TopAppBar divider (#4060) 2024-10-10 20:05:53 +00:00
Andrew Haisting
54e59cc61b Return noop bridge manager when password sync feature flag is off (#232)
Co-authored-by: Brian Yencho <brian@livefront.com>
2024-10-10 10:40:46 -05:00
David Perez
537281f6c3 PM-13301: Fix 2fa with key connector bug (#4059) 2024-10-09 21:16:20 +00:00
David Perez
79d2a00bf8 Add logic to identify root cause of flakey test (#4056) 2024-10-09 18:03:21 +00:00
aj-rosado
57d79cd51c [PM-12408] Updating password revision date on password change (#4044) 2024-10-09 17:09:03 +00:00
David Perez
57082ff7c1 Update Mockk to 1.13.13 (#4055) 2024-10-09 15:42:12 +00:00
Andrew Haisting
d6ae7da44c Fix empty state for totp codes (#231) 2024-10-09 09:08:41 -05:00
renovate[bot]
280aa35b73 [deps]: Update gradle minor (#222) 2024-10-09 10:01:06 -04:00
David Perez
8a30f14dea Apply formatter to entire app (#4053) 2024-10-08 21:42:09 +00:00
Andrew Haisting
f3bce23942 Use correct feature for syncing with Bitwarden (#230) 2024-10-08 15:08:35 -05:00
David Perez
2af96988ab PM-13021: Update empty state for TOTP flow (#4051) 2024-10-08 19:20:05 +00:00
David Perez
ccb52ae6c5 Add shapes to the BitwardenTheme (#4052) 2024-10-08 18:35:59 +00:00
André Bispo
cda4e47414 [PM-12695] Add hidden field changes to password history (#4047) 2024-10-08 18:29:50 +00:00
Dave Severns
5e7dc26837 PM-13300 Adjust size and padding modifier order where needed. (#4050) 2024-10-08 18:18:44 +00:00
Dave Severns
b5658fda42 PM-11177 Update the empty state on the sends screen to v3 design (#4045) 2024-10-08 18:18:27 +00:00
Andrew Haisting
1015654d27 BITAU-70 Implement symmetric key storage (#226) 2024-10-08 13:01:55 -05:00
David Perez
1539c2032e Add a bitwarden styles snackbar (#4049) 2024-10-08 17:41:40 +00:00
David Perez
94791b4256 Rename BitwardenPolicyWarning to BitwardenInfoCalloutCard (#4048) 2024-10-08 16:49:16 +00:00
Dave Severns
49d9a46917 PM-11175 update to new empty vault screen (#4046) 2024-10-08 16:00:40 +00:00
David Perez
e7450171cd This PR adds the TOTP matching flow to the app (#4042) 2024-10-08 15:10:18 +00:00
Dave Severns
641a48fe44 PM-13068 Navigate from settings to setup autofill screen. (#4034) 2024-10-08 14:29:40 +00:00
Dave Severns
bc057932a0 PM-12667 Final change, update the image files (#4043) 2024-10-08 13:58:07 +00:00
Patrick Honkonen
d8c80f7e28 [BWA-10] Handle exception when checking for suspicious intents (#228) 2024-10-08 08:20:44 -05:00
Patrick Honkonen
3aaa93675d Update Android Gradle plugin and Gradle wrapper (#225) 2024-10-08 08:18:29 -05:00
Andrew Haisting
af0f894dd3 BITAU-83 Refactor AuthenticatorRepository to accomodate shared codes (#220)
Co-authored-by: Patrick Honkonen <1883101+SaintPatrck@users.noreply.github.com>
2024-10-07 19:47:05 -05:00
Dave Severns
0cb8e369ae PM-12667 Update the names of the the existing icon assets to match with design language (#4040) 2024-10-07 22:38:55 +00:00
Dave Severns
3d4c901039 PM-12667 Update the icons to match V3 designs (#4041) 2024-10-07 21:41:08 +00:00
David Perez
e62dc5dd21 Remove last references to MaterialTheme (#4038) 2024-10-07 17:58:00 +00:00
Andrew Haisting
f8592f4e17 Fix unused test (#4039) 2024-10-07 17:54:09 +00:00
David Perez
c4467f0cba PM-13019: Add special circumstance to navigate to the vault listing UI for TOTP code (#4033) 2024-10-07 15:04:58 +00:00
renovate[bot]
6e7f5a31f1 [deps]: Update androidx.compose:compose-bom to v2024.09.03 (#221) 2024-10-07 09:37:47 -04:00
github-actions[bot]
79b7866e30 Autosync Crowdin Translations (#219) 2024-10-07 13:35:38 +00:00
renovate[bot]
d8da7a8cc2 [deps]: Update gh minor (#223) 2024-10-07 09:32:09 -04:00
renovate[bot]
e36e9e878f [deps]: Lock file maintenance (#224) 2024-10-07 13:27:22 +00:00
Andrew Haisting
8d578a9b57 Remove unused .aar (#4036) 2024-10-07 12:57:57 +00:00
Patrick Honkonen
73a802a483 [PM-13101] Validate FIDO2 privileged apps against community allow list (#4022) 2024-10-07 12:57:07 +00:00
Patrick Honkonen
60fce08c7e Trigger scan and test workflows on merge queue events (#4037) 2024-10-07 12:52:41 +00:00
Dave Severns
8ae6433906 PM-13067 Navigate to setup unlock screen from action card in security settings (#4023) 2024-10-04 14:29:47 -04:00
Dave Severns
83652c9699 PM-12773 show autofill card when user skipped this step in onboarding (#4021) 2024-10-04 14:21:40 -04:00
David Perez
a5cf4f49d7 Add logic for parting a TOTP code from a Uri or Intent (#4032) 2024-10-04 12:41:07 -05:00
David Perez
78d14547e4 Clean up special circumstances (#4031) 2024-10-04 11:23:17 -05:00
David Perez
29f00421bb Update to Junit 5.11.2 (#4028) 2024-10-04 10:54:42 -05:00
David Perez
8501db0eb2 Update compose bom to 2024.09.03 (#4030) 2024-10-04 10:54:27 -05:00
David Perez
c1e9759dae Update credential library (1.3.0) (#4029) 2024-10-04 10:54:16 -05:00
github-actions[bot]
8f24597bad Autosync Crowdin Translations (#4024) 2024-10-04 15:53:05 +00:00
Dave Severns
954a9acf92 PM-12764 update image assets (#3982) 2024-10-04 10:05:56 -04:00
David Perez
3dfe6adc05 PM-12322: Update color scheme (#3986) 2024-10-04 08:47:28 -05:00
mpbw2
1d84479cf3 [PM-9363] Disable cipher key encryption for older server versions (#4006) 2024-10-03 17:42:23 -04:00
Dave Severns
c8dcafe737 PM-10632 update the copy on setup complete (#4020) 2024-10-03 17:37:43 -04:00
Andrew Haisting
567c2ffb94 BITAU-99 Expose and protect AuthenticatorBridgeService (#3988) 2024-10-03 15:02:58 -05:00
Patrick Honkonen
488ec095bc [PM-13073] Handle Fido2 credential errors on vault unlock screen (#4010) 2024-10-03 15:40:03 -04:00
Andrew Haisting
32f2bfb29f BITAU-69 Check for OS version in AuthenticatorBridgeManager (#4019) 2024-10-03 14:06:15 -05:00
Andrew Haisting
93423d4b13 BITAU-68 Specify build specific bridge permission in manifest (#218) 2024-10-03 13:45:27 -05:00
Lucas
20383f06a8 [PM-13011] Allow relevant browsers in the privacy/security/FOSS space to use auto-fill and passkeys (#4005) 2024-10-03 14:44:22 -04:00
Dave Severns
fd6b276cc8 PM-12683 SSO user needed password set bug (#4018) 2024-10-03 12:25:58 -04:00
Patrick Honkonen
e6eb626d85 [PM-13070] Add userId to Fido2 GetCredentials and CredentialAssertion requests (#4003) 2024-10-03 11:14:03 -04:00
Dave Severns
569ffc3583 PM-12760 Add way to re-show the onboarding carousel via debug menu (#3999) 2024-10-03 09:58:37 -04:00
aj-rosado
e2e5042be5 [PM-12739] adjusted generator length to not be lower than minimum length (#4016) 2024-10-03 10:30:54 +02:00
Patrick Honkonen
ee165491c9 [BWA-90] Remove WorkManager for clipboard clearing (#216) 2024-10-02 14:57:22 -04:00
Patrick Honkonen
8ad9bc5eed [BWA-91] Add OmitFromCoverage annotation (#217) 2024-10-02 14:43:07 -04:00
David Perez
0c83a1099f PM-10628: Update pin dialog title (#4017) 2024-10-02 12:57:34 -05:00
David Perez
36a5fee048 Update the Firebase BOM to 33.4.0 (#4015) 2024-10-02 12:57:17 -05:00
Patrick Honkonen
01ab047d9c [PM-13074] Explicitly sync FIDO2 credentials (#4012) 2024-10-02 13:50:18 -04:00
renovate[bot]
e2e49a4555 [deps]: Update kotlin (#193) 2024-10-02 10:22:58 -04:00
David Perez
4fd81ed3b8 PM-10628: Update Pin Input Dialog UI (#4013) 2024-10-02 08:59:26 -05:00
Patrick Honkonen
a92fd5b35d [deps]: Update androidxLifecycle to 2.8.6 (#213) 2024-10-02 15:49:39 +02:00
Patrick Honkonen
5e5b29677a [deps]: Update compose to 2024.09.02 (#212) 2024-10-02 15:49:22 +02:00
Dave Severns
8e092ef860 PM-12772 Add notification action card to security settings when applicable (#4008) 2024-10-02 08:27:45 -04:00
Andrew Haisting
9e4119fe32 BITAU-97 Add AuthenticatorBridgeManager (#3987) 2024-10-01 21:27:12 +00:00
David Perez
757baf0290 Clean up text field typography (#4011) 2024-10-01 16:18:55 -05:00
Andrew Haisting
9f4a85d373 remove unused getAuthCodeFlow() (#215) 2024-10-01 15:33:21 -05:00
David Perez
53b1bec42b Update the Android Gradle Plugin and the Gradle Wrapper (#4009) 2024-10-01 13:57:12 -05:00
David Perez
e63c4806f1 Migrate all references of MaterialTheme Typography to BitwardenTheme (#4007) 2024-10-01 13:11:57 -05:00
David Perez
2224708fb1 Add singular BitwardenTypography to manage all text-styles (#4002) 2024-10-01 09:20:26 -05:00
aj-rosado
b3e885bcb1 [PM-12279] Update SDK reference and use Origin.Android on Fido2Credential (#3975) 2024-10-01 15:07:30 +02:00
David Perez
10bbab971f PM-12322: Add bitwarden color scheme to BitwardenTheme (#4000) 2024-09-30 16:47:08 -05:00
vphan916
b0edb7cf3b Added locators for the settings page and the Add Code button (#203) 2024-09-30 13:45:27 -07:00
Andrew Haisting
0d5bbc177c BITAU-67 Add custom authenticator bridge permission to manifest (#211) 2024-09-30 14:40:02 -05:00
github-actions[bot]
f7c14890f1 Autosync Crowdin Translations (#202) 2024-09-30 19:39:15 +00:00
renovate[bot]
924ff87979 [deps]: Update gradle minor (#206) 2024-09-30 19:36:01 +00:00
renovate[bot]
713bb51974 [deps]: Update org.testng:testng to v7 (#208) 2024-09-30 15:35:28 -04:00
renovate[bot]
6faf720076 [deps]: Update gh minor (#207) 2024-09-30 15:34:51 -04:00
David Perez
8ec743736a Update to Junit 5.11.1 (#3998) 2024-09-30 13:51:04 -05:00
renovate[bot]
a13a7c363f [deps]: Update ubuntu to v24 (#209) 2024-09-30 17:58:29 +00:00
renovate[bot]
9d6192ba1f [deps]: Lock file maintenance (#210) 2024-09-30 17:57:45 +00:00
David Perez
2f05355487 PM-12322: New color scheme (#3995) 2024-09-30 12:56:32 -05:00
David Perez
b7c48c2e26 Update account item font and remove unused fonts (#3997) 2024-09-30 12:56:06 -05:00
renovate[bot]
1e9583b3be [deps]: Update org.jetbrains.kotlinx:kotlinx-serialization-json to v1.7.3 (#3990) 2024-09-30 13:49:35 -04:00
Patrick Honkonen
75819cce3c [PM-12322] Remove branch restriction for distributing to Firebase (#3996) 2024-09-30 14:42:12 -03:00
aj-rosado
d60c534e06 [PM-12739] Updated generator maximum number and specials (#3994) 2024-09-30 19:33:27 +02:00
github-actions[bot]
ad338a8fd6 Autosync Crowdin Translations (#3978) 2024-09-30 17:00:23 +00:00
renovate[bot]
290377af74 [deps]: Update ubuntu to v24 (#3992) 2024-09-30 12:51:05 -04:00
renovate[bot]
24195ddb90 [deps]: Lock file maintenance (#3993)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-30 11:23:07 -05:00
Oscar Hinton
73c5571d6b Fix linking url (#3979) 2024-09-30 17:26:51 +02:00
renovate[bot]
5beec9d687 [deps]: Update gh minor (#3991)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-30 10:52:17 -04:00
André Bispo
9d19a73fd6 [PM-9755] Change error message from a toast to a dialog (#3963) 2024-09-30 08:20:45 +01:00
Dave Severns
72cb9918ac PM-10616 update copy to match design (#3985) 2024-09-27 15:58:44 -04:00
David Perez
aa6762dc22 Add BitwardenOutlinedErrorButton and rename BitwardenErrorButton (#3984) 2024-09-27 11:42:12 -05:00
David Perez
b696964cb7 Add a reusable Navigation Bar Item (#3983) 2024-09-27 11:41:57 -05:00
Dave Severns
853f25bf57 [PM-12595] add notification badge to settings item in settings tab screen (#3976) 2024-09-27 11:37:30 -04:00
Dave Severns
70e75b910c [PM-12711] Auto-Fill selection bug fix (#3981) 2024-09-27 11:31:34 -04:00
David Perez
aaa541dd19 Simplify and clean up segmented button (#3977) 2024-09-26 16:11:44 -05:00
David Perez
80c1c26f5c Add reusable slider component (#3974) 2024-09-26 16:00:23 -05:00
Dave Severns
f349a72f72 [PM-12592] & [PM-12593] bottom nav notification dot (#3968) 2024-09-26 13:04:40 -04:00
David Perez
21e1d8b5bc Add reusable radio button (#3973) 2024-09-26 10:59:17 -05:00
David Perez
9213b4843f Disable stepper buttons when they reach the end of range (#3972) 2024-09-26 10:39:46 -05:00
Patrick Honkonen
ddeece0a5c [BWA-79] Sanitize manual entry code before validation (#200) 2024-09-26 10:22:10 -04:00
David Perez
dad501d37e Remove unused span styles (#3970) 2024-09-26 08:57:37 -05:00
Oscar Hinton
61b09fe8f1 [PM-7587] Support conditionally loading local sdk (#3957) 2024-09-26 10:21:22 +02:00
David Perez
415aafb5e9 Add a reusable bitwarden loading indicator (#3971) 2024-09-25 19:53:24 -05:00
David Perez
251d13a832 Add reusable icon button components (#3969) 2024-09-25 17:37:38 -05:00
Dave Severns
40dd0e9776 PM-12594 Add observable flows to observe badge count changes when corresponding settings update (#3964) 2024-09-25 15:37:58 -04:00
David Perez
ad154b6c91 Add Bitwarden Horizontal Divider (#3967) 2024-09-25 14:27:24 -05:00
Andrew Haisting
3445191a05 BITAU-66 Use fixed keystore for signing debug build (#201) 2024-09-25 14:17:36 -05:00
David Perez
caa0c613a5 PM-12631: Handle password re-prompt for accessibility autofill (#3965) 2024-09-25 13:16:22 -05:00
Andrew Haisting
6908111377 BITAU-173 Return null symmetric key when no users have enabled Authen… (#3961) 2024-09-25 10:01:07 -05:00
Dave Severns
0f009943b5 [PM-12604] Fix showing the biometric prompt when not needed adding account (#3962) 2024-09-25 10:49:48 -04:00
github-actions[bot]
2d75679586 Autosync Crowdin Translations (#197) 2024-09-25 12:48:38 +00:00
Álison Fernandes
d676a6c76c [BWA-77] Setup codeowners (#198) 2024-09-25 08:45:06 -04:00
Andrew Haisting
4f34f6da21 BITAU-172 Rename Authenticator Bridge SDK (#3959) 2024-09-24 22:09:27 +00:00
David Perez
3d0dd2996e Replace usages of raw button with BitwardenFilledTonalButton (#3960) 2024-09-24 16:15:24 -05:00
Dave Severns
774b828cb0 PM-11535 Only add password to 2 factor login path if present (#3958) 2024-09-24 12:11:44 -04:00
David Perez
071a5330e6 Create new reusable FAB component (#3956) 2024-09-24 10:04:23 -05:00
aj-rosado
86bbf13175 [PM-10671] update password generator policy (#3936) 2024-09-24 17:00:30 +02:00
Andrew Haisting
87e223bc59 BITAU-104 Implement BridgeService (#3954) 2024-09-24 09:16:59 -05:00
David Perez
190f92ec67 Update switch to represent disabled state (#3955) 2024-09-23 15:30:54 -05:00
Álison Fernandes
ee7d00247e [PM-9328] Codeowners setup (#3926) 2024-09-23 12:43:55 -04:00
Dave Severns
f26374aae7 [PM-10118] update selected generator type when returning to main tab. (#3942) 2024-09-20 15:53:45 -04:00
David Perez
f68b4df9f9 PM-9901: Use sensitive text font for passwords (#3952) 2024-09-20 14:52:57 -05:00
Dave Severns
05d6c2f61e [PM-10622] Handle the skip unlock step in the onboarding, storing when the user selects to do so. (#3928) 2024-09-20 15:25:01 -04:00
renovate[bot]
8fe637d207 [deps]: Lock file maintenance (#3917)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-20 13:09:24 -05:00
renovate[bot]
ad8702a34f [deps]: Update gh minor (#3916)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-20 13:09:13 -05:00
David Perez
bcdbea13bf Password encoding and decoding handing in TwoFactorLoginNavigation (#3951) 2024-09-20 12:04:57 -05:00
github-actions[bot]
37b5dc7de3 Autosync Crowdin Translations (#3948) 2024-09-20 12:48:26 -04:00
Dave Severns
39cc24c13a PM-12321 Update typography for V3 design (#3946) 2024-09-20 11:34:30 -04:00
David Perez
d0c2bb5b7e PM-12397: Clear accessibility action when on launcher or Bitwarden App (#3947) 2024-09-20 09:44:30 -05:00
Dave Severns
5667a1cfd0 PM-10631 store when the user selects to turn auto fill on later (#3925) 2024-09-20 09:39:27 -04:00
André Bispo
3238279290 [PM-9755] Update duo AuthUrl error message to match other clients (#3945) 2024-09-20 14:21:53 +01:00
Dave Severns
73e158afd0 PM-10843 autofill setup screen animated image. (#3932) 2024-09-19 17:30:01 -04:00
Dave Severns
21b41fd4db PM-10617 + PM-11270 fixes after QA review (#3944) 2024-09-19 17:26:54 -04:00
renovate[bot]
26eeb39f88 [deps]: Update gradle minor (#192) 2024-09-19 16:35:00 -04:00
David Perez
7fd16c9e10 Add FLAG_ACTIVITY_NEW_TASK flag for autofill tile to avoid crash (#3943) 2024-09-19 14:46:20 -05:00
David Perez
cb1e4f6b39 Update Androidx libraries (#3939) 2024-09-19 12:45:07 -05:00
Dave Severns
71d3ae9ee8 [PM-12319] Skip Auto-fill setup if already enabled. (#3934) 2024-09-19 13:36:11 -04:00
Patrick Honkonen
49c2e3030c [PM-12166] Update detekt (#196) 2024-09-19 18:06:34 +01:00
renovate[bot]
ea267a0298 [deps]: Lock file maintenance (#195) 2024-09-19 12:47:26 -04:00
renovate[bot]
6e0063c977 [deps]: Update gh minor (#194) 2024-09-19 12:47:00 -04:00
David Perez
c8b1b71960 Update APG to 8.6.1 (#3938) 2024-09-19 09:02:59 -05:00
Álison Fernandes
384be79838 Updated version name according to our pattern (#3940) 2024-09-19 09:15:15 -04:00
Andrew Haisting
cdf8b49d61 BITAU-108 Add unlockWithAuthenticatorSyncKey to VaultRepository (#3909) 2024-09-18 21:41:57 +00:00
David Perez
84f92f1b13 PM-12014: Enable accessibility autofill outside of debug builds (#3919) 2024-09-18 16:00:36 -05:00
David Perez
2068948035 PM-11486: Parse the Accessibility Nodes for username and password fields (#3935) 2024-09-18 15:35:15 -05:00
Andrew Haisting
f89b053d2e BITAU-103 Implement symmetric key creation and storage (#3905) 2024-09-18 13:47:10 -05:00
David Perez
4b53358c67 Bump version name to 2024.09.00 (#3937) 2024-09-18 11:19:23 -05:00
Patrick Honkonen
1f89314bbb [BWA-65] Sort items alphabetically with special char precedence (#190) 2024-09-18 13:10:16 -03:00
David Perez
2721f7293c PM-12297: Add accessibility service alert for autofill tile (#3931) 2024-09-18 10:08:04 -05:00
github-actions[bot]
afd7097b53 Autosync Crowdin Translations (#186) 2024-09-18 15:00:57 +00:00
David Perez
1c2ccd5305 Add logic to ensure url has a valid https protocol (#3933) 2024-09-18 09:52:28 -05:00
Patrick Honkonen
4f55d622cb [PM-11884] Perform origin validation during FIDO 2 auth (#3896) 2024-09-18 10:41:52 -04:00
Andrew Haisting
087cd5a093 BITAU-158 Add PasswordManagerSync local feature flag (#189) 2024-09-18 09:12:13 -05:00
David Perez
74ae39a665 Update Firebase BOM to v33.3.0 (#3930) 2024-09-18 08:56:01 -05:00
Dave Severns
37f1da1ec2 PM-12076 remaining state based navigation linkup for onboarding (#3923) 2024-09-17 13:51:06 -04:00
David Perez
503c966177 Create reusable isAccessibilityServiceEnabled extension (#3929) 2024-09-17 11:53:37 -05:00
Dave Severns
76cc9c8579 [PM-12289] add onboarding status override to debug menu (#3927) 2024-09-17 11:52:29 -04:00
renovate[bot]
ed0494e159 [deps]: Update kotlin to v1.9.0 (#3849)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-17 09:53:42 -05:00
github-actions[bot]
fd8eda75b5 Autosync Crowdin Translations (#3914)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2024-09-17 09:29:06 -05:00
David Perez
765a9ebd74 PM-11485: Add routing logic to handle searching during accessibility autofill (#3924) 2024-09-17 09:04:00 -05:00
Dave Severns
39df103f12 [PM-10632] Setup complete screen for new onboarding (#3921) 2024-09-17 09:23:24 -04:00
David Perez
135a48b3c0 PM-12240: Remove unused permissions from the sync response (#3920) 2024-09-16 15:20:44 -05:00
David Perez
368ca49fd6 Add BitwardenLegacyAppComponents for legacy app component names (#3922) 2024-09-16 15:00:00 -05:00
Dave Severns
759e926588 PM-11464 Add onboarding status to user Account to allow for root navigation to onboarding flow. (#3878) 2024-09-16 12:40:56 -04:00
David Perez
3ecf1382b2 PM-11488: Add a switch to the autofill settings UI for enabling the accessibility service (#3911) 2024-09-16 09:14:00 -05:00
Dave Severns
190ba792a1 [PM-10905] Update JSON model to match API (#3913) 2024-09-13 13:22:21 -04:00
Andrew Haisting
d1f21d3585 BITAU-98 Add EncryptionUtils helper functions to the bridge SDK (#3888) 2024-09-12 15:02:01 -05:00
David Perez
4c1d55e9fe PM-11487: Initial accessibility service and processor for handling autofill (#3906) 2024-09-12 12:17:25 -05:00
Dave Severns
f544ccc3ef [PM-11741] shortcut navigation pt2 electric boogaloo (#3904) 2024-09-12 13:02:01 -04:00
David Perez
537c501b9b Update compose BOM to 2024.09.01 (#3907) 2024-09-11 15:31:25 -05:00
David Perez
2d3a47f3d1 Update Androidx libraries (#3908) 2024-09-11 15:31:11 -05:00
David Perez
6521848a8d PM-11485: Add routing for accessibility autofill (#3895) 2024-09-11 11:53:30 -05:00
David Perez
fe1f897d64 Update to detekt 1.23.7 (#3901) 2024-09-11 11:41:35 -05:00
Andrew Haisting
a5726fb72b BITAU-160 Update feature flag name for authenticator sync (#3903) 2024-09-11 09:12:35 -05:00
Dave Severns
8f30742908 PM-10845 add landscape layout for setup auto-fill (#3897) 2024-09-11 07:53:05 -04:00
David Perez
98bcff5e06 Add PreviewScreenSizes annotation to ignored list of annotations for tests (#3899) 2024-09-10 16:07:32 -05:00
Andrew Haisting
19596ea4c3 BITAU-102 Return null BridgeService when API level is below 12 (#3887) 2024-09-10 15:10:05 -05:00
Dave Severns
8dce8cd576 PM-10630 setup autofill UI and interactions set up (#3891) 2024-09-10 14:10:23 -04:00
Andrew Haisting
b94a1adda9 Use an aar to define bridge dependency (#3892) 2024-09-10 16:33:49 +00:00
David Perez
8489693d84 Update KSP to 2.0.20-1.0.25 (#3894) 2024-09-10 11:10:31 -05:00
Andrew Haisting
647b3e921b BITAU-168 Add Bridge SDK test dependencies (#3890) 2024-09-10 10:11:50 -05:00
aj-rosado
4e69ed57e8 [PM-10930] Fix password generator policies (#3853) 2024-09-10 16:31:58 +02:00
David Perez
95240a7ce3 Update to AGP 8.6.0 (#3889) 2024-09-10 09:22:24 -05:00
Andrew Haisting
19facaf8fd BITAU-164 add no-op version of BridgeService (#3884) 2024-09-09 15:36:34 -05:00
David Perez
bef05d5ed9 Simplify adding flags to debug menu (#3886) 2024-09-09 14:51:04 -05:00
David Perez
fa93985a2e Update Slider UI after Compose BOM update (#3885) 2024-09-09 14:50:48 -05:00
Andrew Haisting
b7544ef7f4 BITAU-96 Setup AIDL interface and files (#3880) 2024-09-09 10:43:33 -05:00
Dave Severns
fa2d7e0218 PM-11741 add password modal to root nav for generator shortcut specia… (#3883) 2024-09-09 11:42:19 -04:00
Andrew Haisting
c817253760 BITAU-108 Store Authenticator Sync Key (#3873) 2024-09-09 10:09:10 -05:00
github-actions[bot]
eb4e2ab31f Autosync Crowdin Translations (#3875) 2024-09-09 14:18:01 +00:00
David Perez
705153ea21 Add missing SerialName annotations (#3879) 2024-09-06 17:24:11 -05:00
Andrew Haisting
47fe78536f BITAU-165 add kotlinx serialization dependency to bridge (#3877) 2024-09-06 15:28:29 -05:00
David Perez
3f78ad6d6d Update the compose BOM to 2024.09.00 (#3874) 2024-09-06 12:45:12 -05:00
Dave Severns
e468ec695b PM-11604 Network layer for checking email token, nav to UI if needed. (#3862) 2024-09-06 13:40:00 -04:00
Dave Severns
ae349183e8 PM-11714 record if a user has signed in on device before. (#3876)
Co-authored-by: Patrick Honkonen <1883101+SaintPatrck@users.noreply.github.com>
2024-09-06 13:18:35 -04:00
renovate[bot]
e039d5c3fb [deps]: Update gh minor (#3851)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-05 13:14:47 -05:00
Andrew Haisting
b1ecf125d1 BITAU-107 Add Feature Flag and UI for Authenticator Syncing (#3847) 2024-09-05 13:13:48 -05:00
David Perez
69ca7649e2 Update the Gemfile.lock (#3872) 2024-09-05 13:13:40 -05:00
David Perez
22958aa5ed Update KotlinX Serialization to v1.7.2 (#3871) 2024-09-05 13:13:23 -05:00
David Perez
7ebbe700f0 Update immutable collection to v0.3.8 (#3870) 2024-09-05 12:33:55 -05:00
Andrew Haisting
de48bb37d7 BITAU-96 Setup Bridge SDK (#3857) 2024-09-05 12:22:49 -05:00
David Perez
1dd19a8b2d Update to latest Kotlin v2.0.20 (#3869) 2024-09-05 11:59:08 -05:00
David Perez
733053b548 PM-11484: Add logic to parse URI from AccessibilityNodeInfo (#3864) 2024-09-05 11:20:11 -05:00
David Perez
f10a2b15ba Remove unsued shouldFinishOnComplete property (#3865) 2024-09-04 17:50:31 -05:00
David Perez
c02afb6714 PM-11643: Add LauncherPackageNameManager for tracking launcher apps (#3861) 2024-09-04 14:12:09 -05:00
Dave Severns
b672418c45 PM-11479 Expired link UI (#3854) 2024-09-04 13:07:47 -04:00
David Perez
c017c1b10c PM-11642: Security stamp soft logout (#3859) 2024-09-04 11:54:31 -05:00
David Perez
e3a4a7b153 Relocate the accessibility package into the autofill package (#3860) 2024-09-04 11:30:43 -05:00
David Perez
36f13e44a3 PM-11616: Manage totp logic in AutofillTotpManager (#3856) 2024-09-03 15:54:37 -05:00
Mathias Mader
2597c44117 [PM-11398] [PM-10872] - Fix: Search fields not showing text correctly (#3840) 2024-09-03 14:37:30 -04:00
github-actions[bot]
ae685c73d2 Autosync Crowdin Translations (#3845) 2024-09-03 18:22:58 +00:00
Dave Severns
2b5337c4ff PM-11214 change navoptions to support single top without retaining VM (#3843) 2024-09-03 14:14:13 -04:00
renovate[bot]
06d742bd16 [deps]: Update gradle minor (#183) 2024-09-03 14:13:38 -04:00
renovate[bot]
05bcaf9dbc [deps]: Lock file maintenance (#184) 2024-09-03 13:13:05 +00:00
renovate[bot]
d37fa652bb [deps]: Update org.jetbrains.kotlinx:kotlinx-serialization-json to v1.7.2 (#181) 2024-09-03 13:12:48 +00:00
renovate[bot]
170e74db55 [deps]: Update gh minor (#182) 2024-09-03 13:11:12 +00:00
github-actions[bot]
b75133516d Autosync Crowdin Translations (#180) 2024-09-03 13:09:49 +00:00
Patrick Honkonen
e90c41a3b7 [BWA-61] Fix pre-existing detekt issues (#179) 2024-09-03 09:05:20 -04:00
David Perez
7e5203efa5 PM-11483: Create AutofillTileService (#3844) 2024-08-30 09:50:54 -05:00
Dave Severns
17c579bfc2 PM-11387 on new create account with email verification, attempt login… (#3842) 2024-08-29 14:07:42 -04:00
Dave Severns
3c39d8beac PM-11224 Add menu to update feature flags with overridden values in real time (#3838) 2024-08-29 14:07:21 -04:00
Patrick Honkonen
5758b34dcf [BWA-60] Configure detekt scanning (#178) 2024-08-29 13:50:17 -04:00
Patrick Honkonen
b49d8a18a2 [BWA-59] Define feature flag manager (#177) 2024-08-29 13:24:27 -04:00
Carlos Gonçalves
2a057bb1fb [PM-10762] Remove Passkey button should be hidden when I have Can View permission (#3829) 2024-08-29 16:40:01 +01:00
Patrick Honkonen
0d77e7085b [BWA-58] Define feature flag repo (#176) 2024-08-29 14:26:24 +00:00
Patrick Honkonen
d0203eedc4 [BWA-57] Define feature flag disk source (#175) 2024-08-29 10:22:14 -04:00
Patrick Honkonen
3c74a342d1 [BWA-56] Add network module (#174) 2024-08-29 09:43:51 -04:00
Patrick Honkonen
f778d7ecd1 [PM-10902] Base64 encode sensitive 2FA nav args (#3841) 2024-08-29 08:45:54 -04:00
Dave Severns
4c983525d3 PM-11310 handle email registration special circumstance after successful login (#3831) 2024-08-28 13:27:58 -04:00
Dave Severns
e32a9f303d PM-11394 String parse issue with app link (#3839) 2024-08-27 17:02:27 -04:00
renovate[bot]
8503610b0b [deps]: Update com.google.firebase:firebase-bom to v33.2.0 (#172) 2024-08-27 15:37:43 -04:00
renovate[bot]
ae1225b948 [deps]: Update kotlin (#171) 2024-08-27 14:54:24 -04:00
David Perez
522e3bb939 PM-11354: TDE unlock since we already have the correct key from the identity service (#3835) 2024-08-27 08:54:51 -05:00
David Perez
0676cf8826 Update internal BitwardenTextButton padding to be consistent with all Bitwarden Buttons (#3834) 2024-08-26 17:10:02 -05:00
David Perez
5173dfd424 Carousel buttons should be full width (#3833) 2024-08-26 17:09:39 -05:00
David Perez
5bc31448b4 Update Firebase BOM to 33.2.0 (#3832) 2024-08-26 14:20:59 -05:00
David Perez
e9a7136a9a PM-10899: Only display the TDE UI if a selection has not yet been made (#3823) 2024-08-26 12:53:35 -05:00
David Perez
c36d0851ca Update the compose BOM (2024.08.00) (#3830) 2024-08-26 12:53:17 -05:00
Wu Nan
ace5f19375 [PM-11307] Fix typo in method name: shouldShouldRequestPermissionRationale (#3821) 2024-08-26 10:58:19 -04:00
A. Bubnov
88b40cfd10 [PM-10685] Support keyboard Done event as CTA Unlock on Pin\Master Password unlock screen (#3691) 2024-08-26 10:57:48 -04:00
David Perez
38e693f92c Simplify manual unlock check (#3824) 2024-08-26 09:07:23 -05:00
mpbw2
9dbb40f33b Add My Vault and Password Generator Quick Settings tiles (#3764) 2024-08-26 09:53:10 -04:00
Dave Severns
76a3265bbb PM-10692 pass a generated password back to the complete registration … (#3806) 2024-08-26 08:56:28 -04:00
David Perez
666c165b6f PM-10899: Fix user not being logged out properly on app restart (#3822) 2024-08-23 13:49:49 -05:00
github-actions[bot]
959361adc2 Autosync Crowdin Translations (#169) 2024-08-23 17:43:56 +00:00
renovate[bot]
f9ccb766c2 [deps]: Lock file maintenance (#173) 2024-08-23 17:42:12 +00:00
renovate[bot]
e5e5d3c67c [deps]: Update github/codeql-action action to v3.26.4 (#170) 2024-08-23 17:41:25 +00:00
Dave Severns
9db09c18cc [PM-11270] hide new UI in complete registration screen behind flag pt. 2 (#3812) 2024-08-23 12:52:21 -04:00
David Perez
b7330392cc PM-11299: Update the userState to properly parse the hasManageResetPasswordPermission flag (#3820) 2024-08-23 11:11:20 -05:00
David Perez
162da64567 Minor formatting an import cleanup (#3819) 2024-08-23 10:49:59 -05:00
github-actions[bot]
09f497ca9b Autosync Crowdin Translations (#3815) 2024-08-23 10:25:44 -04:00
André Bispo
87d7143cc8 [PM-6702] AppLink new redirect path (#3814) 2024-08-23 13:19:19 +00:00
David Perez
23bcfad717 PM-11273: Update the 'useKeyConnector' with 'keyConnectorEnabled' (#3813) 2024-08-22 17:05:46 -05:00
David Perez
f1f16cfee5 PM-11265: Remove the leave organization API (#3811) 2024-08-22 15:17:54 -05:00
Dave Severns
82d3b44712 [PM-11270] Hide all new UI behind onboarding flow flag. (#3810) 2024-08-22 16:06:54 -04:00
David Perez
b56a21b6e5 PM-10917: Fix crash caused when adding an item from a collection (#3809) 2024-08-22 13:48:46 -05:00
David Perez
eb2ba8e598 PM-11264: Ensure user has valid timeout action after migrating to Key Connector (#3807) 2024-08-22 13:48:26 -05:00
David Perez
91f039ecb6 Simplify common login helper methods (#3805) 2024-08-22 11:22:07 -05:00
Dave Severns
0d6aeee870 PM-10617 modify pw strength indicator to show min chars if required. (#3793) 2024-08-22 11:13:23 -04:00
David Perez
a0a5070ac7 PM-11254: Add logic for logging in with Key Connector (#3802) 2024-08-21 16:13:36 -05:00
David Perez
e7bd966e94 PM-11256: Add RootNav logic to display Remove Password Screen (#3803) 2024-08-21 15:53:27 -05:00
Dave Severns
075956ce17 PM-10617 + PM-10637 update complete registration screen to match new onboarding design (#3787) 2024-08-21 15:32:28 -04:00
David Perez
13b256d4e9 PM-11155: Add logic for handling remove password flow (#3801) 2024-08-21 14:30:27 -05:00
David Perez
5761e9510a PM-11248: Add isUsingKeyConnector flag to UserState (#3798) 2024-08-21 14:24:34 -05:00
David Perez
3b3b9ef33b Fix IllegalArgumentException in test (#3799) 2024-08-21 12:33:33 -05:00
David Perez
17fd3ec0f0 PM-11226: Wrap Key Connector APIs (#3794) 2024-08-21 12:26:20 -05:00
David Perez
43a6495b98 PM-11236: Add build type and flavor to the user agent (#3797) 2024-08-21 09:36:45 -05:00
renovate[bot]
ea1813a1b6 [deps]: Lock file maintenance (#166) 2024-08-21 09:30:21 -04:00
renovate[bot]
b1f0a10a55 [deps]: Update sonarsource/sonarcloud-github-action action to v3 (#165) 2024-08-21 09:29:52 -04:00
renovate[bot]
1af16bfbef [deps]: Update github/codeql-action action to v3.26.3 (#164) 2024-08-21 09:29:19 -04:00
Dave Severns
86dabea39f PM-11192 update check email screen to new design (#3788) 2024-08-20 18:17:03 -04:00
David Perez
8d08b5f7c5 PM-11223: Enable remote confg for email verification feature (#3792) 2024-08-20 15:19:23 -05:00
Matt Bishop
13c29c8296 Update public suffix list (#3790) 2024-08-20 14:18:00 -04:00
David Perez
eac5516a94 PM-11154: Create basic Remove Master Password UI (#3782) 2024-08-20 13:15:44 -05:00
renovate[bot]
88b674f54c [deps]: Lock file maintenance (#3786) 2024-08-20 12:27:51 -04:00
renovate[bot]
bcc24a2e25 [deps]: Update sonarsource/sonarcloud-github-action action to v3 (#3785) 2024-08-20 12:25:30 -04:00
renovate[bot]
e14f399e2d [deps]: Update github/codeql-action action to v3.26.3 (#3784) 2024-08-20 12:13:39 -04:00
Martini
524e0941e4 [BWA-53] Fix: Resolve issue with code copying in search results (#163) 2024-08-20 09:17:32 -04:00
André Bispo
ad2c575b39 [PM-9933] Update marketing copy (#3778) 2024-08-20 08:33:53 -04:00
Dave Severns
57c2e7ee4e [Pm 10616] create account start design (#3751) 2024-08-19 17:47:45 -04:00
Patrick Honkonen
55b57a605e [PM-10282] Update build artifact names (#3774) 2024-08-19 16:42:48 -04:00
David Perez
397c78b4af PM-11140: Update hasMasterPassword logic for key connectors (#3775) 2024-08-19 15:13:31 -05:00
David Perez
9e372c29d1 Update to the latest Bitwarden SDK (#3779) 2024-08-19 15:12:30 -05:00
David Perez
82fd7f01f8 PM-10954: Update the key connector APIs to use the correct url and responses (#3781) 2024-08-19 15:12:09 -05:00
Patrick Honkonen
a15b84a5bf [PM-10282] Default to last active account for passkey creation (#3780) 2024-08-19 15:10:31 -04:00
David Perez
5f46423638 Apply formatter to the app (#3777) 2024-08-19 13:43:45 -05:00
renovate[bot]
8aebd36465 [deps]: Update gradle minor (#3771) 2024-08-19 09:40:42 -04:00
renovate[bot]
b4f864d89c [deps]: Update kotlin (#3770) 2024-08-19 09:39:03 -04:00
github-actions[bot]
bcea5a6b25 Autosync Crowdin Translations (#158) 2024-08-19 13:28:34 +00:00
renovate[bot]
b2a256e2fc [deps]: Update gradle minor (#160) 2024-08-19 09:23:40 -04:00
renovate[bot]
83c8db6867 [deps]: Update github/codeql-action action to v3.26.2 (#159) 2024-08-19 09:23:11 -04:00
renovate[bot]
96e2985aed [deps]: Update gradle/actions action to v4 (#161) 2024-08-19 09:22:37 -04:00
renovate[bot]
5e544ff1f9 [deps]: Lock file maintenance (#162) 2024-08-19 09:22:02 -04:00
Patrick Honkonen
8c8db78da6 [PM-10883] Support deserializing Forward Email service type details (#3739) 2024-08-19 09:02:57 -04:00
renovate[bot]
b18d9f53c6 [deps]: Lock file maintenance (#3772) 2024-08-19 12:59:25 +00:00
Dave Severns
7134d89352 PM-10986 explicitly keep AuthenticatedKeyConnectionApi to prevent cla… (#3765) 2024-08-16 15:45:03 -04:00
Patrick Honkonen
5a7dc198dd [PM-10884] Catch ProviderException when generating a secure key (#3733) 2024-08-16 15:13:41 -04:00
renovate[bot]
7dbfcfdea2 [deps]: Lock file maintenance (#3760) 2024-08-16 14:10:09 -04:00
renovate[bot]
b56ccd1bab [deps]: Update gradle/actions action to v4 (#3759) 2024-08-16 12:58:03 -04:00
renovate[bot]
f05828c87d [deps]: Update gh minor (#3758) 2024-08-16 12:31:59 -04:00
David Perez
48817f0fe4 Simplify error responses (#3762) 2024-08-16 15:07:56 +00:00
github-actions[bot]
3bed2581af Autosync Crowdin Translations (#3756) 2024-08-16 14:27:06 +00:00
André Bispo
acb125b2b9 [PM-6702] 6# Complete registration screen (#3622) 2024-08-16 15:16:36 +01:00
David Perez
72e5aedccd Rename APIs for extra specificity (#3755) 2024-08-16 09:04:10 -05:00
Shannon Draeker
9148a750a5 PM-10874: Prompt for biometrics after switching accounts (#3753) 2024-08-16 09:45:32 -04:00
David Perez
d4600c5c83 PM-10956: Add support for leave organization API (#3754) 2024-08-16 08:37:07 -05:00
David Perez
8094b3fd22 PM-10954: Add network APIs for key-connector (#3752) 2024-08-16 08:36:42 -05:00
David Perez
bd55b9ce72 Add helper function for static retrofit instances (#3749) 2024-08-15 15:26:12 -05:00
David Perez
4726cb743a PM-10936: Add account apis for key connectors (#3748) 2024-08-15 13:53:48 -05:00
André Bispo
244d259804 [PM-6702] 5# Check your email screen (#3621) 2024-08-15 18:25:45 +01:00
André Bispo
eab94dde79 [PM-6702] 4# Start registration screen (#3620) 2024-08-15 17:15:45 +01:00
David Perez
2bb921b592 All booleans stored are nullable for consistency (#3747) 2024-08-15 11:02:01 -05:00
David Perez
18b58e75f8 PM-10909: Add persistance layer for usersKeyConnector (#3740) 2024-08-15 10:34:30 -05:00
André Bispo
e2cd3867dd [PM-6702] 3# Open app from App Link to CompleteRegistration (#3619) 2024-08-15 14:28:35 +01:00
David Perez
524b9e9a08 Add logging for SDK functionality in debug only (#3738) 2024-08-14 16:10:19 -05:00
David Perez
4b35484abb Update to AGP 8.5.2 (#3736) 2024-08-14 15:33:03 -05:00
David Perez
d305dc3081 Remove unused dangerfile (#3735) 2024-08-14 15:32:36 -05:00
David Perez
dde90a251a Update WorkManager to 2.9.1 (#3737) 2024-08-14 15:32:13 -05:00
David Perez
516cd72f66 Fix a failing test (#3734) 2024-08-14 14:46:04 -05:00
David Perez
63884e8518 PM-10894: Add flag for disabling remote feature flag configuration (#3729) 2024-08-14 14:06:09 -05:00
David Perez
8a4d436f1f Remove API specific autofill configuration file (#3730) 2024-08-14 13:54:03 -05:00
Dave Severns
ab279e2264 PM-10851 make the default top app bar reactive (#3726) 2024-08-14 13:42:08 -04:00
Shannon Draeker
2876d75a21 PM-10874: Fix biometrics auto-prompt (#3728) 2024-08-14 11:48:58 -04:00
Patrick Honkonen
aaa0ce4ecd [PM-10664] Display server error message during 2FA login (#3719) 2024-08-14 11:30:05 -04:00
David Perez
499bc20850 PM-10878: Access parcelable data in a safe manor across SDK versions (#3727) 2024-08-14 10:28:01 -05:00
David Perez
2bed4986a1 PM-10855: Update the minimum SDK to API 29 (Android 10) (#3723) 2024-08-14 09:23:13 -05:00
Dave Severns
151b081161 PM-10619 screen to generate master password (#3721) 2024-08-13 16:58:51 -04:00
Shannon Draeker
e3371b7620 PM-8522: Fix vault tab nav bar title when logging in (#3710) 2024-08-13 12:55:51 -04:00
David Perez
551f948644 PM-10835: Make config request after environment update (#3720) 2024-08-13 11:34:33 -05:00
github-actions[bot]
58c31937a2 Autosync Crowdin Translations (#153) 2024-08-13 16:22:53 +00:00
Patrick Honkonen
01ac1f3f93 [BWA-52] Disable MissingTranslation lint error (#156) 2024-08-13 12:19:10 -04:00
renovate[bot]
f93d11fe36 [deps]: Update kotlin (#151) 2024-08-13 12:12:50 -04:00
renovate[bot]
44a53f18d3 [deps]: Update gradle minor (#150) 2024-08-13 11:04:53 -04:00
renovate[bot]
72218b643d [deps]: Update gh minor (#148) 2024-08-13 10:48:24 -04:00
André Bispo
4bd81782c8 [PM-6702] 2# Region load in complete registration step (#3618) 2024-08-13 15:22:34 +01:00
Shannon Draeker
4dbcec85bb PM-10118: Remember generator types (#3708) 2024-08-13 09:27:54 -04:00
Patrick Honkonen
d00a77e247 [BWA-47] Update gradle wrapper validation GH action (#145) 2024-08-13 10:18:44 -03:00
Patrick Honkonen
6e9f9d62a1 [BWA-28] Read Crowdin API token from secrets (#152) 2024-08-13 09:18:07 -04:00
Patrick Honkonen
5a0b1caecd [PM-10696] Dismiss vault unlock keyboard (#3718) 2024-08-12 16:11:30 -04:00
Dave Severns
2b13151bd1 PM-10620 prevent account lockout tips screen (#3711) 2024-08-12 08:38:23 -04:00
David Perez
5e643e11fd PM-10243: Update carousel text (#3714) 2024-08-09 16:15:23 -05:00
Patrick Honkonen
2789b1cc37 [PM-10697] Auto-focus on PIN Dialog field (#3713) 2024-08-09 16:26:54 -04:00
David Perez
b7a47eb91e Add helper method for standardizing margins (#3712) 2024-08-09 14:59:21 -05:00
Dave Severns
06f6f19255 PM-10071 ensure that lowercase letters take priority over the upperca… (#3707) 2024-08-09 14:55:24 -04:00
André Bispo
e717183239 [PM-6702] 1# Add service calls for email verification (#3617) 2024-08-09 19:38:52 +01:00
David Perez
edb87202d2 PM-10628: Add pin unlock to SetupUnlockViewModel (#3709) 2024-08-09 12:09:52 -05:00
David Perez
9b808058f5 Allow the ShowShareSheet event to be launched after the screen is paused (#3706) 2024-08-09 09:58:47 -05:00
github-actions[bot]
89589aa907 Autosync Crowdin Translations (#3703)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2024-08-09 14:33:21 +00:00
David Perez
805fea630c Add logic for biometric unlock to SetupUnlockScreen (#3702) 2024-08-09 09:09:41 -05:00
David Perez
145f8adf0c PM-10621: Add the SetupUnlockScreen (#3699) 2024-08-08 16:18:29 -05:00
Dave Severns
6bb5ef7417 [PM-10618] MP guidance screen with info and clickable card to navigate … (#3697) 2024-08-08 16:53:56 -04:00
Carlos Gonçalves
722726882b [PM-9833] Allow passkey deletion edit view (#3654) 2024-08-08 21:17:09 +01:00
David Perez
9ed30d7913 Fix a minor parcelable warning (#3701) 2024-08-08 14:47:43 -05:00
David Perez
6c5c0c7c03 PM-10729: Add a helper method for determining if the app is in portrait orientation (#3698) 2024-08-08 12:24:12 -05:00
Dave Severns
a57a7e099c [PM-10065] Use appropriate back behavior depending on how you are take to auth approval screen (#3695) 2024-08-08 11:37:20 -04:00
Shannon Draeker
f17289a104 PM-10242 PM-10243 PM-10244 PM-10245 PM-10246: Welcome carousel (#3657) 2024-08-07 16:12:46 -04:00
David Perez
e598fe5714 PM-10621: Create common biometrics and pin unlock UI elements (#3696) 2024-08-07 14:50:40 -05:00
Patrick Honkonen
be534f940b [PM-10670] Prompt for PIN creation during passkey user verification (#3694) 2024-08-07 14:17:13 -04:00
David Perez
782b474e54 BIT-2437: Add mitigation logic for bad encryption key (#3426) 2024-08-07 11:07:17 -05:00
Álison Fernandes
d8471b41ca [PM-10686] Change the background colour of the app launcher to Bitwarden's blue (#3693) 2024-08-07 16:45:56 +01:00
David Perez
9484eebc70 Consolidate unlock vault functionality for auth into a single helper method (#3690) 2024-08-07 10:45:04 -05:00
A. Bubnov
22dae88b42 [PM-10024] Force focus on Master Password or Pin input field (#3601) 2024-08-07 11:34:32 -04:00
David Perez
23066769a1 Add option to retrieve feature flag synchronously (#3692) 2024-08-07 10:13:52 -05:00
Shannon Draeker
59ba585048 PM-10122: Autofocus on PIN or password field (#3678) 2024-08-06 15:49:39 -04:00
David Perez
6c50cbf558 Add onboarding feature flag (#3689) 2024-08-06 14:44:49 -05:00
Dave Severns
0085388446 [PM-10071] Sort search items with same logic as displayed items (#3683) 2024-08-06 15:29:33 -04:00
Dave Severns
18cd66a34b PM-9532: pt2. separate vault unlock logic and fail out on error during login. (#3609) 2024-08-06 14:42:05 -04:00
Dave Severns
a090000826 [PM-10058] Non-remembered device TDE issue in same session (#3631) 2024-08-06 13:34:04 -04:00
David Perez
af82261fba Minor formating for the VaultSdkSource (#3688) 2024-08-06 12:09:56 -05:00
David Perez
b15371bfce Remove a suppression from gradle properties that is no longer needed (#3687) 2024-08-06 11:38:06 -05:00
Patrick Honkonen
1e5bee2917 [PM-10644] Re-prompt master password for protected passkeys (#3682) 2024-08-06 15:43:12 +00:00
David Perez
3819916241 PM-10241: Add the onboarding carousel feature flag (#3686) 2024-08-06 10:22:46 -05:00
David Perez
e7c69fc089 Allow null network responses for 204s (#3685) 2024-08-06 10:13:57 -05:00
André Bispo
994a577600 [PM-9401] Server feature flags manager (#3656) 2024-08-06 16:00:22 +01:00
David Perez
02167024b1 Minor formatting and clean up for ResultCall (#3684) 2024-08-06 09:52:20 -05:00
Dave Severns
f110687e76 PM-10066 don't prompt for MP if the user does not have one (#3633) 2024-08-05 17:34:46 -04:00
Dave Severns
abeb60e237 [PM-10645] add nav bar padding in bw scaffold for FAB (#3679) 2024-08-05 16:57:21 -04:00
Patrick Honkonen
4c8164954d [PM-10556] Move FIDO 2 intent filter to main manifest (#3677) 2024-08-05 11:26:46 -04:00
Patrick Honkonen
7f13822f15 [PM-9927] Sort Sends alphabetically (#3665) 2024-08-05 10:32:35 -04:00
Patrick Honkonen
31bf696e7e [PM-10373] Fix FIDO 2 credential creation from unprivileged apps (#3658) 2024-08-05 09:28:37 -05:00
renovate[bot]
f46d12c7b1 [deps]: Update com.google.devtools.ksp to v2.0.0-1.0.24 (#3672)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-05 09:25:12 -05:00
renovate[bot]
ad240a9a19 [deps]: Update gradle minor (#3674)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-05 08:53:21 -05:00
renovate[bot]
93107ec6a3 [deps]: Lock file maintenance (#3675) 2024-08-05 13:07:33 +00:00
renovate[bot]
056eb7fdd5 [deps]: Update gh minor (#3673) 2024-08-05 13:06:01 +00:00
David Perez
bbe50ae0ff PM-10559: Add logic to re-evaluate invalid password fields for Autofill (#3668) 2024-08-02 16:52:39 -05:00
Brian Yencho
aae7a6e895 PM-10528: Fix user switching issue due to rapid Activity recreation when locking (#3669) 2024-08-02 16:39:23 -05:00
github-actions[bot]
32b260ca9f Autosync Crowdin Translations (#3666) 2024-08-02 15:28:27 +00:00
Patrick Honkonen
0612a5834a [PM-9472] Update release notes generated for Firebase (#3664) 2024-08-02 10:48:33 -04:00
Shannon Draeker
055fbc1277 PM-10094: Disable double-navigation by default (#3660) 2024-08-01 15:31:04 -06:00
Patrick Honkonen
d0edca67c5 [PM-10441] Fix memory exception during CI builds (#3662) 2024-07-31 21:23:25 -04:00
Patrick Honkonen
d558f94e40 [PM-10440] Enable minification on beta build variants (#3661) 2024-07-31 22:19:52 +00:00
Patrick Honkonen
1f8d50e788 [PM-10428] Default UserVerificationRequirement to PREFERRED (#3659) 2024-07-31 17:41:47 -04:00
Patrick Honkonen
260b3bfb1b [PM-9803] Enable Credential Manager on production builds (#3651) 2024-07-31 09:11:09 -04:00
David Perez
d5e0ebee12 Remove unused Json object from VaultRepository (#3653) 2024-07-30 17:44:05 -05:00
David Perez
6d22ee9550 PM-10379: Update the timeout action logic to occur immediately after requirements are met (#3652) 2024-07-30 17:43:54 -05:00
Shannon Draeker
82096e0625 PM-9406: Add passkey management to autofill settings (#3392) 2024-07-30 16:10:09 -06:00
André Bispo
646566edd8 [PM-9875] Server configurations (#3645) 2024-07-30 20:23:33 +01:00
Patrick Honkonen
b26e1a082e [PM-9410] Filter matching FIDO 2 credentials after vault unlock (#3648) 2024-07-30 13:45:36 -04:00
Patrick Honkonen
deb8f811e5 [PM-9410] Implement FIDO 2 Get Credentials completion (#3639) 2024-07-29 16:50:20 -04:00
Shannon Draeker
0e90bbb905 PM-8522: Vault tab bar title for organization users (#3632) 2024-07-29 14:19:08 -06:00
David Perez
58a91c15aa PM-10140: Update the VaultSdkSource and VaultDiskSource to use parallelization when processing heavier loads (#3649) 2024-07-29 15:10:38 -05:00
David Perez
1daddbc905 PM-10140: Update Autofill classes to be singletons (#3647) 2024-07-29 13:13:08 -05:00
David Perez
b6af48fb3b PM-10140: Allow for the vault data to have a pending state by default when data is already present (#3646) 2024-07-29 13:06:08 -05:00
David Perez
3ff70b4598 PM-10140: Update looping SDK calls to use single instance of client (#3644) 2024-07-29 11:10:22 -05:00
Patrick Honkonen
b0079fca5c [PM-9410] Introduce FIDO 2 Get Credentials Request special circumstance (#3637) 2024-07-29 11:54:23 -04:00
David Perez
39250e5cb4 PM-10140: Add caching for large string resources to avoid delays and reduce timeout when retrieving ciphers (#3638) 2024-07-29 10:46:13 -05:00
Patrick Honkonen
74132de8ed [PM-9409] Authenticate selected FIDO 2 credential (#3630) 2024-07-26 13:18:29 -04:00
David Perez
a6bbde2bed PM-9135: Update host matching to include optional port value (#3623) 2024-07-26 10:33:15 -05:00
github-actions[bot]
544eabfaa3 Autosync Crowdin Translations (#3634)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2024-07-26 15:26:46 +00:00
Shannon Draeker
680ebc2e47 PM-9681: Setup Bitwarden PIN on add edit view (#3627) 2024-07-26 09:06:49 -06:00
Patrick Honkonen
b0f0c0f33b [PM-9409] Add FIDO 2 authentication to credential manager (#3629) 2024-07-25 15:46:26 -04:00
Shannon Draeker
c09fe554bc PM-9681: Setup Bitwarden PIN (#3626) 2024-07-25 10:59:20 -06:00
A. Bubnov
5c2ac2e037 [PM-10067] Show content on Vault screen when we have trashed items only (#3624) 2024-07-25 10:54:21 -04:00
Patrick Honkonen
793971c3a3 [PM-9409] Complete FIDO 2 assertion with appropriate response (#3615) 2024-07-25 10:33:14 -04:00
Dave Severns
8ffd14c2fb [PM-9927] Sort order update (#3625) 2024-07-24 16:17:58 -04:00
Patrick Honkonen
da3d834a91 [PM-9409] Define FIDO 2 assertion Special Circumstance (#3612) 2024-07-24 16:01:22 -04:00
Shannon Draeker
b48837e13c PM-9682: Verify with PIN on add edit view (#3610) 2024-07-24 09:40:25 -06:00
Dave Severns
b44a320dc8 PM-9937 an existing email should be able to add account from a different hosted instance. (#3613) 2024-07-23 15:45:56 -04:00
Patrick Honkonen
d2432f7cf7 Extract FIDO 2 user verification enum (#3614) 2024-07-23 15:33:20 -04:00
Shannon Draeker
7cf7536857 PM-9682: Verify with PIN on item listing (#3600) 2024-07-23 10:53:44 -06:00
David Perez
779cd1356a Update the HOST type cipher matching to ignore the port (#3611) 2024-07-23 10:38:55 -05:00
Dave Severns
05dc220303 PM-9532 pt. 1 small refactor of login success steps (#3599) 2024-07-23 09:52:10 -04:00
renovate[bot]
48f30f022d [deps]: Update gradle minor (#149) 2024-07-23 13:08:54 +00:00
David Perez
21c1fa7131 Provide autofill response data even if focused field is not fillable (#3598) 2024-07-22 17:10:48 -05:00
Shannon Draeker
2475bf5a41 PM-9684: Verify with master password on add edit view (#3586) 2024-07-22 15:20:00 -06:00
Shannon Draeker
62154f5261 PM-9408: Show bottom sheet with passkey options (#3444) 2024-07-22 14:07:22 -06:00
renovate[bot]
0e44b21361 [deps]: Update kotlin (#3591)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-22 13:19:24 -05:00
David Perez
f3d28551b1 BIT-877: Mockk update fixed a disabled test (#3597) 2024-07-22 11:39:06 -05:00
renovate[bot]
1927630acb [deps]: Update io.mockk:mockk to v1.13.12 (#3590) 2024-07-22 11:39:56 -04:00
renovate[bot]
975fa91d36 [deps]: Lock file maintenance (#3592) 2024-07-22 11:39:12 -04:00
renovate[bot]
7218ca2477 [deps]: Update github/codeql-action action to v3.25.13 (#3589) 2024-07-22 09:14:07 -04:00
Shannon Draeker
ee87d8ada8 PM-9684: Verify with master password on item listing (#3585) 2024-07-19 15:20:55 -06:00
Patrick Honkonen
8a381d8682 Refactor PublicKeyCredentialCreationOptions (#3584) 2024-07-19 15:08:54 -04:00
David Perez
1fdfbac7b7 Add timeouts to operations that could hang (#3553) 2024-07-19 11:05:24 -05:00
github-actions[bot]
7fbc6ea4f3 Autosync Crowdin Translations (#3555)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2024-07-19 16:02:15 +00:00
Patrick Honkonen
7ddbc99add Cancel FIDO 2 registration job when cancellation occurs (#3583) 2024-07-19 11:44:33 -04:00
David Perez
4abf907dc5 Catch TransactionTooLargeExceptions in autofill (#3569) 2024-07-19 09:31:17 -05:00
David Perez
9ffc0360bd Update the Firebase BOM to 33.1.2 (#3552) 2024-07-18 15:50:48 -05:00
David Perez
c4365c0193 Update to AGP 8.5.1 (#3551) 2024-07-18 15:50:31 -05:00
Patrick Honkonen
1ea1e7918b [PM-9407] Confirm overwrite existing passkey in edit mode (#3542) 2024-07-18 16:53:15 +00:00
Patrick Honkonen
815e779475 [PM-9407] Confirm overwrite existing passkey on item listing (#3540) 2024-07-18 12:35:05 -04:00
renovate[bot]
d9f506dd8f [deps]: Update ubuntu to v22 (#3550) 2024-07-18 12:34:10 -04:00
renovate[bot]
4377921d20 [deps]: Update gh minor (#3549) 2024-07-18 12:33:15 -04:00
David Perez
775a73fe54 PM-9659: Do not show push notification permissions on FDroid (#3528) 2024-07-18 11:17:23 -05:00
David Perez
96324f01d7 All of the autofill processing happens in a job (#3545) 2024-07-17 15:05:11 -05:00
Dave Severns
7d18310f30 PM-8534 update the active account after a "soft logout" (#3456) 2024-07-17 14:06:51 -04:00
Dave Severns
3d584c84f2 [PM-9844] Android - Non-Premium Users Can Copy TOTP Code From Item Menu (#3539) 2024-07-17 14:06:18 -04:00
Dave Severns
f1c486bf9a [PM-9838] Custom field spacing on Add/Edit item screen (#3546) 2024-07-17 13:09:47 -04:00
Dave Severns
a5224c966c PM-9007: export vault copy (#3537) 2024-07-17 09:23:37 -04:00
Patrick Honkonen
9b19c71d95 [PM-8137] Perform FIDO 2 verification on item add/edit when required (#3532) 2024-07-16 17:02:16 -04:00
Patrick Honkonen
36270ec55a [PM-8137] Perform FIDO 2 verification on item listing when required (#3529) 2024-07-16 17:01:55 -04:00
Patrick Honkonen
94781bc1a9 [PM-9407] Create reusable overwrite passkey confirmation dialog (#3541) 2024-07-16 16:19:41 -04:00
Patrick Honkonen
93cde9bfdc Update Bitwarden SDK (#3538) 2024-07-16 13:34:33 -04:00
Patrick Honkonen
291af8d017 [PM-8137] Introduce FIDO 2 user verification to add edit item (#3450) 2024-07-16 10:56:12 -04:00
Dave Severns
b0ff0b9185 [Build Issue] use full source set to match fastfile test task (#3533) 2024-07-16 09:56:23 -04:00
Patrick Honkonen
7653d71b3d [PM-8137] Set initial FIDO 2 user verification state (#3463) 2024-07-16 09:02:59 -04:00
Patrick Honkonen
5ea2f1c736 [PM-8137] Introduce FIDO 2 user verification tracking (#3459) 2024-07-15 14:44:16 -04:00
Dave Severns
721c69619e PM-9017 updated the continue button state when switching 2FA method (#3530) 2024-07-15 14:32:40 -04:00
Patrick Honkonen
58937d4e20 Fix detekt issues (#3531) 2024-07-15 18:18:46 +00:00
Dave Severns
ed53abb29f PM-7495 perform client side check for invalid MP before account deletion (#3439) 2024-07-15 13:51:50 -04:00
Patrick Honkonen
53c5d11076 [PM-8137] Introduce FIDO 2 user verification to item listing screen (#3449) 2024-07-15 11:11:45 -04:00
David Perez
4d65230476 Update the detekt command for fastlane to cover more of the app (#3462) 2024-07-12 16:23:28 -05:00
David Perez
20d37e2f90 Hide inline autofill option when not supported (#3455) 2024-07-12 16:09:14 -05:00
Patrick Honkonen
101b807b5c Resolve detekt issues (#3460) 2024-07-12 20:54:48 +00:00
Matt Bishop
2f526a7725 Exclude tests from Sonar (#147) 2024-07-12 16:45:20 -04:00
Matt Bishop
3931af096d Exclude tests from Sonar (#3457) 2024-07-12 16:43:36 -04:00
Patrick Honkonen
c6d05b4631 [PM-8137] Respond to SDK user verification callbacks implicitly (#3448) 2024-07-12 09:29:34 -05:00
Dave Severns
27747b6cb9 PM-8202 move dialog status to VM for restore item, add check for MP p… (#3436) 2024-07-12 09:56:40 -04:00
github-actions[bot]
dbf1d423e8 Autosync Crowdin Translations (#3453)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2024-07-12 10:29:34 +00:00
Shannon Draeker
eb771e9dfa PM-9439: Update cipher list item for passkeys (#3422) 2024-07-11 18:48:25 -06:00
Patrick Honkonen
a84694b100 [PM-8137] Introduce user verification prompt (#3447) 2024-07-11 22:22:54 +00:00
Patrick Honkonen
9b240ddf5f [PM-8137] Refactor FIDO 2 credential registration result object (#3445) 2024-07-11 18:04:24 -04:00
David Perez
c409132825 Update no network errors to be consistent and have a space inbetween concatenated text (#3446) 2024-07-11 15:00:30 -05:00
David Perez
f6f28f6a58 Add logic to find missing username fields (#3440) 2024-07-11 12:16:35 -05:00
Patrick Honkonen
b2300328e1 Refactor PublicKeyCredentialCreationOptions to match WebAuthn spec (#3443) 2024-07-11 12:43:51 -04:00
Patrick Honkonen
9205dbef59 Introduce utility function for displaying VaultAddEdit error message (#3438) 2024-07-10 21:56:36 +00:00
Patrick Honkonen
0651494393 Introduce utility function for clearing VaultAddEdit dialog state (#3437) 2024-07-10 15:57:43 -04:00
David Perez
4f3d42264d Add support for AutoCompleteTextView as an input field (#3435) 2024-07-10 11:40:46 -05:00
Patrick Honkonen
0cdae9bccf Upload F-Droid Beta artifacts to GitHub (#3428) 2024-07-09 17:50:46 -04:00
David Perez
5677373421 Use random ints for request codes to ensure no overlap (#3427) 2024-07-09 14:13:58 -05:00
David Perez
0dc606b470 Clean up some minor detekt issues (#3425) 2024-07-09 11:32:57 -05:00
David Perez
65237c18d7 Add ability to log non-fatal errors (#3417) 2024-07-09 10:02:36 -05:00
David Perez
adf7916a4c BIT-2446: Limit the number of inline autofill items that can be displayed (#3418) 2024-07-09 09:38:40 -05:00
David Perez
01b786fcf9 Update to the latest Bitwarden SDK (#3419) 2024-07-08 17:25:57 -05:00
Shannon Draeker
99c50a3fc8 PM-9443: Update empty search state (#3409) 2024-07-08 14:26:34 -06:00
David Perez
e9057cb866 BIT-2440, BIT-2441: Clean up the way we update the account info after token refresh (#3416) 2024-07-08 10:44:43 -05:00
David Perez
4b0c6ad911 PM-9077: Ensure each PendingIntent for inline autofill uses unique requestCode (#3401) 2024-07-08 08:51:01 -05:00
renovate[bot]
263b401dc6 [deps]: Update kotlin (#3412) 2024-07-08 09:47:58 -04:00
renovate[bot]
43855ab555 [deps]: Update kotlin (#142) 2024-07-08 09:47:07 -04:00
renovate[bot]
9fdeb8e639 [deps]: Update gradle minor (#138) 2024-07-08 09:46:40 -04:00
renovate[bot]
a19523a3f8 [deps]: Lock file maintenance (#134) 2024-07-08 09:46:00 -04:00
renovate[bot]
023e5dd2fc [deps]: Update ubuntu to v22 (#133) 2024-07-08 09:45:31 -04:00
renovate[bot]
0af9bb887a [deps]: Update crowdin/github-action action to v2 (#131) 2024-07-08 09:44:58 -04:00
renovate[bot]
cae000ef5f [deps]: Update gradle minor (#3414) 2024-07-08 09:43:01 -04:00
renovate[bot]
5856403c66 [deps]: Update crowdin/github-action action to v2 (#3415) 2024-07-08 09:41:42 -04:00
renovate[bot]
02b5542388 [deps]: Update gh minor (#3411) 2024-07-08 09:41:02 -04:00
renovate[bot]
1e1beec6e4 [deps]: Update gh minor (#117) 2024-07-08 09:33:44 -04:00
Dave Severns
870de652be BIT-2431 add condition to only update labelTextWidth on initial layout (#3399) 2024-07-05 14:48:49 -04:00
Dave Severns
f13679cd2c BIT-2398 if the org associated with a cipher uses TOTP enable the aut… (#3398) 2024-07-05 14:40:06 -04:00
github-actions[bot]
9e0e07967f Autosync Crowdin Translations (#3402) 2024-07-05 15:53:30 +00:00
Patrick Honkonen
d182b4edf1 [PM-8137] Allow registering a passkey to a new cipher (#3329) 2024-07-05 11:35:28 -04:00
Patrick Honkonen
a2572d996b Include Livefront in Firebase distributions (#3400) 2024-07-03 14:37:33 -05:00
David Perez
c3d2389829 BIT-2439: Handle invalid patterns when processing regular expression matching (#3397) 2024-07-03 09:56:09 -05:00
David Perez
074979095b Update detekt config and update suppressions (#3396) 2024-07-02 17:19:56 -05:00
David Perez
ba95a53ebf BIT-2443: Fix crash caused by extra blank spaces in name (#3395) 2024-07-02 16:24:03 -05:00
David Perez
bb6a7af423 BIT-2442: check type before extracting autofill text (#3394) 2024-07-02 15:18:25 -05:00
David Perez
b181d0d026 BIT-2438: Update push notification processing logic to be more lenient (#3393) 2024-07-02 14:53:29 -05:00
David Perez
f5039d72b9 Update NotificationPayload to handle null values (#3391) 2024-07-01 17:01:07 -05:00
Patrick Honkonen
9a72c0c8e5 [BWA-45] Update Androidx Lifecycle components to fix runtime crash (#140) 2024-07-01 17:09:33 -04:00
David Perez
44e2596a30 Update the Lifecycle library (#3390) 2024-07-01 14:12:53 -05:00
David Perez
32e3f1e9ba PM-9081: Should cancel the job not the scope when managing autofill requests (#3389) 2024-07-01 13:09:50 -05:00
Patrick Honkonen
d7032b8475 Distribute builds to Firebase on push events to main (#3388) 2024-07-01 11:31:10 -04:00
github-actions[bot]
7d03b62dd7 Autosync Crowdin Translations (#3381) 2024-06-28 19:00:40 -04:00
Álison Fernandes
fd7ceef2ee [PM-9340] Improve Bug template and adds a config link (#3380)
Co-authored-by: Matt Bishop <mbishop@bitwarden.com>
2024-06-28 09:08:19 -04:00
Patrick Honkonen
581539b0d0 [PM-8985] Fix typo in fastfile (#3379) 2024-06-28 00:00:31 +01:00
Álison Fernandes
fae92be38a [PM-9340] Fix bug template syntax error by adding quotes to label (#3378) 2024-06-27 18:38:15 -04:00
Álison Fernandes
9f354bf248 [PM-9340] Fix template syntax error (#3377) 2024-06-27 23:13:43 +01:00
Patrick Honkonen
fc84a89dd2 [PM-8985] Publish beta builds to internal track (#3376) 2024-06-27 18:08:54 -04:00
Álison Fernandes
1d6707ef82 [PM-9340] Updates the bug template and readme to direct users to the right repos (#3374) 2024-06-27 22:58:33 +01:00
Patrick Honkonen
82e2c82666 [PM-8985] Fetch all tags when checking out repo for build job (#3371) 2024-06-27 17:15:17 -04:00
David Perez
0f838965fb Fix bug where JWT token clearing premium status (#3373) 2024-06-27 15:30:51 -05:00
David Perez
4f5454b4b7 Fix a screen capture bug that clears the setting when the app language changes (#3372) 2024-06-27 13:56:55 -05:00
David Perez
1bc348fa1a Update to the latest versions of AndroidX Lifecycle (#3370) 2024-06-27 10:21:31 -05:00
Patrick Honkonen
54218f86d8 [BIT-2140] Add strings for typeform and export vault (#3369) 2024-06-27 10:38:19 -04:00
David Perez
d9d1e9a12c Update CipherViewExtensions to use previous state to avoid clearing user set values (#3368) 2024-06-27 09:11:58 -05:00
utzcoz
2720a80e2a [PM-9151] gradle: Fix typo for Robolectric library name (#3338) 2024-06-27 09:38:23 -04:00
Patrick Honkonen
1e1d41579a [PM-8985] Trigger build job on push events to main (#3362) 2024-06-27 09:16:51 -04:00
Patrick Honkonen
96b4326d7d [PM-8015] Update Crowdin destination path (#3365) 2024-06-27 09:08:35 -04:00
David Perez
f1d05f2e6a Clean up some detekt issues (#3366) 2024-06-26 15:11:52 -05:00
Matt Bishop
280d34d85c Use proper coverage report (#3367) 2024-06-26 16:06:36 -04:00
David Perez
732ebb61fb Clean up environment urls (#3364) 2024-06-26 14:59:26 -05:00
Matt Bishop
67874655fa Replace Danger / Shroud with Codecov (#3363) 2024-06-26 15:45:23 -04:00
David Perez
fc78037fb0 BIT-2433: Filter trash from search results (#3361) 2024-06-26 11:34:39 -05:00
Patrick Honkonen
2226c8d59e [PM-8015] Update language directories to follow Crowdin + Android defaults (#3359) 2024-06-26 12:27:35 -04:00
Patrick Honkonen
a3c72e572c [PM-8985] Distribute beta builds on every push to main (#3351) 2024-06-26 12:19:32 -04:00
renovate[bot]
159cb02899 [deps]: Lock file maintenance (#3343) 2024-06-26 09:52:59 -04:00
renovate[bot]
d8bd3ee6b6 [deps]: Update gh minor (#3342) 2024-06-26 09:52:16 -04:00
David Perez
d9b1809e58 BIT-2411: Add logic for managed device pre-configured URLs (#3358) 2024-06-25 16:18:05 -05:00
David Perez
63e7465433 Update strings (#3356) 2024-06-25 11:25:51 -05:00
Patrick Honkonen
ad7a223c22 [PM-8015] Pull translations from Crowdin (#3348) 2024-06-25 12:06:04 -04:00
Patrick Honkonen
c2b41859c5 [PM-8016] Push string resources to Crowdin (#3347) 2024-06-25 11:57:06 -04:00
David Perez
ed645cb421 Update Firebase and Crashlytics (#3355) 2024-06-25 10:04:49 -05:00
David Perez
d1e8ed63a4 Add edit cipher org events (#3352) 2024-06-25 09:12:45 -05:00
David Perez
949768ac95 Add password reprompt for card number and code (#3350) 2024-06-24 15:08:38 -05:00
Matt Bishop
94b56f624f Adjust Sonar scan paths (#3349) 2024-06-24 14:20:06 -04:00
Matt Bishop
cff5c7b9a2 Adjust Sonar scan paths (#139) 2024-06-24 14:15:07 -04:00
David Perez
9f5a27c06c Add organization event tracking (#3346) 2024-06-24 12:44:31 -05:00
David Perez
6bd628c346 Create sealed class for Organization Events (#3345) 2024-06-24 11:09:01 -05:00
David Perez
448ef1597f Append 'Json' suffix to network model name (#3344) 2024-06-24 10:22:26 -05:00
Matt Bishop
be96f1b9d4 Remove Renovate SDK customizations (#137) 2024-06-21 11:31:36 -04:00
Matt Bishop
b8511ec4f8 Configure registry URL for SDK (#135) 2024-06-21 11:07:30 -04:00
Matt Bishop
e5f7488a7c Add Maven as supported Renovate manager (#136) 2024-06-21 10:34:00 -04:00
David Perez
5183832e35 trackEvent should not suspend (#3331) 2024-06-20 16:03:42 -05:00
Matt Bishop
ae15372d8d Additional scanning (#3328) 2024-06-20 16:44:39 -04:00
David Perez
16fce43739 BIT-2418: Add the OrganizationEventManager (#3330) 2024-06-20 14:45:13 -05:00
David Perez
170db5077d Add Organization events database (#1470) 2024-06-20 17:08:07 +01:00
David Perez
a2f2216df2 Create a common FakeLifecycle and LifecycleOwner (#1471) 2024-06-20 17:08:07 +01:00
David Perez
cd25e2b280 BIT-2430: Allow lowercase TOTP secrets (#1469) 2024-06-20 17:08:07 +01:00
David Perez
efbb9b3a19 Add organization events API request (#1468) 2024-06-20 17:08:07 +01:00
David Perez
0faa1be4e4 [AC-2787] Remove the unassigned items dialog (#1466) 2024-06-20 17:08:07 +01:00
David Perez
f03f9e63d4 Set all multiipart request MIME types to 'multipart/form-data' (#1467) 2024-06-20 17:08:07 +01:00
David Perez
5e52b5a53d Remove legacy GCM notification support (#1464) 2024-06-20 17:08:07 +01:00
David Perez
f4bdf5178a Remove unused beta icons (#1465) 2024-06-20 17:08:07 +01:00
Patrick Honkonen
a2b7132cf3 [BWA-28] Sync translations with Crowdin (#129) 2024-06-17 12:26:17 -04:00
Patrick Honkonen
8be57a6ef7 Escape and use correct apostrophe symbol (#130) 2024-06-17 12:25:48 -04:00
renovate[bot]
49a5ff34df [deps]: Update gradle minor (#67) 2024-06-14 15:43:04 -04:00
renovate[bot]
53ac8ac49c [deps]: Update kotlin (#107) 2024-06-14 15:32:28 -04:00
renovate[bot]
2b721ac52c [deps]: Update googleProtoBufJava to v4 (major) (#118) 2024-06-14 15:19:59 -04:00
renovate[bot]
31f45ae5a4 [deps]: Update kotlin to v2 (major) (#108) 2024-06-14 15:09:01 -04:00
Patrick Honkonen
f912e00d21 [BWA-10] Sanitize launch intents before processing (#128) 2024-06-14 15:06:45 -04:00
Patrick Honkonen
7ca1eab4b2 [BWA-32] Sort verification codes by issuer (#127) 2024-06-14 15:06:15 -04:00
Patrick Honkonen
cbb469e5ab Extract account name from Aegis imports (#126) 2024-06-14 15:05:38 -04:00
Patrick Honkonen
17c9008f95 Improve 2FAS import (#124) 2024-06-13 16:02:27 -04:00
Patrick Honkonen
2640d28468 Display a descriptive error when import fails (#122) 2024-06-12 13:13:17 -05:00
Patrick Honkonen
f695254fc1 Update 2FAS import option label (#123) 2024-06-12 14:12:27 -04:00
Patrick Honkonen
18e5b711bb Fix Bitwarden import (#120) 2024-06-12 11:46:11 -04:00
Patrick Honkonen
9912123293 Remove language switcher (#121) 2024-06-12 11:38:22 -04:00
Michał Chęciński
e737f3260d [BRE-101] Remove dept-devops from CODEOWNERS (#116) 2024-06-11 18:19:32 -04:00
renovate[bot]
be8562b4db [deps]: Lock file maintenance (#109) 2024-06-11 18:19:06 -04:00
Matt Bishop
dc0413b416 Code coverage configuration (#115) 2024-06-05 16:02:24 -04:00
Patrick Honkonen
d1b5f3078e Add example test for MainViewModel (#113) 2024-06-03 13:43:13 -04:00
Matt Bishop
c8194545a4 Repo tuneup (#112) 2024-06-03 10:17:36 -04:00
Matt Bishop
c67a5d1a8d Checkmarx configuration (#111) 2024-05-31 12:31:40 -04:00
Patrick Honkonen
00b35bd3ab [BWA-16] Import Google Authenticator exports via scanner (#101) 2024-05-28 13:01:07 -04:00
renovate[bot]
a40f3b91db [deps]: Update gh minor (#106)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-28 12:57:01 -04:00
Patrick Honkonen
9537bfaf6f [BWA-21] Disable screen capture (#110) 2024-05-28 12:50:30 -04:00
Patrick Honkonen
e9fb28d374 [BWA-18] Add Backup option to settings (#103) 2024-05-22 22:11:48 +00:00
Patrick Honkonen
1161c3c446 [BWA-22] Prevent FAB from hiding verification codes (#102) 2024-05-22 22:06:00 +00:00
Patrick Honkonen
d3e4b56d30 Add androidx.lifecycle dependencies to kotlin group (#104) 2024-05-22 18:04:56 -04:00
Dillon Beresford
f9dd295188 [PM-7288] Include changes to actions in scan workflow (#87) 2024-05-17 17:49:48 -05:00
Patrick Honkonen
6fae5b8b77 [BWA-12] Update workflow to accept custom inputs (#96) 2024-05-17 10:57:00 -04:00
Patrick Honkonen
2529ed3fb9 [BWA-5] Support importing Aegis exports (#99) 2024-05-17 09:53:23 -04:00
Patrick Honkonen
a1e7e92d6d [BWA-14] Support importing LastPass exports (#98) 2024-05-16 15:30:48 -04:00
Patrick Honkonen
15251c840c Separate androidxTest and androidxTestRules dependency versions (#97) 2024-05-16 15:19:55 -04:00
Patrick Honkonen
663265d7b3 [BWA-11] Import 2FAS exports (#95) 2024-05-16 12:30:53 -04:00
Patrick Honkonen
f2365771ff [BWA-9] Set task affinity to mitigate task hijacking (#94) 2024-05-15 15:13:47 -04:00
renovate[bot]
97e6758449 [deps]: Update kotlin (#90) 2024-05-15 14:50:28 -04:00
renovate[bot]
91e197db2c [deps]: Update com.google.firebase.crashlytics to v3 (#91) 2024-05-14 15:19:42 -04:00
renovate[bot]
8e10170347 [deps]: Lock file maintenance (#93) 2024-05-13 12:26:59 -04:00
renovate[bot]
74b6fc7e2e [deps]: Update com.google.firebase:firebase-bom to v33 (#92) 2024-05-13 09:29:48 -04:00
renovate[bot]
6b4f959b12 [deps]: Update gh minor (#89)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-13 09:19:12 -04:00
Patrick Honkonen
578efd3b7f Define issue template for bugs (#86) 2024-05-08 23:24:54 -04:00
Patrick Honkonen
31669cf457 Force scanned codes to uppercase alpha characters (#85) 2024-05-07 15:50:43 -04:00
Patrick Honkonen
d9e29d3c81 Allow users to select favorites (#84) 2024-05-07 13:21:30 -04:00
Patrick Honkonen
5c38d62a61 Allow users to import exported JSON vault files (#81) 2024-05-06 20:58:27 -04:00
Patrick Honkonen
9b5449f657 Enforce Base32 key values (#82) 2024-05-03 16:14:49 -04:00
Patrick Honkonen
6da31f797d Declare ruby version globally (#80) 2024-05-03 16:14:01 -04:00
Patrick Honkonen
f546bd2640 Fix version name generation (#78) 2024-05-02 12:28:38 -05:00
Patrick Honkonen
d32ed06516 Build release bundles and publish to Firebase (#50) 2024-05-02 10:24:37 -04:00
Patrick Honkonen
26c22295fc Use valid authenticators on Android Q and below (#77) 2024-05-01 21:20:29 -04:00
Patrick Honkonen
de9aebbda9 Remove nulab password strength library (#73) 2024-05-01 20:09:31 -05:00
Kyle Spearrin
f7ea3a7972 Fix screenshot dimensions in readme (#76) 2024-05-01 13:51:00 -04:00
Patrick Honkonen
51c3f2b04a Add README and code style guidelines (#75) 2024-05-01 09:50:36 -04:00
renovate[bot]
61d80793e7 [deps]: Update ruby to v3.3.1 (#30)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Patrick Honkonen <phonkonen@bitwarden.com>
Co-authored-by: Patrick Honkonen <1883101+SaintPatrck@users.noreply.github.com>
2024-05-01 07:16:42 -04:00
renovate[bot]
b59814aa83 [deps]: Update kotlin (#66) 2024-04-30 18:23:21 -04:00
Patrick Honkonen
5c46e913a2 Allow users to toggle crash logging (#72) 2024-04-30 17:41:55 -04:00
Patrick Honkonen
1a592273bf Enable crashlytics (#48) 2024-04-30 17:27:44 -04:00
Patrick Honkonen
b597a2fb62 Update label for OTP type input field (#71) 2024-04-30 17:14:43 -04:00
Patrick Honkonen
ea55cbc914 Convert digits input to stepper (#70) 2024-04-29 22:19:29 -04:00
Vince Grassia
86d8a2ed8d DEVOPS-1952 - Update Gradle validation action (#69) 2024-04-29 12:33:58 -06:00
renovate[bot]
4bfe787f01 [deps]: Update gh minor (#65)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-29 09:48:36 -04:00
Patrick Honkonen
c0b04694d9 Release prep and refinement (#64) 2024-04-27 14:49:06 -04:00
Patrick Honkonen
dd4a0a502d Add About section to settings (#63) 2024-04-26 14:13:38 -04:00
Patrick Honkonen
1eb4a9770e Update empty list screen text to omit sync references (#62) 2024-04-26 14:00:05 -04:00
Patrick Honkonen
165ae77113 Allow fallback to device credential when biometrics fails (#61) 2024-04-26 12:31:03 -04:00
Patrick Honkonen
dad060e8c1 Increase spacing in tutorial slide content (#60) 2024-04-26 11:37:32 -04:00
Patrick Honkonen
75fb200eaf Remove bottom nav bar when relaunching tutorial (#59) 2024-04-26 11:17:47 -04:00
Patrick Honkonen
2bd0df2910 Adjust top app bar (#58) 2024-04-26 11:02:18 -04:00
Patrick Honkonen
2b6fe1b28a Increase spacing around Help header (#57) 2024-04-26 10:22:18 -04:00
Patrick Honkonen
f39669e615 Display correct icons when app overrides system theme. (#56) 2024-04-25 16:48:54 -05:00
Patrick Honkonen
1f0881f74e Make issuer required and account name optional (#55) 2024-04-25 17:17:15 -04:00
Patrick Honkonen
cb158b0947 Update toast message when a code is added (#53) 2024-04-25 16:48:00 -04:00
Patrick Honkonen
3adc43683a Display dark mode asset for empty vault (#54) 2024-04-25 13:40:17 -04:00
Patrick Honkonen
3ae4c72b46 Create dedicated unlock screen (#52) 2024-04-25 08:42:04 -05:00
Patrick Honkonen
7e93c1a74b Fix routing on tutorial completion (#51) 2024-04-24 19:29:48 -04:00
Patrick Honkonen
f191f02296 Allow users to enable biometric unlock from settings (#44) 2024-04-24 08:40:54 -05:00
Patrick Honkonen
9e86332c5e Cache build output separate from gradle cache (#49) 2024-04-24 10:53:21 +02:00
Patrick Honkonen
d85904748e Correct tutorial screen behavior during rotation (#45) 2024-04-24 01:23:43 -04:00
Patrick Honkonen
5167b2c491 Flip name and key fields in manual entry screen (#46) 2024-04-24 05:05:13 +00:00
Patrick Honkonen
6b88bcf02f Establish infrastructure to support biometric lock and unlock (#43) 2024-04-24 00:44:46 -04:00
Patrick Honkonen
eb97a33e8e Define proguard rules for release builds (#47) 2024-04-24 00:03:04 -04:00
Patrick Honkonen
e829e1e2ca Assemble, sign, upload and publish release builds (#38) 2024-04-22 13:49:16 -04:00
Patrick Honkonen
015cbdd37a Prompt for camera permission from Add Code button (#42) 2024-04-22 10:38:14 -04:00
Patrick Honkonen
66d834c7e9 Users can export unencrypted data to JSON or CSV (#41) 2024-04-22 10:30:04 -04:00
Patrick Honkonen
066d5c5628 Remove Import button from empty item listing screen (#40) 2024-04-22 10:29:03 -04:00
Patrick Honkonen
34c547a431 Remove Sync with Bitwarden button (#39) 2024-04-21 22:07:58 -04:00
Patrick Honkonen
af1ab4c953 Remove x8bit references from project (#37) 2024-04-17 08:34:54 -04:00
Patrick Honkonen
186766960f Include app database in auto backup and restore (#36) 2024-04-16 23:29:20 -04:00
Patrick Honkonen
de02a6999d Prompt for camera permissions from item listing screen (#34) 2024-04-16 22:19:51 -05:00
Patrick Honkonen
736761ee93 Update settings tutorial label (#35) 2024-04-16 22:19:36 -05:00
Patrick Honkonen
7bad184849 Box in list item context menu (#33) 2024-04-16 09:04:42 -05:00
Patrick Honkonen
612c8e8aa3 Implement context menu on item long press (#31) 2024-04-15 20:08:26 -05:00
Patrick Honkonen
8da98f95e1 Copy auth code on item click (#28) 2024-04-15 19:39:45 -05:00
Patrick Honkonen
6d4df646af Allow backup & restore to cloud and device transfer (#32) 2024-04-15 20:18:48 -04:00
renovate[bot]
d98db6ee67 [deps]: Update gh minor (#29)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-15 16:10:17 -04:00
Patrick Honkonen
12e5314c61 Show Welcome Tutorial on first launch (#27) 2024-04-15 10:12:58 -04:00
Patrick Honkonen
b6a165aef5 Allow modification of appearance settings (#26) 2024-04-14 17:03:34 -04:00
Patrick Honkonen
6b025832d7 DIsplay base settings screen (#25) 2024-04-13 20:39:03 -04:00
Patrick Honkonen
ea58313e31 Display bottom app bar for navigation (#24) 2024-04-13 18:06:20 -04:00
Patrick Honkonen
a27002af0f Allow users to search items (#23) 2024-04-12 11:34:13 -05:00
Patrick Honkonen
8ad7c184f1 Remove View Item screen (#22) 2024-04-11 10:08:26 -04:00
Patrick Honkonen
168e662a38 Update item listing header text (#21) 2024-04-11 10:03:16 -04:00
Patrick Honkonen
a00452faf1 Edit item UI (#20) 2024-04-11 09:14:11 -04:00
Patrick Honkonen
32b0c90f17 Refactor primary data model (#19) 2024-04-09 10:01:57 -04:00
Patrick Honkonen
cd992a6994 Allow users to save items to local storage (#18) 2024-04-05 15:12:25 -05:00
renovate[bot]
38a92042de [deps]: Update kotlin (#12) 2024-04-05 13:11:17 -04:00
renovate[bot]
65263ebad9 [deps]: Update gradle minor (#11) 2024-04-05 13:03:53 -04:00
Patrick Honkonen
50530b57c6 Define local database (#17) 2024-04-05 12:49:04 -04:00
Patrick Honkonen
04a565e5a2 Include Compose compiler in kotlin renovate group (#16) 2024-04-03 18:11:20 -05:00
Patrick Honkonen
9aa091818d Display no items content when user has no items saved (#13) 2024-04-03 13:10:36 -04:00
Patrick Honkonen
6a226f21bd Correct renovate ruby manager declaration to use bundler (#15) 2024-04-03 12:39:30 -04:00
Patrick Honkonen
67d641572e Trigger checks during CI execution (#10) 2024-04-02 22:35:00 -05:00
Patrick Honkonen
a92ed17d65 QR Scanner and Manual Key Entry screens (#7) 2024-04-02 17:45:33 -04:00
Patrick Honkonen
580a0eecdd Configure Renovate to monitor Android project dependencies (#9) 2024-04-02 16:19:38 -05:00
Patrick Honkonen
d28a754ee9 Introduce Expandable floating action button (#6) 2024-04-02 10:34:13 -04:00
Matt Bishop
5fd8593095 Provide prefix for Renovate 2024-03-29 11:30:47 -04:00
Patrick Honkonen
bcaf00dc97 Change color of countdown indicator when period nears expiration (#5) 2024-03-29 00:02:01 -04:00
Matt Bishop
c012e3cb7e Disable SARIF upload until repo becomes public (#8) 2024-03-28 11:05:03 -04:00
Patrick Honkonen
4575f52fe0 Splash, Item Listing, & View Item screens (#4) 2024-03-28 09:27:33 -04:00
Matt Bishop
c01a101f83 Adjust scan permissions 2024-03-27 10:02:59 -04:00
Patrick Honkonen
8553fb3995 Set mobile dev team as default code owners (#3) 2024-03-27 10:31:20 +01:00
Patrick Honkonen
3636da5c4e Update .gitignore (#2) 2024-03-26 14:22:54 -04:00
Matt Bishop
8bd430b793 Initial commit 2024-03-26 12:09:32 -04:00
1996 changed files with 182315 additions and 29483 deletions

View File

@@ -8,4 +8,4 @@ checkmarx:
configs:
sast:
# Exclude test directories
filter: "!app/src/test/**"
filter: "**/test/**,!**/androidTest/**,!**/commonTest/**,!**/jvmTest/**,!**/jsTest/**,!**/iosTest/**"

View File

@@ -12,127 +12,20 @@ end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
guidelines = 120
# Code files
[*.{cs,csx,vb,vbx}]
indent_size = 4
# Xml project files
[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}]
indent_size = 2
# Xml config files
[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}]
indent_size = 2
# JSON files
[*.json]
indent_size = 2
# JS files
[*.{js,ts,scss,html}]
# Kotlin files
# noinspection EditorConfigKeyCorrectness
[*.{kt,kts}]
# https://pinterest.github.io/ktlint/1.0.1/rules/configuration-ktlint/#trailing-comma-on-declaration-site
ij_kotlin_allow_trailing_comma = true
# https://pinterest.github.io/ktlint/1.0.1/rules/configuration-ktlint/#trailing-comma-on-declaration-site
trailing-comma-on-declaration-site = true
# https://pinterest.github.io/ktlint/1.0.1/rules/configuration-ktlint/#trailing-comma-on-call-site
ij_kotlin_allow_trailing_comma_on_call_site = true
[*.{scss,yml}]
indent_size = 2
[*.{ts}]
quote_type = single
[*.{scss,yml,csproj}]
indent_size = 2
[*.sln]
indent_style = tab
# Dotnet code style settings:
[*.{cs,vb}]
# Sort using and Import directives with System.* appearing first
dotnet_sort_system_directives_first = true
# Avoid "this." and "Me." if not necessary
dotnet_style_qualification_for_field = false:suggestion
dotnet_style_qualification_for_property = false:suggestion
dotnet_style_qualification_for_method = false:suggestion
dotnet_style_qualification_for_event = false:suggestion
# Use language keywords instead of framework type names for type references
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
dotnet_style_predefined_type_for_member_access = true:suggestion
# Suggest more modern language features when available
dotnet_style_object_initializer = true:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_explicit_tuple_names = true:suggestion
# Prefix private members with underscore
dotnet_naming_rule.private_members_with_underscore.symbols = private_fields
dotnet_naming_rule.private_members_with_underscore.style = prefix_underscore
dotnet_naming_rule.private_members_with_underscore.severity = suggestion
dotnet_naming_symbols.private_fields.applicable_kinds = field
dotnet_naming_symbols.private_fields.applicable_accessibilities = private
dotnet_naming_style.prefix_underscore.capitalization = camel_case
dotnet_naming_style.prefix_underscore.required_prefix = _
# Async methods should have "Async" suffix
dotnet_naming_rule.async_methods_end_in_async.symbols = any_async_methods
dotnet_naming_rule.async_methods_end_in_async.style = end_in_async
dotnet_naming_rule.async_methods_end_in_async.severity = suggestion
dotnet_naming_symbols.any_async_methods.applicable_kinds = method
dotnet_naming_symbols.any_async_methods.applicable_accessibilities = *
dotnet_naming_symbols.any_async_methods.required_modifiers = async
dotnet_naming_style.end_in_async.required_prefix =
dotnet_naming_style.end_in_async.required_suffix = Async
dotnet_naming_style.end_in_async.capitalization = pascal_case
dotnet_naming_style.end_in_async.word_separator =
# Obsolete warnings, this should be removed or changed to warning once we address some of the obsolete items.
dotnet_diagnostic.CS0618.severity = suggestion
# Obsolete warnings, this should be removed or changed to warning once we address some of the obsolete items.
dotnet_diagnostic.CS0612.severity = suggestion
# Remove unnecessary using directives https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0005
dotnet_diagnostic.IDE0005.severity = warning
# CSharp code style settings:
[*.cs]
# Prefer "var" everywhere
csharp_style_var_for_built_in_types = true:suggestion
csharp_style_var_when_type_is_apparent = true:suggestion
csharp_style_var_elsewhere = true:suggestion
# Prefer method-like constructs to have a expression-body
csharp_style_expression_bodied_methods = true:none
csharp_style_expression_bodied_constructors = true:none
csharp_style_expression_bodied_operators = true:none
# Prefer property-like constructs to have an expression-body
csharp_style_expression_bodied_properties = true:none
csharp_style_expression_bodied_indexers = true:none
csharp_style_expression_bodied_accessors = true:none
# Suggest more modern language features when available
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
csharp_style_inlined_variable_declaration = true:suggestion
csharp_style_throw_expression = true:suggestion
csharp_style_conditional_delegate_call = true:suggestion
# Newline settings
csharp_new_line_before_open_brace = all
csharp_new_line_before_else = true
csharp_new_line_before_catch = true
csharp_new_line_before_finally = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_members_in_anonymous_types = true
# Namespace settings
csharp_style_namespace_declarations = file_scoped:warning
# Switch expression
dotnet_diagnostic.CS8509.severity = error # missing switch case for named enum value
dotnet_diagnostic.CS8524.severity = none # missing switch case for unnamed enum value

5
.github/CODEOWNERS vendored
View File

@@ -5,7 +5,10 @@
# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
# Default file owners.
# * @bitwarden/tech-leads
* @bitwarden/team-android @brian-livefront @david-livefront @dseverns-livefront @ahaisting-livefront @phil-livefront
# Actions and workflow changes.
.github/ @bitwarden/dept-development-mobile
# Auth
# app/src/main/java/com/x8bit/bitwarden/data/auth @bitwarden/team-auth-dev

84
.github/ISSUE_TEMPLATE/bug-bwa.yml vendored Normal file
View File

@@ -0,0 +1,84 @@
name: Authenticator Android App Bug Report
description: File a bug report
labels: [ "app:authenticator", "bug" ]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report!
Please do not submit feature requests. The [Community Forums](https://community.bitwarden.com) has a section for submitting, voting for, and discussing product feature requests.
- type: textarea
id: reproduce
attributes:
label: Steps To Reproduce
description: How can we reproduce the behavior.
value: |
1. Go to '...'
2. Click on '...'
3. Scroll down to '...'
4. Click on '...'
validations:
required: true
- type: textarea
id: expected
attributes:
label: Expected Result
description: A clear and concise description of what you expected to happen.
validations:
required: true
- type: textarea
id: actual
attributes:
label: Actual Result
description: A clear and concise description of what is happening.
validations:
required: true
- type: textarea
id: screenshots
attributes:
label: Screenshots or Videos
description: If applicable, add screenshots and/or a short video to help explain your problem.
- type: textarea
id: additional-context
attributes:
label: Additional Context
description: Add any other context about the problem here.
- type: input
id: version
attributes:
label: Build Version
description: What version of our software are you running?
validations:
required: true
- type: dropdown
id: server-region
attributes:
label: What server are you connecting to?
options:
- US
- EU
- Self-host
- N/A
validations:
required: true
- type: input
id: server-version
attributes:
label: Self-host Server Version
description: If self-hosting, what version of Bitwarden Server are you running?
- type: textarea
id: environment-details
attributes:
label: Environment Details
placeholder: |
- Device: [e.g. Pixel Tablet, Samsung Galaxy S24 ]
- OS Version: [e.g. API 32, Tiramisu ]
- type: checkboxes
id: issue-tracking-info
attributes:
label: Issue Tracking Info
description: |
Issue tracking information
options:
- label: I understand that work is tracked outside of Github. A PR will be linked to this issue should one be opened to address it, but Bitwarden doesn't use fields like "assigned", "milestone", or "project" to track progress.

View File

@@ -1,6 +1,6 @@
name: Android Bug Report
name: Password Manager Android App Bug Report
description: File a bug report
labels: [ bug ]
labels: [ "app:password-manager", "bug" ]
body:
- type: markdown
attributes:
@@ -51,6 +51,22 @@ body:
description: What version of our software are you running?
validations:
required: true
- type: dropdown
id: server-region
attributes:
label: What server are you connecting to?
options:
- US
- EU
- Self-host
- N/A
validations:
required: true
- type: input
id: server-version
attributes:
label: Self-host Server Version
description: If self-hosting, what version of Bitwarden Server are you running?
- type: textarea
id: environment-details
attributes:

View File

@@ -12,3 +12,5 @@ contact_links:
- name: Security Issues
url: https://hackerone.com/bitwarden
about: We use HackerOne to manage security disclosures.
- name: Report mobile autofill failure
url: https://docs.google.com/forms/d/e/1FAIpQLScMopHyN7KGJs8hW562VTzbIGL4KcFnx0wJcsW0GYE1BnPiGA/viewform

View File

@@ -15,10 +15,11 @@
- Contributor guidelines followed
- All formatters and local linters executed and passed
- Written new unit and / or integration tests where applicable
- Protected functional changes with optionality (feature flags)
- Used internationalization (i18n) for all UI strings
- CI builds passed
- Communicated to DevOps any deployment requirements
- Updated any necessary documentation or informed the documentation team
- Updated any necessary documentation (Confluence, contributing docs) or informed the documentation team
## 🦮 Reviewer guidelines
@@ -27,8 +28,7 @@
- 👍 (`:+1:`) or similar for great changes
- 📝 (`:memo:`) or (`:information_source:`) for notes or general info
- ❓ (`:question:`) for questions
- 🤔 (`:thinking:`) or 💭 (`:thought_balloon:`) for more open inquiry that's not quite a confirmed
issue and could potentially benefit from discussion
- 🤔 (`:thinking:`) or 💭 (`:thought_balloon:`) for more open inquiry that's not quite a confirmed issue and could potentially benefit from discussion
- 🎨 (`:art:`) for suggestions / improvements
- ❌ (`:x:`) or ⚠️ (`:warning:`) for more significant problems or concerns needing attention
- 🌱 (`:seedling:`) or ♻️ (`:recycle:`) for future improvements or indications of technical debt

2
.github/codecov.yml vendored Normal file
View File

@@ -0,0 +1,2 @@
ignore:
- "src/test/**" # Tests

View File

@@ -18,6 +18,7 @@
"description": "Kotlin and Compose dependencies that must be updated together to maintain compatibility.",
"matchPackagePatterns": [
"androidx.compose:compose-bom",
"androidx.lifecycle:*",
"org.jetbrains.kotlin.*",
"com.google.devtools.ksp"
],

View File

@@ -0,0 +1,64 @@
import sys
import subprocess
from typing import List
def create_linked_issue_comment(repo_owner: str, repo_name: str, release_name: str, release_link: str, pr_numbers: List[int]) -> str:
if len(pr_numbers) == 0:
return ""
pr_links = [f"* https://github.com/{repo_owner}/{repo_name}/pull/{pr_number}" for pr_number in pr_numbers]
return f":shipit: Pull Request(s) linked to this issue released in [{release_name}]({release_link}):\n\n"+ "\n".join(pr_links)
def comment_linked_issues_in_pr(owner: str, repo: str, pr_number: int) -> None:
"""Use GitHub CLI to comment all issues linked to a PR.
"""
linked_issues = get_linked_issues(owner, repo, pr_number)
for issue_number in linked_issues:
comment_github_issue(owner, repo, issue_number, comment)
def comment_github_issue(owner: str, repo: str, issue_number: int, comment: str) -> None:
"""Use GitHub CLI to comment on an issue.
"""
subprocess.run([
'gh', 'issue', 'comment', str(issue_number), '--body', comment, '--repo', f'{owner}/{repo}'
], check=True)
def get_linked_issues(owner: str, repo: str, pr_number: int) -> List[int]:
"""Use GitHub CLI to retrieve linked issue numbers for a PR.
"""
query = """
query ($owner: String!, $repo: String!, $pr: Int!) {
repository(owner: $owner, name: $repo) {
pullRequest(number: $pr) {
closingIssuesReferences(first: 100) {
nodes {
number
}
}
}
}
}
"""
try:
result = subprocess.run([
'gh', 'api', 'graphql',
'-F', f'owner={owner}',
'-F', f'repo={repo}',
'-F', f'pr={pr_number}',
'-f', f'query={query}',
'--jq', '.data.repository.pullRequest.closingIssuesReferences.nodes[].number'
], capture_output=True, text=True, check=True)
# Split output into lines and convert to integers
if result.stdout.strip():
return [int(num) for num in result.stdout.strip().split('\n')]
return []
except subprocess.CalledProcessError:
print(f"Error fetching linked issues for PR #{pr_number}")
return []

View File

@@ -0,0 +1,112 @@
import re
import sys
import subprocess
import json
from typing import List, Tuple
def extract_jira_tickets(line: str) -> List[str]:
# Find all Jira tickets in format ABC-123 (with any prefix/suffix)
return re.findall(r'[A-Z]+-\d+', line)
def extract_pr_numbers(line: str) -> List[str]:
# Match PR numbers from GitHub format (#123)
return re.findall(r'#(\d+)', line)
def process_line(line: str) -> str:
"""Process a single line from release notes by removing Jira tickets, conventional commit prefixes and other common patterns.
Args:
line: A single line from release notes
Returns:
Processed line with tickets and prefixes removed
Example:
>>> process_line("[ABC-123] feat(ui): Add new button")
"Add new button"
"""
original = line
# Remove Jira ticket patterns:
# line = re.sub(r'\[[A-Z]+-\d+\]', '', line) # [ABC-123] -> ""
# line = re.sub(r'[A-Z]+-\d+:\s', '', line) # ABC-123: -> ""
# line = re.sub(r'[A-Z]+-\d+\s-\s', '', line) # ABC-123 - -> ""
# Remove keywords and their variations
patterns = [
r'BACKPORT', # BACKPORT -> ""
r'[deps]:', # [deps]: -> ""
r'feat(?:\([^)]*\))?:', # feat: or feat(ui): -> ""
r'bug(?:\([^)]*\))?:', # bug: or bug(core): -> ""
r'ci(?:\([^)]*\))?:' # ci: or ci(workflow): -> ""
]
for pattern in patterns:
line = re.sub(pattern, '', line)
cleaned = line.strip()
if cleaned != original.strip():
print(f"Processed: {original.strip()} -> {cleaned}")
return cleaned
def process_file(input_file: str) -> Tuple[List[str], List[str], List[str]]:
jira_tickets: List[str] = []
pr_numbers: List[str] = []
processed_lines: List[str] = []
print("Processing file: ", input_file)
with open(input_file, 'r') as f:
for line in f:
line = line.strip()
should_process = line and not line.endswith(':')
if should_process:
tickets = extract_jira_tickets(line)
jira_tickets.extend(tickets)
prs = extract_pr_numbers(line)
pr_numbers.extend(prs)
processed_lines.append(process_line(line))
else:
processed_lines.append(line)
# Remove duplicates while preserving order
jira_tickets = list(dict.fromkeys(jira_tickets))
pr_numbers = list(dict.fromkeys(pr_numbers))
print("Jira tickets:", ",".join(jira_tickets))
print("PR numbers:", ",".join(pr_numbers))
print("Finished processing file: ", input_file)
return jira_tickets, pr_numbers, processed_lines
def save_results(jira_tickets: List[str], pr_numbers: List[str], processed_lines: List[str],
jira_file: str = 'jira_tickets.txt',
pr_file: str = 'pr_numbers.txt',
processed_file: str = 'processed_notes.txt') -> None:
with open(jira_file, 'w') as f:
f.write('\n'.join(jira_tickets))
with open(pr_file, 'w') as f:
f.write('\n'.join(pr_numbers))
with open(processed_file, 'w') as f:
f.write('\n'.join(processed_lines))
if __name__ == '__main__':
input_file = 'release_notes.txt'
jira_file = 'jira_tickets.txt'
pr_file = 'pr_numbers.txt'
processed_file = 'processed_notes.txt'
if len(sys.argv) >= 2:
input_file = sys.argv[1]
if len(sys.argv) >= 3:
jira_file = sys.argv[2]
if len(sys.argv) >= 4:
pr_file = sys.argv[3]
if len(sys.argv) >= 5:
processed_file = sys.argv[4]
jira_tickets, pr_numbers, processed_lines = process_file(input_file)
save_results(jira_tickets, pr_numbers, processed_lines, jira_file, pr_file, processed_file)

View File

@@ -0,0 +1,4 @@
[project]
name = "release-notes-processor"
description = "Process GitHub release notes to clean up formatting and extract relevant IDs."
requires-python = ">=3.13"

View File

@@ -0,0 +1,30 @@
import unittest
from linked_issues import get_linked_issues, create_linked_issue_comment
class TestLinkedIssues(unittest.TestCase):
def test_create_linked_issue_comment(self):
test_cases = [
("bitwarden", "android", "v2025.1.0", "https://github.com/bitwarden/android/releases/tag/v2025.1.0", [4696]),
("bitwarden", "android", "v2025.2.0", "https://github.com/bitwarden/android/releases/tag/v2025.2.0", [4809, 1, 2, 3]),
("bitwarden", "android", "v2025.3.0", "https://github.com/bitwarden/android/releases/tag/v2025.3.0", []),
]
for owner, repo, release_name, release_link, pr_numbers in test_cases:
with self.subTest(msg=f"Creating comment for issue in release {release_name}"):
comment = create_linked_issue_comment(owner, repo, release_name, release_link, pr_numbers)
print(comment + "\n")
def test_get_linked_issues(self):
test_cases = [
("bitwarden", "android", 4696, [4659]),
("bitwarden", "android", 4809, [])
]
for owner, repo, pr_id, expected_linked_issues in test_cases:
with self.subTest(msg=f"Testing PR #{pr_id} for {owner}/{repo}"):
result = get_linked_issues(owner, repo, pr_id)
self.assertEqual(sorted(result), sorted(expected_linked_issues))
if __name__ == '__main__':
unittest.main()

View File

@@ -0,0 +1,95 @@
import unittest
import tempfile
import os
from process_release_notes import extract_jira_tickets, extract_pr_numbers, process_line, process_file, get_linked_issues
class TestProcessReleaseNotes(unittest.TestCase):
def setUp(self):
self.test_file = tempfile.NamedTemporaryFile(delete=False)
def tearDown(self):
os.unlink(self.test_file.name)
def test_extract_jira_tickets(self):
test_cases = [
("[ABC-123] Some text", ["ABC-123"]),
("DEF-456: Some text", ["DEF-456"]),
("GHI-789 - Some text", ["GHI-789"]),
("Multiple [ABC-123] and DEF-456: tickets", ["ABC-123", "DEF-456"]),
("No tickets here", []),
("Mixed formats ABC-123 [DEF-456] GHI-789:", ["ABC-123", "DEF-456", "GHI-789"])
]
for input_text, expected in test_cases:
with self.subTest(input_text=input_text):
result = extract_jira_tickets(input_text)
self.assertEqual(result, expected)
def test_extract_pr_numbers(self):
test_cases = [
("PR #123 text", ["123"]),
("Multiple PRs #456 and #789", ["456", "789"]),
("No PR numbers", [])
]
for input_text, expected in test_cases:
with self.subTest(input_text=input_text):
result = extract_pr_numbers(input_text)
self.assertEqual(result, expected)
def test_process_line(self):
test_cases = [
("[ABC-123] BACKPORT Some text", "Some text"),
("DEF-456: feat(component): Some text", "Some text"),
("GHI-789 - bug(fix): Some text", "Some text"),
("ci: Some text", "Some text"),
("ci(workflow): Some text", "Some text"),
("feat: Direct feature", "Direct feature"),
("bug: Simple bugfix", "Simple bugfix"),
("Normal text", "Normal text")
]
for input_text, expected in test_cases:
with self.subTest(input_text=input_text):
result = process_line(input_text)
self.assertEqual(result, expected)
def test_process_file(self):
content = """
### Features:
[ABC-123] feat(comp): Feature 1 #123
DEF-456: bug(fix): Bug fix #456
GHI-789 - BACKPORT Some text #789
### Bug Fixes:
Another line without changes
"""
with open(self.test_file.name, 'w') as f:
f.write(content)
jira_tickets, pr_numbers, processed_lines = process_file(self.test_file.name)
self.assertEqual(jira_tickets, ["ABC-123", "DEF-456", "GHI-789"])
self.assertEqual(pr_numbers, ["123", "456", "789"])
self.assertEqual(processed_lines, [
'',
'### Features:',
'Feature 1 #123',
'Bug fix #456',
'Some text #789',
'',
'### Bug Fixes:',
'Another line without changes'
])
def test_get_linked_issues(self):
test_cases = [
("bitwarden", "android", 4696, [4659]),
("bitwarden", "android", 4809, [])
]
for owner, repo, pr_id, expected_linked_issues in test_cases:
with self.subTest(msg=f"Testing PR #{pr_id} for {owner}/{repo}"):
result = get_linked_issues(owner, repo, pr_id)
self.assertEqual(sorted(result), sorted(expected_linked_issues))
if __name__ == '__main__':
unittest.main()

View File

@@ -0,0 +1,289 @@
name: Build Authenticator
on:
push:
branches:
- main
workflow_dispatch:
inputs:
version-name:
description: "Optional. Version string to use, in X.Y.Z format. Overrides default in the project."
required: false
type: string
version-code:
description: "Optional. Build number to use. Overrides default of GitHub run number."
required: false
type: number
distribute-to-firebase:
description: "Optional. Distribute artifacts to Firebase."
required: false
default: false
type: boolean
publish-to-play-store:
description: "Optional. Deploy bundle artifact to Google Play Store"
required: false
default: false
type: boolean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
JAVA_VERSION: 17
jobs:
build:
name: Build Authenticator
runs-on: ubuntu-24.04
steps:
- name: Check out repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Validate Gradle wrapper
uses: gradle/actions/wrapper-validation@0bdd871935719febd78681f197cd39af5b6e16a6 # v4.2.2
- name: Cache Gradle files
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-v2-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties', '**/libs.versions.toml') }}
restore-keys: |
${{ runner.os }}-gradle-v2-
- name: Cache build output
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: |
${{ github.workspace }}/build-cache
key: ${{ runner.os }}-build-cache-${{ github.sha }}
restore-keys: |
${{ runner.os }}-build-
- name: Configure JDK
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
with:
distribution: "temurin"
java-version: ${{ env.JAVA_VERSION }}
- name: Configure Ruby
uses: ruby/setup-ruby@28c4deda893d5a96a6b2d958c5b47fc18d65c9d3 # v1.213.0
with:
bundler-cache: true
- name: Install Fastlane
run: |
gem install bundler:2.2.27
bundle config path vendor/bundle
bundle install --jobs 4 --retry 3
- name: Check Authenticator
run: bundle exec fastlane checkAuthenticator
- name: Build Authenticator
run: bundle exec fastlane buildAuthenticatorDebug
publish_playstore:
name: Publish Authenticator Play Store artifacts
needs:
- build
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
variant: ["aab", "apk"]
steps:
- name: Check out repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Configure Ruby
uses: ruby/setup-ruby@28c4deda893d5a96a6b2d958c5b47fc18d65c9d3 # v1.213.0
with:
bundler-cache: true
- name: Install Fastlane
run: |
gem install bundler:2.2.27
bundle config path vendor/bundle
bundle install --jobs 4 --retry 3
- name: Log in to Azure
uses: Azure/login@cb79c773a3cfa27f31f25eb3f677781210c9ce3d # v1.6.1
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
- name: Retrieve secrets
env:
ACCOUNT_NAME: bitwardenci
CONTAINER_NAME: mobile
run: |
mkdir -p ${{ github.workspace }}/secrets
mkdir -p ${{ github.workspace }}/keystores
az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \
--name authenticator_apk-keystore.jks --file ${{ github.workspace }}/keystores/authenticator_apk-keystore.jks --output none
az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \
--name authenticator_aab-keystore.jks --file ${{ github.workspace }}/keystores/authenticator_aab-keystore.jks --output none
az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \
--name com.bitwarden.authenticator-google-services.json --file ${{ github.workspace }}/authenticator/src/google-services.json --output none
az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \
--name com.bitwarden.authenticator.dev-google-services.json --file ${{ github.workspace }}/authenticator/src/debug/google-services.json --output none
- name: Download Firebase credentials
if : ${{ inputs.distribute-to-firebase || github.event_name == 'push' }}
env:
ACCOUNT_NAME: bitwardenci
CONTAINER_NAME: mobile
run: |
mkdir -p ${{ github.workspace }}/secrets
az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \
--name authenticator_play_firebase-creds.json --file ${{ github.workspace }}/secrets/authenticator_play_firebase-creds.json --output none
- name: Download Play Store credentials
if: ${{ inputs.publish-to-play-store }}
env:
ACCOUNT_NAME: bitwardenci
CONTAINER_NAME: mobile
run: |
mkdir -p ${{ github.workspace }}/secrets
az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \
--name authenticator_play_store-creds.json --file ${{ github.workspace }}/secrets/authenticator_play_store-creds.json --output none
- name: Verify Play Store credentials
if: ${{ inputs.publish-to-play-store }}
run: |
bundle exec fastlane run validate_play_store_json_key \
json_key:${{ github.workspace }}/secrets/authenticator_play_store-creds.json }}
- name: Validate Gradle wrapper
uses: gradle/actions/wrapper-validation@0bdd871935719febd78681f197cd39af5b6e16a6 # v4.2.2
- name: Cache Gradle files
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-v2-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties', '**/libs.versions.toml') }}
restore-keys: |
${{ runner.os }}-gradle-v2-
- name: Cache build output
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: |
${{ github.workspace }}/build-cache
key: ${{ runner.os }}-build-cache-${{ github.sha }}
restore-keys: |
${{ runner.os }}-build-
- name: Configure JDK
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
with:
distribution: "temurin"
java-version: ${{ env.JAVA_VERSION }}
- name: Increment version
run: |
DEFAULT_VERSION_CODE=$GITHUB_RUN_NUMBER
VERSION_CODE="${{ inputs.version-code || '$DEFAULT_VERSION_CODE' }}"
bundle exec fastlane setAuthenticatorBuildVersionInfo \
versionCode:$VERSION_CODE \
versionName:${{ inputs.version-name || '' }}
regex='versionName = "([^"]+)"'
if [[ "$(cat authenticator/build.gradle.kts)" =~ $regex ]]; then
VERSION_NAME="${BASH_REMATCH[1]}"
fi
echo "Version Name: ${VERSION_NAME}" >> $GITHUB_STEP_SUMMARY
echo "Version Number: $VERSION_CODE" >> $GITHUB_STEP_SUMMARY
- name: Generate release Play Store bundle
if: ${{ matrix.variant == 'aab' }}
run: |
bundle exec fastlane bundleAuthenticatorRelease \
storeFile:${{ github.workspace }}/keystores/authenticator_aab-keystore.jks \
storePassword:'${{ secrets.BWA_AAB_KEYSTORE_STORE_PASSWORD }}' \
keyAlias:authenticatorupload \
keyPassword:'${{ secrets.BWA_AAB_KEYSTORE_KEY_PASSWORD }}'
- name: Generate release Play Store APK
if: ${{ matrix.variant == 'apk' }}
run: |
bundle exec fastlane buildAuthenticatorRelease \
storeFile:${{ github.workspace }}/keystores/authenticator_apk-keystore.jks \
storePassword:'${{ secrets.BWA_APK_KEYSTORE_STORE_PASSWORD }}' \
keyAlias:bitwardenauthenticator \
keyPassword:'${{ secrets.BWA_APK_KEYSTORE_KEY_PASSWORD }}'
- name: Upload release Play Store .aab artifact
if: ${{ matrix.variant == 'aab' }}
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: com.bitwarden.authenticator.aab
path: authenticator/build/outputs/bundle/release/com.bitwarden.authenticator.aab
if-no-files-found: error
- name: Upload release .apk artifact
if: ${{ matrix.variant == 'apk' }}
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: com.bitwarden.authenticator.apk
path: authenticator/build/outputs/apk/release/com.bitwarden.authenticator.apk
if-no-files-found: error
- name: Create checksum file for Release AAB
if: ${{ matrix.variant == 'aab' }}
run: |
sha256sum "authenticator/build/outputs/bundle/release/com.bitwarden.authenticator.aab" \
> ./authenticator-android-aab-sha256.txt
- name: Create checksum for release .apk artifact
if: ${{ matrix.variant == 'apk' }}
run: |
sha256sum "authenticator/build/outputs/apk/release/com.bitwarden.authenticator.apk" \
> ./authenticator-android-apk-sha256.txt
- name: Upload .apk SHA file for release
if: ${{ matrix.variant == 'apk' }}
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: authenticator-android-apk-sha256.txt
path: ./authenticator-android-apk-sha256.txt
if-no-files-found: error
- name: Upload .aab SHA file for release
if: ${{ matrix.variant == 'aab' }}
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: authenticator-android-aab-sha256.txt
path: ./authenticator-android-aab-sha256.txt
if-no-files-found: error
- name: Install Firebase app distribution plugin
if: ${{ inputs.distribute-to-firebase || github.event_name == 'push' }}
run: bundle exec fastlane add_plugin firebase_app_distribution
- name: Publish release bundle to Firebase
if: ${{ matrix.variant == 'aab' && (inputs.distribute-to-firebase || github.event_name == 'push') }}
env:
FIREBASE_CREDS_PATH: ${{ github.workspace }}/secrets/authenticator_play_firebase-creds.json
run: |
bundle exec fastlane distributeAuthenticatorReleaseBundleToFirebase \
serviceCredentialsFile:${{ env.FIREBASE_CREDS_PATH }}
# Only publish bundles to Play Store when `publish-to-play-store` is true while building
# bundles
- name: Publish release bundle to Google Play Store
if: ${{ inputs.publish-to-play-store && matrix.variant == 'aab' }}
env:
PLAY_STORE_CREDS_FILE: ${{ github.workspace }}/secrets/authenticator_play_store-creds.json
run: |
bundle exec fastlane publishAuthenticatorReleaseToGooglePlayStore \
serviceCredentialsFile:${{ env.PLAY_STORE_CREDS_FILE }} \

View File

@@ -1,6 +1,9 @@
name: Build
on:
push:
branches:
- main
workflow_dispatch:
inputs:
version-name:
@@ -25,21 +28,22 @@ on:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
JAVA_VERSION: 17
GITHUB_ACTION_RUN_URL: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
jobs:
build:
name: Build
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
steps:
- name: Check out repo
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Validate Gradle wrapper
uses: gradle/actions/wrapper-validation@dbbdc275be76ac10734476cc723d82dfe7ec6eda # v3.4.2
uses: gradle/actions/wrapper-validation@0bdd871935719febd78681f197cd39af5b6e16a6 # v4.2.2
- name: Cache Gradle files
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: |
~/.gradle/caches
@@ -49,7 +53,7 @@ jobs:
${{ runner.os }}-gradle-v2-
- name: Cache build output
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: |
${{ github.workspace }}/build-cache
@@ -58,13 +62,13 @@ jobs:
${{ runner.os }}-build-
- name: Configure JDK
uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4.2.1
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
with:
distribution: "temurin"
java-version: ${{ env.JAVA_VERSION }}
- name: Configure Ruby
uses: ruby/setup-ruby@3783f195e29b74ae398d7caca108814bbafde90e # v1.180.1
uses: ruby/setup-ruby@28c4deda893d5a96a6b2d958c5b47fc18d65c9d3 # v1.213.0
with:
bundler-cache: true
@@ -75,27 +79,34 @@ jobs:
bundle install --jobs 4 --retry 3
- name: Check
run: bundle exec fastlane test
run: bundle exec fastlane check
- name: Build
run: bundle exec fastlane assembleDebugApks
- name: Upload test reports on failure
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
if: failure()
with:
name: test-reports
path: app/build/reports/tests/
publish_playstore:
name: Publish Play Store artifacts
needs:
- build
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
variant: ["prod", "qa"]
variant: ["prod", "dev"]
artifact: ["apk", "aab"]
steps:
- name: Check out repo
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Configure Ruby
uses: ruby/setup-ruby@3783f195e29b74ae398d7caca108814bbafde90e # v1.180.1
uses: ruby/setup-ruby@28c4deda893d5a96a6b2d958c5b47fc18d65c9d3 # v1.213.0
with:
bundler-cache: true
@@ -135,7 +146,7 @@ jobs:
--name google-services.json --file ${{ github.workspace }}/app/src/standardBeta/google-services.json --output none
- name: Download Firebase credentials
if: ${{ matrix.variant == 'prod' && inputs.distribute-to-firebase }}
if: ${{ matrix.variant == 'prod' && (inputs.distribute-to-firebase || github.event_name == 'push') }}
env:
ACCOUNT_NAME: bitwardenci
CONTAINER_NAME: mobile
@@ -146,10 +157,10 @@ jobs:
--name app_play_prod_firebase-creds.json --file ${{ github.workspace }}/secrets/app_play_prod_firebase-creds.json --output none
- name: Validate Gradle wrapper
uses: gradle/actions/wrapper-validation@dbbdc275be76ac10734476cc723d82dfe7ec6eda # v3.4.2
uses: gradle/actions/wrapper-validation@0bdd871935719febd78681f197cd39af5b6e16a6 # v4.2.2
- name: Cache Gradle files
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: |
~/.gradle/caches
@@ -159,7 +170,7 @@ jobs:
${{ runner.os }}-gradle-v2-
- name: Cache build output
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: |
${{ github.workspace }}/build-cache
@@ -168,11 +179,20 @@ jobs:
${{ runner.os }}-build-
- name: Configure JDK
uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4.2.1
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
with:
distribution: "temurin"
java-version: ${{ env.JAVA_VERSION }}
- name: Update app CI Build info
run: |
./scripts/update_app_ci_build_info.sh \
$GITHUB_REPOSITORY \
$GITHUB_REF_NAME \
$GITHUB_SHA \
$GITHUB_RUN_ID \
$GITHUB_RUN_ATTEMPT
- name: Increment version
run: |
DEFAULT_VERSION_CODE=$((11000+$GITHUB_RUN_NUMBER))
@@ -226,140 +246,142 @@ jobs:
keyAlias:bitwarden-beta \
keyPassword:${{ env.PLAY_BETA_KEY_PASSWORD }}
- name: Generate QA Play Store APKs
- name: Generate debug Play Store APKs
if: ${{ (matrix.variant != 'prod') && (matrix.artifact == 'apk') }}
run: |
bundle exec fastlane assembleDebugApks
- name: Upload release Play Store .aab artifact
if: ${{ (matrix.variant == 'prod') && (matrix.artifact == 'aab') }}
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: com.x8bit.bitwarden.aab
path: app/build/outputs/bundle/standardRelease/com.x8bit.bitwarden-standard-release.aab
path: app/build/outputs/bundle/standardRelease/com.x8bit.bitwarden.aab
if-no-files-found: error
- name: Upload beta Play Store .aab artifact
if: ${{ (matrix.variant == 'prod') && (matrix.artifact == 'aab') }}
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: com.x8bit.bitwarden.beta.aab
path: app/build/outputs/bundle/standardBeta/com.x8bit.bitwarden-standard-beta.aab
path: app/build/outputs/bundle/standardBeta/com.x8bit.bitwarden.beta.aab
if-no-files-found: error
- name: Upload release .apk artifact
if: ${{ (matrix.variant == 'prod') && (matrix.artifact == 'apk') }}
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: com.x8bit.bitwarden.apk
path: app/build/outputs/apk/standard/release/com.x8bit.bitwarden-standard-release.apk
path: app/build/outputs/apk/standard/release/com.x8bit.bitwarden.apk
if-no-files-found: error
- name: Upload beta .apk artifact
if: ${{ (matrix.variant == 'prod') && (matrix.artifact == 'apk') }}
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: com.x8bit.bitwarden.beta.apk
path: app/build/outputs/apk/standard/beta/com.x8bit.bitwarden-standard-beta.apk
path: app/build/outputs/apk/standard/beta/com.x8bit.bitwarden.beta.apk
if-no-files-found: error
# When building variants other than 'prod'
- name: Upload other .apk artifact
- name: Upload debug .apk artifact
if: ${{ (matrix.variant != 'prod') && (matrix.artifact == 'apk') }}
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: com.x8bit.bitwarden-${{ matrix.variant }}.apk
path: app/build/outputs/apk/standard/debug/com.x8bit.bitwarden-standard-debug.apk
name: com.x8bit.bitwarden.${{ matrix.variant }}.apk
path: app/build/outputs/apk/standard/debug/com.x8bit.bitwarden.dev.apk
if-no-files-found: error
- name: Create checksum for release .apk artifact
if: ${{ (matrix.variant == 'prod') && (matrix.artifact == 'apk') }}
run: |
sha256sum "app/build/outputs/apk/standard/release/com.x8bit.bitwarden-standard-release.apk" \
> ./bw-android-apk-sha256.txt
sha256sum "app/build/outputs/apk/standard/release/com.x8bit.bitwarden.apk" \
> ./com.x8bit.bitwarden.apk-sha256.txt
- name: Create checksum for beta .apk artifact
if: ${{ (matrix.variant == 'prod') && (matrix.artifact == 'apk') }}
run: |
sha256sum "app/build/outputs/apk/standard/beta/com.x8bit.bitwarden-standard-beta.apk" \
> ./bw-android-beta-apk-sha256.txt
sha256sum "app/build/outputs/apk/standard/beta/com.x8bit.bitwarden.beta.apk" \
> ./com.x8bit.bitwarden.beta.apk-sha256.txt
- name: Create checksum for release .aab artifact
if: ${{ (matrix.variant == 'prod') && (matrix.artifact == 'aab') }}
run: |
sha256sum "app/build/outputs/bundle/standardRelease/com.x8bit.bitwarden-standard-release.aab" \
> ./bw-android-aab-sha256.txt
sha256sum "app/build/outputs/bundle/standardRelease/com.x8bit.bitwarden.aab" \
> ./com.x8bit.bitwarden.aab-sha256.txt
- name: Create checksum for beta .aab artifact
if: ${{ (matrix.variant == 'prod') && (matrix.artifact == 'aab') }}
run: |
sha256sum "app/build/outputs/bundle/standardBeta/com.x8bit.bitwarden-standard-beta.aab" \
> ./bw-android-beta-aab-sha256.txt
sha256sum "app/build/outputs/bundle/standardBeta/com.x8bit.bitwarden.beta.aab" \
> ./com.x8bit.bitwarden.beta.aab-sha256.txt
- name: Create checksum for other .apk artifact
- name: Create checksum for Debug .apk artifact
if: ${{ (matrix.variant != 'prod') && (matrix.artifact == 'apk') }}
run: |
sha256sum "app/build/outputs/apk/standard/debug/com.x8bit.bitwarden-standard-debug.apk" \
> ./bw-android-${{ matrix.variant }}-apk-sha256.txt
sha256sum "app/build/outputs/apk/standard/debug/com.x8bit.bitwarden.dev.apk" \
> ./com.x8bit.bitwarden.${{ matrix.variant }}.apk-sha256.txt
- name: Upload .apk SHA file for release
if: ${{ (matrix.variant == 'prod') && (matrix.artifact == 'apk') }}
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: bw-android-apk-sha256.txt
path: ./bw-android-apk-sha256.txt
name: com.x8bit.bitwarden.apk-sha256.txt
path: ./com.x8bit.bitwarden.apk-sha256.txt
if-no-files-found: error
- name: Upload .apk SHA file for beta
if: ${{ (matrix.variant == 'prod') && (matrix.artifact == 'apk') }}
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: bw-android-beta-apk-sha256.txt
path: ./bw-android-beta-apk-sha256.txt
name: com.x8bit.bitwarden.beta.apk-sha256.txt
path: ./com.x8bit.bitwarden.beta.apk-sha256.txt
if-no-files-found: error
- name: Upload .aab SHA file for release
if: ${{ (matrix.variant == 'prod') && (matrix.artifact == 'aab') }}
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: bw-android-aab-sha256.txt
path: ./bw-android-aab-sha256.txt
name: com.x8bit.bitwarden.aab-sha256.txt
path: ./com.x8bit.bitwarden.aab-sha256.txt
if-no-files-found: error
- name: Upload .aab SHA file for beta
if: ${{ (matrix.variant == 'prod') && (matrix.artifact == 'aab') }}
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: bw-android-beta-aab-sha256.txt
path: ./bw-android-beta-aab-sha256.txt
name: com.x8bit.bitwarden.beta.aab-sha256.txt
path: ./com.x8bit.bitwarden.beta.aab-sha256.txt
if-no-files-found: error
- name: Upload .apk SHA file for other
- name: Upload .apk SHA file for debug
if: ${{ (matrix.variant != 'prod') && (matrix.artifact == 'apk') }}
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: bw-android-${{ matrix.variant }}-apk-sha256.txt
path: ./bw-android-${{ matrix.variant }}-apk-sha256.txt
name: com.x8bit.bitwarden.${{ matrix.variant }}.apk-sha256.txt
path: ./com.x8bit.bitwarden.${{ matrix.variant }}.apk-sha256.txt
if-no-files-found: error
- name: Install Firebase app distribution plugin
if: ${{ matrix.variant == 'prod' && github.ref_name == 'main' && inputs.distribute-to-firebase }}
if: ${{ matrix.variant == 'prod' && (inputs.distribute-to-firebase || github.event_name == 'push') }}
run: bundle exec fastlane add_plugin firebase_app_distribution
- name: Publish release artifacts to Firebase
if: ${{ matrix.variant == 'prod' && matrix.artifact == 'apk' && github.ref_name == 'main' && inputs.distribute-to-firebase }}
if: ${{ matrix.variant == 'prod' && matrix.artifact == 'apk' && (inputs.distribute-to-firebase || github.event_name == 'push') }}
env:
APP_PLAY_FIREBASE_CREDS_PATH: ${{ github.workspace }}/secrets/app_play_prod_firebase-creds.json
run: |
bundle exec fastlane distributeReleasePlayStoreToFirebase \
actionUrl:${{ env.GITHUB_ACTION_RUN_URL }} \
service_credentials_file:${{ env.APP_PLAY_FIREBASE_CREDS_PATH }}
- name: Publish beta artifacts to Firebase
if: ${{ (matrix.variant == 'prod' && matrix.artifact == 'apk') && github.ref_name == 'main' && inputs.distribute-to-firebase }}
if: ${{ (matrix.variant == 'prod' && matrix.artifact == 'apk') && (inputs.distribute-to-firebase || github.event_name == 'push') }}
env:
APP_PLAY_FIREBASE_CREDS_PATH: ${{ github.workspace }}/secrets/app_play_prod_firebase-creds.json
run: |
bundle exec fastlane distributeBetaPlayStoreToFirebase \
actionUrl:${{ env.GITHUB_ACTION_RUN_URL }} \
service_credentials_file:${{ env.APP_PLAY_FIREBASE_CREDS_PATH }}
- name: Verify Play Store credentials
@@ -368,20 +390,22 @@ jobs:
bundle exec fastlane run validate_play_store_json_key
- name: Publish Play Store bundle
if: ${{ matrix.variant == 'prod' && matrix.artifact == 'aab' && inputs.publish-to-play-store }}
run: bundle exec fastlane publishForInternalTesting
if: ${{ matrix.variant == 'prod' && matrix.artifact == 'aab' && (inputs.publish-to-play-store || github.ref_name == 'main') }}
run: |
bundle exec fastlane publishProdToPlayStore
bundle exec fastlane publishBetaToPlayStore
publish_fdroid:
name: Publish F-Droid artifacts
needs:
- build
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
steps:
- name: Check out repo
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Configure Ruby
uses: ruby/setup-ruby@3783f195e29b74ae398d7caca108814bbafde90e # v1.180.1
uses: ruby/setup-ruby@28c4deda893d5a96a6b2d958c5b47fc18d65c9d3 # v1.213.0
with:
bundler-cache: true
@@ -407,7 +431,7 @@ jobs:
--name app_beta_fdroid-keystore.jks --file ${{ github.workspace }}/keystores/app_beta_fdroid-keystore.jks --output none
- name: Download Firebase credentials
if: ${{ inputs.distribute-to-firebase }}
if: ${{ inputs.distribute-to-firebase || github.event_name == 'push' }}
env:
ACCOUNT_NAME: bitwardenci
CONTAINER_NAME: mobile
@@ -418,10 +442,10 @@ jobs:
--name app_fdroid_firebase-creds.json --file ${{ github.workspace }}/secrets/app_fdroid_firebase-creds.json --output none
- name: Validate Gradle wrapper
uses: gradle/actions/wrapper-validation@dbbdc275be76ac10734476cc723d82dfe7ec6eda # v3.4.2
uses: gradle/actions/wrapper-validation@0bdd871935719febd78681f197cd39af5b6e16a6 # v4.2.2
- name: Cache Gradle files
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: |
~/.gradle/caches
@@ -431,7 +455,7 @@ jobs:
${{ runner.os }}-gradle-v2-
- name: Cache build output
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: |
${{ github.workspace }}/build-cache
@@ -440,19 +464,35 @@ jobs:
${{ runner.os }}-build-
- name: Configure JDK
uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4.2.1
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
with:
distribution: "temurin"
java-version: ${{ env.JAVA_VERSION }}
- name: Update app CI Build info
run: |
./scripts/update_app_ci_build_info.sh \
$GITHUB_REPOSITORY \
$GITHUB_REF_NAME \
$GITHUB_SHA \
$GITHUB_RUN_ID \
$GITHUB_RUN_ATTEMPT
# Start from 11000 to prevent collisions with mobile build version codes
- name: Increment version
run: |
DEFAULT_VERSION_CODE=$((11000+$GITHUB_RUN_NUMBER))
VERSION_CODE="${{ inputs.version-code || '$DEFAULT_VERSION_CODE' }}"
bundle exec fastlane setBuildVersionInfo \
versionCode:${{ inputs.version-code || '$DEFAULT_VERSION_CODE' }} \
versionCode:$VERSION_CODE \
versionName:${{ inputs.version-name || '' }}
regex='versionName = "([^"]+)"'
if [[ "$(cat app/build.gradle.kts)" =~ $regex ]]; then
VERSION_NAME="${BASH_REMATCH[1]}"
fi
echo "Version Name: ${VERSION_NAME}" >> $GITHUB_STEP_SUMMARY
echo "Version Number: $VERSION_CODE" >> $GITHUB_STEP_SUMMARY
- name: Generate F-Droid artifacts
env:
FDROID_STORE_PASSWORD: ${{ secrets.FDROID_KEYSTORE_PASSWORD }}
@@ -463,7 +503,6 @@ jobs:
keyAlias:bitwarden \
keyPassword:"${{ env.FDROID_STORE_PASSWORD }}"
# Generate the F-Droid APK for publishing
- name: Generate F-Droid Beta Artifacts
env:
FDROID_BETA_KEYSTORE_PASSWORD: ${{ secrets.FDROID_BETA_KEYSTORE_PASSWORD }}
@@ -476,32 +515,52 @@ jobs:
keyPassword:"${{ env.FDROID_BETA_KEY_PASSWORD }}"
- name: Upload F-Droid .apk artifact
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: com.x8bit.bitwarden-fdroid.apk
path: app/build/outputs/apk/fdroid/release/com.x8bit.bitwarden-fdroid-release.apk
path: app/build/outputs/apk/fdroid/release/com.x8bit.bitwarden-fdroid.apk
if-no-files-found: error
- name: Create checksum for F-Droid artifact
run: |
sha256sum "app/build/outputs/apk/fdroid/release/com.x8bit.bitwarden-fdroid-release.apk" \
> ./bw-fdroid-apk-sha256.txt
sha256sum "app/build/outputs/apk/fdroid/release/com.x8bit.bitwarden-fdroid.apk" \
> ./com.x8bit.bitwarden-fdroid.apk-sha256.txt
- name: Upload F-Droid SHA file
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: bw-fdroid-apk-sha256.txt
path: ./bw-fdroid-apk-sha256.txt
name: com.x8bit.bitwarden-fdroid.apk-sha256.txt
path: ./com.x8bit.bitwarden-fdroid.apk-sha256.txt
if-no-files-found: error
- name: Upload F-Droid Beta .apk artifact
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: com.x8bit.bitwarden.beta-fdroid.apk
path: app/build/outputs/apk/fdroid/beta/com.x8bit.bitwarden.beta-fdroid.apk
if-no-files-found: error
- name: Create checksum for F-Droid Beta artifact
run: |
sha256sum "app/build/outputs/apk/fdroid/beta/com.x8bit.bitwarden.beta-fdroid.apk" \
> ./com.x8bit.bitwarden.beta-fdroid.apk-sha256.txt
- name: Upload F-Droid Beta SHA file
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: com.x8bit.bitwarden.beta-fdroid.apk-sha256.txt
path: ./com.x8bit.bitwarden.beta-fdroid.apk-sha256.txt
if-no-files-found: error
- name: Install Firebase app distribution plugin
if: ${{ github.ref_name == 'main' && inputs.distribute_to_firebase }}
if: ${{ inputs.distribute-to-firebase || github.event_name == 'push' }}
run: bundle exec fastlane add_plugin firebase_app_distribution
- name: Publish release F-Droid artifacts to Firebase
if: ${{ github.ref_name == 'main' && inputs.distribute_to_firebase }}
if: ${{ inputs.distribute-to-firebase || github.event_name == 'push' }}
env:
APP_FDROID_FIREBASE_CREDS_PATH: ${{ github.workspace }}/secrets/app_fdroid_firebase-creds.json
run: |
bundle exec fastlane distributeReleaseFDroidToFirebase \
actionUrl:${{ env.GITHUB_ACTION_RUN_URL }} \
service_credentials_file:${{ env.APP_FDROID_FIREBASE_CREDS_PATH }}

View File

@@ -0,0 +1,56 @@
name: Crowdin Sync - Authenticator
on:
workflow_dispatch:
inputs: {}
schedule:
- cron: '0 0 * * 5'
jobs:
crowdin-sync:
name: Autosync
runs-on: ubuntu-24.04
env:
_CROWDIN_PROJECT_ID: "673718"
steps:
- name: Check out repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Log in to Azure - CI Subscription
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
- name: Retrieve secrets
id: retrieve-secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@main
with:
keyvault: "bitwarden-ci"
secrets: "github-gpg-private-key, github-gpg-private-key-passphrase"
- name: Generate GH App token
uses: actions/create-github-app-token@c1a285145b9d317df6ced56c09f525b5c2b6f755 # v1.11.1
id: app-token
with:
app-id: ${{ secrets.BW_GHAPP_ID }}
private-key: ${{ secrets.BW_GHAPP_KEY }}
- name: Download translations
uses: crowdin/github-action@d1632879d4d4da358f2d040f79fa094571c9a649 # v2.5.1
env:
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
CROWDIN_API_TOKEN: ${{ secrets.CROWDIN_API_TOKEN }}
with:
config: crowdin-bwa.yml
upload_sources: false
upload_translations: false
download_translations: true
github_user_name: "bitwarden-devops-bot"
github_user_email: "106330231+bitwarden-devops-bot@users.noreply.github.com"
commit_message: "Autosync the updated translations"
localization_branch_name: crowdin-auto-sync
create_pull_request: true
pull_request_title: "Autosync Crowdin Translations"
pull_request_body: "Autosync the updated translations"
gpg_private_key: ${{ steps.retrieve-secrets.outputs.github-gpg-private-key }}
gpg_passphrase: ${{ steps.retrieve-secrets.outputs.github-gpg-private-key-passphrase }}

56
.github/workflows/crowdin-pull.yml vendored Normal file
View File

@@ -0,0 +1,56 @@
name: Crowdin Sync
on:
workflow_dispatch:
inputs: {}
schedule:
- cron: '0 0 * * 5'
jobs:
crowdin-sync:
name: Autosync
runs-on: ubuntu-24.04
env:
_CROWDIN_PROJECT_ID: "269690"
steps:
- name: Checkout repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Login to Azure - CI Subscription
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
- name: Retrieve secrets
id: retrieve-secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@main
with:
keyvault: "bitwarden-ci"
secrets: "crowdin-api-token, github-gpg-private-key, github-gpg-private-key-passphrase"
- name: Generate GH App token
uses: actions/create-github-app-token@c1a285145b9d317df6ced56c09f525b5c2b6f755 # v1.11.1
id: app-token
with:
app-id: ${{ secrets.BW_GHAPP_ID }}
private-key: ${{ secrets.BW_GHAPP_KEY }}
- name: Download translations
uses: crowdin/github-action@d1632879d4d4da358f2d040f79fa094571c9a649 # v2.5.1
env:
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }}
with:
config: crowdin.yml
upload_sources: false
upload_translations: false
download_translations: true
github_user_name: "bitwarden-devops-bot"
github_user_email: "106330231+bitwarden-devops-bot@users.noreply.github.com"
commit_message: "Autosync the updated translations"
localization_branch_name: crowdin-auto-sync
create_pull_request: true
pull_request_title: "Autosync Crowdin Translations"
pull_request_body: "Autosync the updated translations"
gpg_private_key: ${{ steps.retrieve-secrets.outputs.github-gpg-private-key }}
gpg_passphrase: ${{ steps.retrieve-secrets.outputs.github-gpg-private-key-passphrase }}

View File

@@ -0,0 +1,30 @@
name: Crowdin Push - Authenticator
on:
workflow_dispatch:
push:
branches:
- "main"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
JAVA_VERSION: 17
jobs:
crowdin-push:
name: Crowdin Push
runs-on: ubuntu-24.04
env:
_CROWDIN_PROJECT_ID: "673718"
steps:
- name: Check out repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Upload sources
uses: crowdin/github-action@d1632879d4d4da358f2d040f79fa094571c9a649 # v2.5.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CROWDIN_API_TOKEN: ${{ secrets.CROWDIN_API_TOKEN }}
with:
config: crowdin-bwa.yml
upload_sources: true
upload_translations: false

39
.github/workflows/crowdin-push.yml vendored Normal file
View File

@@ -0,0 +1,39 @@
name: Crowdin Push
on:
workflow_dispatch:
push:
branches:
- "main"
jobs:
crowdin-push:
name: Crowdin Push
runs-on: ubuntu-24.04
env:
_CROWDIN_PROJECT_ID: "269690"
steps:
- name: Check out repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Log in to Azure
uses: Azure/login@cb79c773a3cfa27f31f25eb3f677781210c9ce3d # v1.6.1
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
- name: Retrieve secrets
id: retrieve-secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@main
with:
keyvault: "bitwarden-ci"
secrets: "crowdin-api-token"
- name: Upload sources
uses: crowdin/github-action@d1632879d4d4da358f2d040f79fa094571c9a649 # v2.5.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }}
with:
config: crowdin.yml
upload_sources: true
upload_translations: false

129
.github/workflows/github-release.yml vendored Normal file
View File

@@ -0,0 +1,129 @@
name: Create GitHub Release
on:
workflow_dispatch:
inputs:
version-name:
description: 'Version Name - E.g. "2024.11.1"'
required: true
type: string
version-number:
description: 'Version Number - E.g. "123456"'
required: true
type: string
artifact-run-id:
description: 'GitHub Action Run ID containing artifacts'
required: true
type: string
draft:
description: 'Create as draft release'
type: boolean
default: true
prerelease:
description: 'Mark as pre-release'
type: boolean
default: true
make-latest:
description: 'Set as the latest release'
type: boolean
branch-protection-type:
description: 'Branch protection type'
type: choice
options:
- Branch Name
- GitHub API
default: Branch Name
env:
ARTIFACTS_PATH: artifacts
jobs:
create-release:
name: Create GitHub Release
runs-on: ubuntu-24.04
permissions:
contents: write
actions: read
steps:
- name: Check out repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
- name: Get branch from workflow run
id: get_release_branch
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ARTIFACT_RUN_ID: ${{ inputs.artifact-run-id }}
BRANCH_PROTECTION_TYPE: ${{ inputs.branch-protection-type }}
run: |
release_branch=$(gh run view $ARTIFACT_RUN_ID --json headBranch -q .headBranch)
case "$BRANCH_PROTECTION_TYPE" in
"Branch Name")
if [[ "$release_branch" != "main" && ! "$release_branch" =~ ^release/ ]]; then
echo "::error::Branch '$release_branch' is not 'main' or a release branch starting with 'release/'. Releases must be created from protected branches."
exit 1
fi
;;
"GitHub API")
#NOTE requires token with "administration:read" scope
if ! gh api "repos/${{ github.repository }}/branches/$release_branch/protection" | grep -q "required_status_checks"; then
echo "::error::Branch '$release_branch' is not protected. Releases must be created from protected branches. If that's not correct, confirm if the github token user has the 'administration:read' scope."
exit 1
fi
;;
*)
echo "::error::Unsupported branch protection type: $BRANCH_PROTECTION_TYPE"
exit 1
;;
esac
echo "release_branch=$release_branch" >> $GITHUB_OUTPUT
- name: Download artifacts
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ARTIFACT_RUN_ID: ${{ inputs.artifact-run-id }}
run: |
gh run download $ARTIFACT_RUN_ID -D $ARTIFACTS_PATH
file_count=$(find $ARTIFACTS_PATH -type f | wc -l)
echo "Downloaded $file_count file(s)."
if [ "$file_count" -gt 0 ]; then
echo "Downloaded files:"
find $ARTIFACTS_PATH -type f
fi
- name: Create Release
id: create_release
uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda # v2.2.1
with:
tag_name: "v${{ inputs.version-name }}"
name: "${{ inputs.version-name }} (${{ inputs.version-number }})"
prerelease: ${{ inputs.prerelease }}
draft: ${{ inputs.draft }}
make_latest: ${{ inputs.make-latest }}
target_commitish: ${{ steps.get_release_branch.outputs.release_branch }}
generate_release_notes: true
files: |
artifacts/**/*
- name: Update Release Description
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RELEASE_ID: ${{ steps.create_release.outputs.id }}
RELEASE_URL: ${{ steps.create_release.outputs.url }}
ARTIFACT_RUN_ID: ${{ inputs.artifact-run-id }}
run: |
# Get current release body
current_body=$(gh api /repos/${{ github.repository }}/releases/$RELEASE_ID --jq .body)
# Append build source to the end
updated_body="${current_body}
**Builds Source:** https://github.com/${{ github.repository }}/actions/runs/$ARTIFACT_RUN_ID"
# Update release
gh api --method PATCH /repos/${{ github.repository }}/releases/$RELEASE_ID \
-f body="$updated_body"
echo "# :rocket: Release ready at:" >> $GITHUB_STEP_SUMMARY
echo "$RELEASE_URL" >> $GITHUB_STEP_SUMMARY

58
.github/workflows/release-branch.yml vendored Normal file
View File

@@ -0,0 +1,58 @@
name: Cut Release Branch
on:
workflow_dispatch:
inputs:
release_type:
description: 'Release Type'
required: true
type: choice
options:
- RC
- Hotfix
jobs:
create-release-branch:
name: Create Release Branch
runs-on: ubuntu-24.04
permissions:
contents: write
steps:
- name: Check out repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
- name: Create RC Branch
if: inputs.release_type == 'RC'
env:
RC_PREFIX_DATE: "true" # replace with input if needed
run: |
if [ "$RC_PREFIX_DATE" = "true" ]; then
current_date=$(date +'%Y.%m')
branch_name="release/${current_date}-rc${{ github.run_number }}"
else
branch_name="release/rc${{ github.run_number }}"
fi
git switch main
git switch -c $branch_name
git push origin $branch_name
echo "# :cherry_blossom: RC branch: ${branch_name}" >> $GITHUB_STEP_SUMMARY
- name: Create Hotfix Branch
if: inputs.release_type == 'Hotfix'
run: |
latest_tag=$(git tag -l --sort=-creatordate | head -n 1)
if [ -z "$latest_tag" ]; then
echo "::error::No tags found in the repository"
exit 1
fi
branch_name="release/hotfix-${latest_tag}"
echo "🌿 branch name: $branch_name"
if git show-ref --verify --quiet "refs/remotes/origin/$branch_name"; then
echo "# :fire: :warning: Hotfix branch already exists: ${branch_name}" >> $GITHUB_STEP_SUMMARY
exit 0
fi
git switch -c $branch_name $latest_tag
git push origin $branch_name
echo "# :fire: Hotfix branch: ${branch_name}" >> $GITHUB_STEP_SUMMARY

View File

@@ -0,0 +1,76 @@
name: Scan Authenticator
on:
workflow_dispatch:
push:
branches:
- "main"
- "rc"
- "hotfix-rc"
pull_request_target:
types: [opened, synchronize]
jobs:
check-run:
name: Check PR run
uses: bitwarden/gh-actions/.github/workflows/check-run.yml@main
sast:
name: SAST scan
runs-on: ubuntu-24.04
needs: check-run
permissions:
contents: read
pull-requests: write
security-events: write
steps:
- name: Check out repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Scan with Checkmarx
uses: checkmarx/ast-github-action@184bf2f64f55d1c93fd6636d539edf274703e434 # 2.0.41
env:
INCREMENTAL: "${{ contains(github.event_name, 'pull_request') && '--sast-incremental' || '' }}"
with:
project_name: ${{ github.repository }}
cx_tenant: ${{ secrets.CHECKMARX_TENANT }}
base_uri: https://ast.checkmarx.net/
cx_client_id: ${{ secrets.CHECKMARX_CLIENT_ID }}
cx_client_secret: ${{ secrets.CHECKMARX_SECRET }}
additional_params: |
--report-format sarif \
--filter "state=TO_VERIFY;PROPOSED_NOT_EXPLOITABLE;CONFIRMED;URGENT" \
--output-path . ${{ env.INCREMENTAL }}
- name: Upload Checkmarx results to GitHub
uses: github/codeql-action/upload-sarif@d68b2d4edb4189fd2a5366ac14e72027bd4b37dd # v3.28.2
with:
sarif_file: cx_result.sarif
quality:
name: Quality scan
runs-on: ubuntu-24.04
needs: check-run
permissions:
contents: read
pull-requests: write
steps:
- name: Check out repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- name: Scan with SonarCloud
uses: sonarsource/sonarqube-scan-action@bfd4e558cda28cda6b5defafb9232d191be8c203 # v4.2.1
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
with:
args: >
-Dsonar.organization=${{ github.repository_owner }}
-Dsonar.projectKey=${{ github.repository_owner }}_${{ github.event.repository.name }}
-Dsonar.pullrequest.key=${{ github.event.pull_request.number }}

61
.github/workflows/scan-ci.yml vendored Normal file
View File

@@ -0,0 +1,61 @@
name: Scan Protected Branches On Push
on:
workflow_dispatch:
push:
branches:
- "main"
jobs:
sast:
name: SAST scan
runs-on: ubuntu-24.04
permissions:
contents: read
security-events: write
steps:
- name: Check out repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
- name: Scan with Checkmarx
uses: checkmarx/ast-github-action@184bf2f64f55d1c93fd6636d539edf274703e434 # 2.0.41
with:
project_name: ${{ github.repository }}
cx_tenant: ${{ secrets.CHECKMARX_TENANT }}
base_uri: https://ast.checkmarx.net/
cx_client_id: ${{ secrets.CHECKMARX_CLIENT_ID }}
cx_client_secret: ${{ secrets.CHECKMARX_SECRET }}
additional_params: |
--report-format sarif \
--filter "state=TO_VERIFY;PROPOSED_NOT_EXPLOITABLE;CONFIRMED;URGENT" \
--output-path .
- name: Upload Checkmarx results to GitHub
uses: github/codeql-action/upload-sarif@b6a472f63d85b9c78a3ac5e89422239fc15e9b3c # v3.28.1
with:
sarif_file: cx_result.sarif
quality:
name: Quality scan
runs-on: ubuntu-24.04
permissions:
contents: read
steps:
- name: Check out repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
- name: Scan with SonarCloud
uses: sonarsource/sonarqube-scan-action@bfd4e558cda28cda6b5defafb9232d191be8c203 # v4.2.1
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
with:
args: >
-Dsonar.organization=${{ github.repository_owner }}
-Dsonar.projectKey=${{ github.repository_owner }}_${{ github.event.repository.name }}
-Dsonar.pullrequest.key=${{ github.event.pull_request.number }}

View File

@@ -1,12 +1,7 @@
name: Scan
name: Scan Pull Requests
on:
workflow_dispatch:
push:
branches:
- "main"
- "rc"
- "hotfix-rc"
pull_request_target:
types: [opened, synchronize]
@@ -17,7 +12,7 @@ jobs:
sast:
name: SAST scan
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
needs: check-run
permissions:
contents: read
@@ -26,12 +21,12 @@ jobs:
steps:
- name: Check out repo
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Scan with Checkmarx
uses: checkmarx/ast-github-action@831a8d51a8a0535c0399f9c12728d8d3cc22d850 # 2.0.28
uses: checkmarx/ast-github-action@184bf2f64f55d1c93fd6636d539edf274703e434 # 2.0.41
env:
INCREMENTAL: "${{ contains(github.event_name, 'pull_request') && '--sast-incremental' || '' }}"
with:
@@ -40,3 +35,37 @@ jobs:
base_uri: https://ast.checkmarx.net/
cx_client_id: ${{ secrets.CHECKMARX_CLIENT_ID }}
cx_client_secret: ${{ secrets.CHECKMARX_SECRET }}
additional_params: |
--report-format sarif \
--filter "state=TO_VERIFY;PROPOSED_NOT_EXPLOITABLE;CONFIRMED;URGENT" \
--output-path . ${{ env.INCREMENTAL }}
- name: Upload Checkmarx results to GitHub
uses: github/codeql-action/upload-sarif@b6a472f63d85b9c78a3ac5e89422239fc15e9b3c # v3.28.1
with:
sarif_file: cx_result.sarif
quality:
name: Quality scan
runs-on: ubuntu-24.04
needs: check-run
permissions:
contents: read
pull-requests: write
steps:
- name: Check out repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- name: Scan with SonarCloud
uses: sonarsource/sonarqube-scan-action@bfd4e558cda28cda6b5defafb9232d191be8c203 # v4.2.1
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
with:
args: >
-Dsonar.organization=${{ github.repository_owner }}
-Dsonar.projectKey=${{ github.repository_owner }}_${{ github.event.repository.name }}
-Dsonar.pullrequest.key=${{ github.event.pull_request.number }}

View File

@@ -0,0 +1,82 @@
name: Test Authenticator
on:
push:
branches:
- "main"
- "rc"
- "hotfix-rc"
pull_request_target:
types: [opened, synchronize]
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
JAVA_VERSION: 17
jobs:
check-run:
name: Check PR run
uses: bitwarden/gh-actions/.github/workflows/check-run.yml@main
test:
name: Test
runs-on: ubuntu-24.04
needs: check-run
permissions:
contents: read
packages: read
pull-requests: write
steps:
- name: Check out repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Validate Gradle wrapper
uses: gradle/actions/wrapper-validation@0bdd871935719febd78681f197cd39af5b6e16a6 # v4.2.2
- name: Cache Gradle files
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-v2-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties', '**/libs.versions.toml') }}
restore-keys: |
${{ runner.os }}-gradle-v2-
- name: Cache build output
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: |
${{ github.workspace }}/build-cache
key: ${{ runner.os }}-build-cache-${{ github.sha }}
restore-keys: |
${{ runner.os }}-build-
- name: Configure Ruby
uses: ruby/setup-ruby@28c4deda893d5a96a6b2d958c5b47fc18d65c9d3 # v1.213.0
with:
bundler-cache: true
- name: Configure JDK
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
with:
distribution: "temurin"
java-version: ${{ env.JAVA_VERSION }}
- name: Install Fastlane
run: |
gem install bundler:2.2.27
bundle config path vendor/bundle
bundle install --jobs 4 --retry 3
- name: Build and test Authenticator
run: |
bundle exec fastlane checkAuthenticator
- name: Upload to codecov.io
uses: codecov/codecov-action@1e68e06f1dbfde0e4cefc87efeba9e4643565303 # v5.1.2
with:
files: authenticator/build/reports/kover/reportDebug.xml

View File

@@ -6,40 +6,33 @@ on:
- "main"
- "rc"
- "hotfix-rc"
pull_request_target:
pull_request:
types: [opened, synchronize]
merge_group:
type: [checks_requested]
workflow_dispatch:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
JAVA_VERSION: 17
_JAVA_VERSION: 17
_GITHUB_ACTION_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}/attempts/${{ github.run_attempt }}
jobs:
check-run:
name: Check PR run
uses: bitwarden/gh-actions/.github/workflows/check-run.yml@main
test:
name: Test
runs-on: ubuntu-22.04
needs: check-run
runs-on: ubuntu-24.04
permissions:
contents: read
issues: write
packages: read
pull-requests: write
steps:
- name: Check out repo
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
with:
ref: ${{ github.event.pull_request.head.sha }}
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Validate Gradle wrapper
uses: gradle/actions/wrapper-validation@dbbdc275be76ac10734476cc723d82dfe7ec6eda # v3.4.2
uses: gradle/actions/wrapper-validation@0bdd871935719febd78681f197cd39af5b6e16a6 # v4.2.2
- name: Cache Gradle files
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: |
~/.gradle/caches
@@ -49,7 +42,7 @@ jobs:
${{ runner.os }}-gradle-v2-
- name: Cache build output
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: |
${{ github.workspace }}/build-cache
@@ -58,27 +51,75 @@ jobs:
${{ runner.os }}-build-
- name: Configure Ruby
uses: ruby/setup-ruby@3783f195e29b74ae398d7caca108814bbafde90e # v1.180.1
uses: ruby/setup-ruby@28c4deda893d5a96a6b2d958c5b47fc18d65c9d3 # v1.213.0
with:
bundler-cache: true
- name: Configure JDK
uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4.2.1
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
with:
distribution: "temurin"
java-version: ${{ env.JAVA_VERSION }}
java-version: ${{ env._JAVA_VERSION }}
- name: Install Fastlane
run: |
gem install bundler:2.2.27
bundle config path vendor/bundle
bundle install --jobs 4 --retry 3
- name: Build and test
# Run checks on standard variant only because release and beta builds are not configured to
# work properly with the Compose testing library. F-Droid related tasks are also skipped as
# there is no significant code difference between the builds.
run: |
./gradlew testStandardDebug \
lintStandardDebug \
detektStandardDebug \
koverXmlReportStandardDebug
- name: Danger
env:
DANGER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: bundle exec danger
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Used in settings.gradle.kts to download the SDK from GitHub Maven Packages
run: |
bundle exec fastlane check
- name: Upload test reports
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
if: always()
with:
name: test-reports
path: |
app/build/reports/tests/
app/build/reports/kover/reportStandardDebug.xml
report:
name: Process Test Reports
needs: test
runs-on: ubuntu-24.04
permissions:
contents: read
issues: write
pull-requests: write
if: success()
steps:
- name: Download test artifacts
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
if: github.event_name == 'push' || github.event_name == 'pull_request'
with:
name: test-reports
- name: Upload to codecov.io
id: upload-to-codecov
uses: codecov/codecov-action@1e68e06f1dbfde0e4cefc87efeba9e4643565303 # v5.1.2
if: github.event_name == 'push' || github.event_name == 'pull_request'
continue-on-error: true
with:
os: linux
files: kover/reportStandardDebug.xml
fail_ci_if_error: true
- name: Comment PR if tests failed
if: steps.upload-to-codecov.outcome == 'failure' && (github.event_name == 'push' || github.event_name == 'pull_request')
env:
PR_NUMBER: ${{ github.event.number }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RUN_ACTOR: ${{ github.triggering_actor }}
run: |
echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY
echo "> Uploading code coverage report failed. Please check the \"Upload to codecov.io\" step of \"Process Test Reports\" job for more details." >> $GITHUB_STEP_SUMMARY
if [ ! -z "$PR_NUMBER" ]; then
message=$'> [!WARNING]\n> @'$RUN_ACTOR' Uploading code coverage report failed. Please check the "Upload to codecov.io" step of [Process Test Reports job]('$_GITHUB_ACTION_RUN_URL') for more details.'
gh pr comment --repo $GITHUB_REPOSITORY $PR_NUMBER --body "$message"
fi

9
.gitignore vendored
View File

@@ -25,5 +25,12 @@ user.properties
# Secrets
/keystores/*.jks
/app/src/standardDebug/google-services.json
/app/src/standardBeta/google-services.json
/app/src/standardRelease/google-services.json
/authenticator/src/google-services.json
# python
__pycache__/
*.py[cod]
*$py.class
*.so

1
.husky/pre-commit Executable file
View File

@@ -0,0 +1 @@
npx lint-staged

View File

@@ -1 +0,0 @@
shroud.reportKover 'App', 'app/build/reports/kover/reportStandardDebug.xml', 80, 80, false

View File

@@ -2,8 +2,6 @@ source "https://rubygems.org"
ruby File.read(".ruby-version").strip
gem 'danger'
gem 'danger-shroud'
gem 'fastlane'
gem 'time'

View File

@@ -5,66 +5,42 @@ GEM
base64
nkf
rexml
addressable (2.8.6)
public_suffix (>= 2.0.2, < 6.0)
addressable (2.8.7)
public_suffix (>= 2.0.2, < 7.0)
artifactory (3.0.17)
atomos (0.1.3)
aws-eventstream (1.3.0)
aws-partitions (1.944.0)
aws-sdk-core (3.197.0)
aws-partitions (1.1040.0)
aws-sdk-core (3.216.0)
aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.651.0)
aws-sigv4 (~> 1.8)
aws-partitions (~> 1, >= 1.992.0)
aws-sigv4 (~> 1.9)
jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.85.0)
aws-sdk-core (~> 3, >= 3.197.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.152.3)
aws-sdk-core (~> 3, >= 3.197.0)
aws-sdk-kms (1.97.0)
aws-sdk-core (~> 3, >= 3.216.0)
aws-sigv4 (~> 1.5)
aws-sdk-s3 (1.178.0)
aws-sdk-core (~> 3, >= 3.216.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.8)
aws-sigv4 (1.8.0)
aws-sigv4 (~> 1.5)
aws-sigv4 (1.11.0)
aws-eventstream (~> 1, >= 1.0.2)
babosa (1.0.4)
base64 (0.2.0)
claide (1.1.0)
claide-plugins (0.9.2)
cork
nap
open4 (~> 1.3)
colored (1.2)
colored2 (3.1.2)
commander (4.6.0)
highline (~> 2.0.0)
cork (0.3.0)
colored2 (~> 3.1)
danger (9.4.3)
claide (~> 1.0)
claide-plugins (>= 0.9.2)
colored2 (~> 3.1)
cork (~> 0.1)
faraday (>= 0.9.0, < 3.0)
faraday-http-cache (~> 2.0)
git (~> 1.13)
kramdown (~> 2.3)
kramdown-parser-gfm (~> 1.0)
no_proxy_fix
octokit (>= 4.0)
terminal-table (>= 1, < 4)
danger-plugin-api (1.0.0)
danger (> 2.0)
danger-shroud (0.0.7)
danger-plugin-api (~> 1.0)
nokogiri
date (3.3.4)
date (3.4.1)
declarative (0.0.20)
digest-crc (0.6.5)
rake (>= 12.0.0, < 14.0.0)
domain_name (0.6.20240107)
dotenv (2.8.1)
emoji_regex (3.2.3)
excon (0.110.0)
faraday (1.10.3)
excon (0.112.0)
faraday (1.10.4)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
faraday-excon (~> 1.1)
@@ -82,20 +58,18 @@ GEM
faraday-em_http (1.0.0)
faraday-em_synchrony (1.0.0)
faraday-excon (1.1.0)
faraday-http-cache (2.5.1)
faraday (>= 0.8)
faraday-httpclient (1.0.1)
faraday-multipart (1.0.4)
multipart-post (~> 2)
faraday-net_http (1.0.1)
faraday-multipart (1.1.0)
multipart-post (~> 2.0)
faraday-net_http (1.0.2)
faraday-net_http_persistent (1.2.0)
faraday-patron (1.0.0)
faraday-rack (1.0.0)
faraday-retry (1.0.3)
faraday_middleware (1.2.0)
faraday_middleware (1.2.1)
faraday (~> 1.0)
fastimage (2.3.1)
fastlane (2.221.0)
fastimage (2.4.0)
fastlane (2.226.0)
CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.8, < 3.0.0)
artifactory (~> 3.0)
@@ -111,6 +85,7 @@ GEM
faraday-cookie_jar (~> 0.0.6)
faraday_middleware (~> 1.0)
fastimage (>= 2.1.0, < 3.0.0)
fastlane-sirp (>= 1.0.0)
gh_inspector (>= 1.1.2, < 2.0.0)
google-apis-androidpublisher_v3 (~> 0.3)
google-apis-playcustomapp_v1 (~> 0.1)
@@ -134,15 +109,14 @@ GEM
tty-spinner (>= 0.8.0, < 1.0.0)
word_wrap (~> 1.0.0)
xcodeproj (>= 1.13.0, < 2.0.0)
xcpretty (~> 0.3.0)
xcpretty (~> 0.4.0)
xcpretty-travis-formatter (>= 0.0.3, < 2.0.0)
fastlane-plugin-firebase_app_distribution (0.9.1)
fastlane-plugin-firebase_app_distribution (0.10.0)
google-apis-firebaseappdistribution_v1 (~> 0.3.0)
google-apis-firebaseappdistribution_v1alpha (~> 0.2.0)
fastlane-sirp (1.0.0)
sysrandom (~> 1.0)
gh_inspector (1.1.3)
git (1.19.1)
addressable (~> 2.8)
rchardet (~> 1.8)
google-apis-androidpublisher_v3 (0.54.0)
google-apis-core (>= 0.11.0, < 2.a)
google-apis-core (0.11.3)
@@ -163,7 +137,7 @@ GEM
google-apis-core (>= 0.11.0, < 2.a)
google-apis-storage_v1 (0.31.0)
google-apis-core (>= 0.11.0, < 2.a)
google-cloud-core (1.7.0)
google-cloud-core (1.7.1)
google-cloud-env (>= 1.0, < 3.a)
google-cloud-errors (~> 1.0)
google-cloud-env (1.6.0)
@@ -184,54 +158,34 @@ GEM
os (>= 0.9, < 2.0)
signet (>= 0.16, < 2.a)
highline (2.0.3)
http-cookie (1.0.6)
http-cookie (1.0.8)
domain_name (~> 0.5)
httpclient (2.8.3)
jmespath (1.6.2)
json (2.7.2)
jwt (2.8.1)
json (2.9.1)
jwt (2.10.1)
base64
kramdown (2.4.0)
rexml
kramdown-parser-gfm (1.1.0)
kramdown (~> 2.0)
mini_magick (4.13.1)
mini_magick (4.13.2)
mini_mime (1.1.5)
mini_portile2 (2.8.7)
multi_json (1.15.0)
multipart-post (2.4.1)
nanaimo (0.3.0)
nap (1.1.0)
nanaimo (0.4.0)
naturally (2.2.1)
nkf (0.2.0)
no_proxy_fix (0.1.2)
nokogiri (1.16.6)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
octokit (9.1.0)
faraday (>= 1, < 3)
sawyer (~> 0.9)
open4 (1.3.4)
optparse (0.5.0)
optparse (0.6.0)
os (1.1.4)
plist (3.7.1)
public_suffix (5.1.1)
racc (1.8.0)
plist (3.7.2)
public_suffix (6.0.1)
rake (13.2.1)
rchardet (1.8.0)
representable (3.2.0)
declarative (< 0.1.0)
trailblazer-option (>= 0.1.1, < 0.2.0)
uber (< 0.2.0)
retriable (3.1.2)
rexml (3.2.9)
strscan
rouge (2.0.7)
rexml (3.4.0)
rouge (3.28.0)
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
sawyer (0.9.2)
addressable (>= 2.3.5)
faraday (>= 0.17.3, < 3)
rubyzip (2.4.1)
security (0.1.5)
signet (0.19.0)
addressable (~> 2.8)
@@ -241,11 +195,11 @@ GEM
simctl (1.6.10)
CFPropertyList
naturally
strscan (3.1.0)
sysrandom (1.0.5)
terminal-notifier (2.0.0)
terminal-table (3.0.2)
unicode-display_width (>= 1.1.1, < 3)
time (0.3.0)
time (0.4.1)
date
trailblazer-option (0.1.2)
tty-cursor (0.7.1)
@@ -253,17 +207,17 @@ GEM
tty-spinner (0.9.3)
tty-cursor (~> 0.7)
uber (0.1.0)
unicode-display_width (2.5.0)
unicode-display_width (2.6.0)
word_wrap (1.0.0)
xcodeproj (1.24.0)
xcodeproj (1.27.0)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
colored2 (~> 3.1)
nanaimo (~> 0.3.0)
rexml (~> 3.2.4)
xcpretty (0.3.0)
rouge (~> 2.0.7)
nanaimo (~> 0.4.0)
rexml (>= 3.3.6, < 4.0)
xcpretty (0.4.0)
rouge (~> 3.28.0)
xcpretty-travis-formatter (1.0.1)
xcpretty (~> 0.2, >= 0.0.7)
@@ -271,8 +225,6 @@ PLATFORMS
ruby
DEPENDENCIES
danger
danger-shroud
fastlane
fastlane-plugin-firebase_app_distribution
time

61
README-bwa.md Normal file
View File

@@ -0,0 +1,61 @@
[![Github Workflow build on main](https://github.com/bitwarden/authenticator-android/actions/workflows/build-authenticator.yml/badge.svg?branch=main)](https://github.com/bitwarden/authenticator-android/actions/workflows/build-authenticator.yml?query=branch:main)
[![Join the chat at https://gitter.im/bitwarden/Lobby](https://badges.gitter.im/bitwarden/Lobby.svg)](https://gitter.im/bitwarden/Lobby)
# Bitwarden Authenticator Android App
<a href="https://play.google.com/store/apps/details?id=com.bitwarden.authenticator" target="_blank"><img alt="Get it on Google Play" src="https://imgur.com/YQzmZi9.png" width="153" height="46"></a>
Bitwarden Authenticator allows you easily store and generate two-factor authentication codes on your device. The Bitwarden Authenticator Android application is written in Kotlin.
<img src="https://raw.githubusercontent.com/bitwarden/brand/master/screenshots/authenticator-android-codes.png" alt="" width="325" height="650" />
## Compatibility
- **Minimum SDK**: 28
- **Target SDK**: 34
- **Device Types Supported**: Phone and Tablet
- **Orientations Supported**: Portrait and Landscape
## Setup
1. Clone the repository:
```sh
$ git clone https://github.com/bitwarden/authenticator-android
```
2. Create a `user.properties` file in the root directory of the project and add the following properties:
- `gitHubToken`: A "classic" Github Personal Access Token (PAT) with the `read:packages` scope (ex: `gitHubToken=gph_xx...xx`). These can be generated by going to the [Github tokens page](https://github.com/settings/tokens). See [the Github Packages user documentation concerning authentication](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-gradle-registry#authenticating-to-github-packages) for more details.
3. Setup the code style formatter:
All code must follow the guidelines described in the [Code Style Guidelines document](docs/STYLE_AND_BEST_PRACTICES.md). To aid in adhering to these rules, all contributors should apply `docs/bitwarden-style.xml` as their code style scheme. In IntelliJ / Android Studio:
- Navigate to `Preferences > Editor > Code Style`.
- Hit the `Manage` button next to `Scheme`.
- Select `Import`.
- Find the `bitwarden-style.xml` file in the project's `docs/` directory.
- Import "from" `BitwardenStyle` "to" `BitwardenStyle`.
- Hit `Apply` and `OK` to save the changes and exit Preferences.
Note that in some cases you may need to restart Android Studio for the changes to take effect.
All code should be formatted before submitting a pull request. This can be done manually but it can also be helpful to create a macro with a custom keyboard binding to auto-format when saving. In Android Studio on OS X:
- Select `Edit > Macros > Start Macro Recording`
- Select `Code > Optimize Imports`
- Select `Code > Reformat Code`
- Select `File > Save All`
- Select `Edit > Macros > Stop Macro Recording`
This can then be mapped to a set of keys by navigating to `Android Studio > Preferences` and editing the macro under `Keymap` (ex : shift + command + s).
Please avoid mixing formatting and logical changes in the same commit/PR. When possible, fix any large formatting issues in a separate PR before opening one to make logical changes to the same code. This helps others focus on the meaningful code changes when reviewing the code.
## Contribute
Code contributions are welcome! Please commit any pull requests against the `main` branch. Learn more about how to contribute by reading the [Contributing Guidelines](https://contributing.bitwarden.com/contributing/). Check out the [Contributing Documentation](https://contributing.bitwarden.com/) for how to get started with your first contribution.
Security audits and feedback are welcome. Please open an issue or email us privately if the report is sensitive in nature. You can read our security policy in the [`SECURITY.md`](SECURITY.md) file.

View File

@@ -8,8 +8,8 @@
## Compatibility
- **Minimum SDK**: 28
- **Target SDK**: 34
- **Minimum SDK**: 29
- **Target SDK**: 35
- **Device Types Supported**: Phone and Tablet
- **Orientations Supported**: Portrait and Landscape
@@ -25,6 +25,7 @@
2. Create a `user.properties` file in the root directory of the project and add the following properties:
- `gitHubToken`: A "classic" Github Personal Access Token (PAT) with the `read:packages` scope (ex: `gitHubToken=gph_xx...xx`). These can be generated by going to the [Github tokens page](https://github.com/settings/tokens). See [the Github Packages user documentation concerning authentication](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-gradle-registry#authenticating-to-github-packages) for more details.
- `localSdk`: A boolean value to determine if the SDK should be loaded from the local maven artifactory (ex: `localSdk=true`). This is particularly useful when developing new SDK capabilities. Review [Linking SDK to clients](https://contributing.bitwarden.com/getting-started/sdk/#linking-the-sdk-to-clients) for more details.
3. Setup the code style formatter:
@@ -131,6 +132,11 @@ The following is a list of all third-party dependencies included as part of the
- https://github.com/firebase/firebase-android-sdk
- Purpose: SDK for crash and non-fatal error reporting. (**NOTE:** This dependency is not included in builds distributed via F-Droid.)
- License: Apache 2.0
- **Google Play Reviews**
- https://developer.android.com/reference/com/google/android/play/core/release-notes
- Purpose: On standard builds provide an interface to add a review for the password manager application in Google Play.
- License: Apache 2.0
- **Glide**
- https://github.com/bumptech/glide
@@ -167,6 +173,11 @@ The following is a list of all third-party dependencies included as part of the
- Purpose: A networking layer interface.
- License: Apache 2.0
- **Timber**
- https://github.com/JakeWharton/timber
- Purpose: Extensible logging library for Android.
- License: Apache 2.0
- **zxcvbn4j**
- https://github.com/nulab/zxcvbn4j
- Purpose: Password strength estimation.
@@ -210,16 +221,6 @@ The following is a list of additional third-party dependencies used as part of t
The following is a list of additional third-party dependencies used as part of the CI/CD workflows. These are not present in the final packaged application.
- **Danger**
- https://github.com/danger/danger
- Purpose: Provides a system for enforcing common Pull Request rules.
- License: MIT
- **Danger Shroud**
- https://github.com/livefront/danger-shroud
- Purpose: A Danger plugin for enforcing code coverage via Kover / Jacoco.
- License: Apache 2.0
- **Fastlane**
- https://fastlane.tools/
- Purpose: Automates building, signing, and distributing applications.

View File

@@ -1,21 +1,32 @@
Bitwarden believes that working with security researchers across the globe is crucial to keeping our users safe. If you believe you've found a security issue in our product or service, we encourage you to please submit a report through our [HackerOne Program](https://hackerone.com/bitwarden/). We welcome working with you to resolve the issue promptly. Thanks in advance!
Bitwarden believes that working with security researchers across the globe is crucial to keeping our
users safe. If you believe you've found a security issue in our product or service, we encourage you
to please submit a report through our [HackerOne Program](https://hackerone.com/bitwarden/). We
welcome working with you to resolve the issue promptly. Thanks in advance!
# Disclosure Policy
- Let us know as soon as possible upon discovery of a potential security issue, and we'll make every effort to quickly resolve the issue.
- Provide us a reasonable amount of time to resolve the issue before any disclosure to the public or a third-party. We may publicly disclose the issue before resolving it, if appropriate.
- Make a good faith effort to avoid privacy violations, destruction of data, and interruption or degradation of our service. Only interact with accounts you own or with explicit permission of the account holder.
- If you would like to encrypt your report, please use the PGP key with long ID `0xDE6887086F892325FEC04CC0D847525B6931381F` (available in the public keyserver pool).
- Let us know as soon as possible upon discovery of a potential security issue, and we'll make every
effort to quickly resolve the issue.
- Provide us a reasonable amount of time to resolve the issue before any disclosure to the public or
a third-party. We may publicly disclose the issue before resolving it, if appropriate.
- Make a good faith effort to avoid privacy violations, destruction of data, and interruption or
degradation of our service. Only interact with accounts you own or with explicit permission of the
account holder.
- If you would like to encrypt your report, please use the PGP key with long ID
`0xDE6887086F892325FEC04CC0D847525B6931381F` (available in the public keyserver pool).
While researching, we'd like to ask you to refrain from:
- Denial of service
- Spamming
- Social engineering (including phishing) of Bitwarden staff or contractors
- Any physical attempts against Bitwarden property or data centers
- Denial of service
- Spamming
- Social engineering (including phishing) of Bitwarden staff or contractors
- Any physical attempts against Bitwarden property or data centers
# We want to help you!
If you have something that you feel is close to exploitation, or if you'd like some information regarding the internal API, or generally have any questions regarding the app that would help in your efforts, please email us at https://bitwarden.com/contact and ask for that information. As stated above, Bitwarden wants to help you find issues, and is more than willing to help.
If you have something that you feel is close to exploitation, or if you'd like some information
regarding the internal API, or generally have any questions regarding the app that would help in
your efforts, please email us at https://bitwarden.com/contact and ask for that information. As
stated above, Bitwarden wants to help you find issues, and is more than willing to help.
Thank you for helping keep Bitwarden and our users safe!

View File

@@ -1,7 +1,12 @@
import com.android.build.gradle.internal.api.BaseVariantOutputImpl
import com.android.utils.cxx.io.removeExtensionIfPresent
import com.google.firebase.crashlytics.buildtools.gradle.tasks.InjectMappingFileIdTask
import com.google.firebase.crashlytics.buildtools.gradle.tasks.UploadMappingFileTask
import com.google.gms.googleservices.GoogleServicesTask
import dagger.hilt.android.plugin.util.capitalize
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import java.io.FileInputStream
import java.util.Properties
plugins {
alias(libs.plugins.android.application)
@@ -17,6 +22,27 @@ plugins {
alias(libs.plugins.kotlinx.kover)
alias(libs.plugins.ksp)
alias(libs.plugins.google.services)
alias(libs.plugins.sonarqube)
}
/**
* Loads local user-specific build properties that are not checked into source control.
*/
val userProperties = Properties().apply {
val buildPropertiesFile = File(rootDir, "user.properties")
if (buildPropertiesFile.exists()) {
FileInputStream(buildPropertiesFile).use { load(it) }
}
}
/**
* Loads CI-specific build properties that are not checked into source control.
*/
val ciProperties = Properties().apply {
val ciPropsFile = File(rootDir, "ci.properties")
if (ciPropsFile.exists()) {
FileInputStream(ciPropsFile).use { load(it) }
}
}
android {
@@ -28,7 +54,7 @@ android {
minSdk = libs.versions.minSdk.get().toInt()
targetSdk = libs.versions.targetSdk.get().toInt()
versionCode = 1
versionName = "2024.06.00"
versionName = "2024.9.0"
setProperty("archivesBaseName", "com.x8bit.bitwarden")
@@ -38,6 +64,12 @@ android {
}
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
buildConfigField(
type = "String",
name = "CI_INFO",
value = "${ciProperties.getOrDefault("ci.info", "\"local\"")}"
)
}
androidResources {
@@ -60,12 +92,23 @@ android {
signingConfig = signingConfigs.getByName("debug")
isDebuggable = true
isMinifyEnabled = false
buildConfigField(type = "boolean", name = "HAS_DEBUG_MENU", value = "true")
buildConfigField(type = "boolean", name = "HAS_LOGS_ENABLED", value = "true")
}
// Beta and Release variants are identical except beta has a different package name
create("beta") {
initWith(buildTypes.getByName("release"))
applicationIdSuffix = ".beta"
isDebuggable = false
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
buildConfigField(type = "boolean", name = "HAS_DEBUG_MENU", value = "false")
buildConfigField(type = "boolean", name = "HAS_LOGS_ENABLED", value = "false")
}
release {
isDebuggable = false
@@ -74,6 +117,9 @@ android {
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
buildConfigField(type = "boolean", name = "HAS_DEBUG_MENU", value = "false")
buildConfigField(type = "boolean", name = "HAS_LOGS_ENABLED", value = "false")
}
}
@@ -88,6 +134,39 @@ android {
}
}
applicationVariants.all {
val bundlesDir = "${layout.buildDirectory.get()}/outputs/bundle"
outputs
.mapNotNull { it as? BaseVariantOutputImpl }
.forEach { output ->
val fileNameWithoutExtension = when (flavorName) {
"fdroid" -> "$applicationId-$flavorName"
"standard" -> "$applicationId"
else -> output.outputFileName.removeExtensionIfPresent(".apk")
}
// Set the APK output filename.
output.outputFileName = "$fileNameWithoutExtension.apk"
val variantName = name
val renameTaskName = "rename${variantName.capitalize()}AabFiles"
tasks.register(renameTaskName) {
group = "build"
description = "Renames the bundle files for $variantName variant"
doLast {
renameFile(
"$bundlesDir/$variantName/$namespace-$flavorName-${buildType.name}.aab",
"$fileNameWithoutExtension.aab",
)
}
}
// Force renaming task to execute after the variant is built.
tasks
.getByName("bundle${variantName.capitalize()}")
.finalizedBy(renameTaskName)
}
}
compileOptions {
sourceCompatibility(libs.versions.jvmTarget.get())
targetCompatibility(libs.versions.jvmTarget.get())
@@ -107,6 +186,12 @@ android {
unitTests.isIncludeAndroidResources = true
unitTests.isReturnDefaultValues = true
}
lint {
disable += listOf(
"MissingTranslation",
"ExtraTranslation",
)
}
}
kotlin {
@@ -115,11 +200,22 @@ kotlin {
}
}
configurations.all {
resolutionStrategy.dependencySubstitution {
if ((userProperties["localSdk"] as String?).toBoolean()) {
substitute(module("com.bitwarden:sdk-android"))
.using(module("com.bitwarden:sdk-android:LOCAL"))
}
}
}
dependencies {
fun standardImplementation(dependencyNotation: Any) {
add("standardImplementation", dependencyNotation)
}
implementation(files("libs/authenticatorbridge-1.0.0-release.aar"))
implementation(libs.androidx.activity.compose)
implementation(libs.androidx.appcompat)
implementation(libs.androidx.autofill)
@@ -161,6 +257,7 @@ dependencies {
implementation(platform(libs.square.retrofit.bom))
implementation(libs.square.retrofit)
implementation(libs.square.retrofit.kotlinx.serialization)
implementation(libs.timber)
implementation(libs.zxing.zxing.core)
// For now we are restricted to running Compose tests for debug builds only
@@ -171,6 +268,7 @@ dependencies {
standardImplementation(libs.google.firebase.cloud.messaging)
standardImplementation(platform(libs.google.firebase.bom))
standardImplementation(libs.google.firebase.crashlytics)
standardImplementation(libs.google.play.review)
testImplementation(libs.androidx.compose.ui.test)
testImplementation(libs.google.hilt.android.testing)
@@ -204,6 +302,7 @@ kover {
annotatedBy(
// Compose previews
"androidx.compose.ui.tooling.preview.Preview",
"androidx.compose.ui.tooling.preview.PreviewScreenSizes",
// Manually excluded classes/files/etc.
"com.x8bit.bitwarden.data.platform.annotation.OmitFromCoverage",
)
@@ -226,6 +325,7 @@ kover {
"*_*Factory\$*",
"*.Hilt_*",
"*_HiltModules",
"*_HiltModules*",
"*_HiltModules\$*",
"*_Impl",
"*_Impl\$*",
@@ -249,7 +349,11 @@ kover {
tasks {
getByName("check") {
// Add detekt with type resolution to check
dependsOn("detektMain")
dependsOn("detekt")
}
getByName("sonar") {
dependsOn("check")
}
withType<io.gitlab.arturbosch.detekt.Detekt>().configureEach {
@@ -264,15 +368,43 @@ tasks {
maxHeapSize = "2g"
maxParallelForks = Runtime.getRuntime().availableProcessors()
jvmArgs = jvmArgs.orEmpty() + "-XX:+UseParallelGC"
android.sourceSets["main"].res.srcDirs("src/test/res")
}
}
afterEvaluate {
// Disable Fdroid-specific tasks that we want to exclude
val tasks = tasks.withType<GoogleServicesTask>() +
val fdroidTasksToDisable = tasks.withType<GoogleServicesTask>() +
tasks.withType<InjectMappingFileIdTask>() +
tasks.withType<UploadMappingFileTask>()
tasks
fdroidTasksToDisable
.filter { it.name.contains("Fdroid") }
.forEach { it.enabled = false }
}
sonar {
properties {
property("sonar.projectKey", "bitwarden_android")
property("sonar.organization", "bitwarden")
property("sonar.host.url", "https://sonarcloud.io")
property("sonar.sources", "app/src/")
property("sonar.tests", "app/src/")
property("sonar.test.inclusions", "app/src/test/")
property("sonar.exclusions", "app/src/test/")
}
}
private fun renameFile(path: String, newName: String) {
val originalFile = File(path)
if (!originalFile.exists()) {
println("File $originalFile does not exist!")
return
}
val newFile = File(originalFile.parentFile, newName)
if (originalFile.renameTo(newFile)) {
println("Renamed $originalFile to $newFile")
} else {
throw RuntimeException("Failed to rename $originalFile to $newFile")
}
}

Binary file not shown.

View File

@@ -6,6 +6,10 @@
# we keep it here.
-keep class com.bitwarden.** { *; }
# The Android Verifier component must be kept because it looks like dead code. Proguard is unable to
# see any JNI usage, so our rules must manually opt into keeping it.
-keep, includedescriptorclasses class org.rustls.platformverifier.** { *; }
################################################################################
# Bitwarden Models
################################################################################

View File

@@ -0,0 +1,68 @@
{
"formatVersion": 1,
"database": {
"version": 1,
"identityHash": "f40d7a933b2f353d8d5b5ca619f28e24",
"entities": [
{
"tableName": "organization_events",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `user_id` TEXT NOT NULL, `organization_event_type` TEXT NOT NULL, `cipher_id` TEXT, `date` INTEGER NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "userId",
"columnName": "user_id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "organizationEventType",
"columnName": "organization_event_type",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "cipherId",
"columnName": "cipher_id",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "date",
"columnName": "date",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
},
"indices": [
{
"name": "index_organization_events_user_id",
"unique": false,
"columnNames": [
"user_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_organization_events_user_id` ON `${TABLE_NAME}` (`user_id`)"
}
],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'f40d7a933b2f353d8d5b5ca619f28e24')"
]
}
}

View File

@@ -0,0 +1,256 @@
{
"formatVersion": 1,
"database": {
"version": 4,
"identityHash": "f7906c69e0a2c065d4d3be140fc721b6",
"entities": [
{
"tableName": "ciphers",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `user_id` TEXT NOT NULL, `cipher_type` TEXT NOT NULL, `cipher_json` TEXT NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "userId",
"columnName": "user_id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "cipherType",
"columnName": "cipher_type",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "cipherJson",
"columnName": "cipher_json",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"id"
]
},
"indices": [
{
"name": "index_ciphers_user_id",
"unique": false,
"columnNames": [
"user_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_ciphers_user_id` ON `${TABLE_NAME}` (`user_id`)"
}
],
"foreignKeys": []
},
{
"tableName": "collections",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `user_id` TEXT NOT NULL, `organization_id` TEXT NOT NULL, `should_hide_passwords` INTEGER NOT NULL, `name` TEXT NOT NULL, `external_id` TEXT, `read_only` INTEGER NOT NULL, `manage` INTEGER NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "userId",
"columnName": "user_id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "organizationId",
"columnName": "organization_id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "shouldHidePasswords",
"columnName": "should_hide_passwords",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "externalId",
"columnName": "external_id",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "isReadOnly",
"columnName": "read_only",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "canManage",
"columnName": "manage",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"id"
]
},
"indices": [
{
"name": "index_collections_user_id",
"unique": false,
"columnNames": [
"user_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_collections_user_id` ON `${TABLE_NAME}` (`user_id`)"
}
],
"foreignKeys": []
},
{
"tableName": "domains",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_id` TEXT NOT NULL, `domains_json` TEXT NOT NULL, PRIMARY KEY(`user_id`))",
"fields": [
{
"fieldPath": "userId",
"columnName": "user_id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "domainsJson",
"columnName": "domains_json",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"user_id"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "folders",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `user_id` TEXT NOT NULL, `name` TEXT, `revision_date` INTEGER NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "userId",
"columnName": "user_id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "revisionDate",
"columnName": "revision_date",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"id"
]
},
"indices": [
{
"name": "index_folders_user_id",
"unique": false,
"columnNames": [
"user_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_folders_user_id` ON `${TABLE_NAME}` (`user_id`)"
}
],
"foreignKeys": []
},
{
"tableName": "sends",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `user_id` TEXT NOT NULL, `send_type` TEXT NOT NULL, `send_json` TEXT NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "userId",
"columnName": "user_id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "sendType",
"columnName": "send_type",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "sendJson",
"columnName": "send_json",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"id"
]
},
"indices": [
{
"name": "index_sends_user_id",
"unique": false,
"columnNames": [
"user_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_sends_user_id` ON `${TABLE_NAME}` (`user_id`)"
}
],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'f7906c69e0a2c065d4d3be140fc721b6')"
]
}
}

View File

@@ -0,0 +1,256 @@
{
"formatVersion": 1,
"database": {
"version": 5,
"identityHash": "ee697e71290c92fe5b607d0b7665481b",
"entities": [
{
"tableName": "ciphers",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `user_id` TEXT NOT NULL, `cipher_type` TEXT NOT NULL, `cipher_json` TEXT NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "userId",
"columnName": "user_id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "cipherType",
"columnName": "cipher_type",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "cipherJson",
"columnName": "cipher_json",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"id"
]
},
"indices": [
{
"name": "index_ciphers_user_id",
"unique": false,
"columnNames": [
"user_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_ciphers_user_id` ON `${TABLE_NAME}` (`user_id`)"
}
],
"foreignKeys": []
},
{
"tableName": "collections",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `user_id` TEXT NOT NULL, `organization_id` TEXT NOT NULL, `should_hide_passwords` INTEGER NOT NULL, `name` TEXT NOT NULL, `external_id` TEXT, `read_only` INTEGER NOT NULL, `manage` INTEGER NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "userId",
"columnName": "user_id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "organizationId",
"columnName": "organization_id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "shouldHidePasswords",
"columnName": "should_hide_passwords",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "externalId",
"columnName": "external_id",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "isReadOnly",
"columnName": "read_only",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "canManage",
"columnName": "manage",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"id"
]
},
"indices": [
{
"name": "index_collections_user_id",
"unique": false,
"columnNames": [
"user_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_collections_user_id` ON `${TABLE_NAME}` (`user_id`)"
}
],
"foreignKeys": []
},
{
"tableName": "domains",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_id` TEXT NOT NULL, `domains_json` TEXT, PRIMARY KEY(`user_id`))",
"fields": [
{
"fieldPath": "userId",
"columnName": "user_id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "domainsJson",
"columnName": "domains_json",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"user_id"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "folders",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `user_id` TEXT NOT NULL, `name` TEXT, `revision_date` INTEGER NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "userId",
"columnName": "user_id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "revisionDate",
"columnName": "revision_date",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"id"
]
},
"indices": [
{
"name": "index_folders_user_id",
"unique": false,
"columnNames": [
"user_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_folders_user_id` ON `${TABLE_NAME}` (`user_id`)"
}
],
"foreignKeys": []
},
{
"tableName": "sends",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `user_id` TEXT NOT NULL, `send_type` TEXT NOT NULL, `send_json` TEXT NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "userId",
"columnName": "user_id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "sendType",
"columnName": "send_type",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "sendJson",
"columnName": "send_json",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"id"
]
},
"indices": [
{
"name": "index_sends_user_id",
"unique": false,
"columnNames": [
"user_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_sends_user_id` ON `${TABLE_NAME}` (`user_id`)"
}
],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'ee697e71290c92fe5b607d0b7665481b')"
]
}
}

View File

@@ -0,0 +1,256 @@
{
"formatVersion": 1,
"database": {
"version": 6,
"identityHash": "ee158c483edfe5102504670f3d9845d4",
"entities": [
{
"tableName": "ciphers",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `user_id` TEXT NOT NULL, `cipher_type` TEXT NOT NULL, `cipher_json` TEXT NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "userId",
"columnName": "user_id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "cipherType",
"columnName": "cipher_type",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "cipherJson",
"columnName": "cipher_json",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"id"
]
},
"indices": [
{
"name": "index_ciphers_user_id",
"unique": false,
"columnNames": [
"user_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_ciphers_user_id` ON `${TABLE_NAME}` (`user_id`)"
}
],
"foreignKeys": []
},
{
"tableName": "collections",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `user_id` TEXT NOT NULL, `organization_id` TEXT NOT NULL, `should_hide_passwords` INTEGER NOT NULL, `name` TEXT NOT NULL, `external_id` TEXT, `read_only` INTEGER NOT NULL, `manage` INTEGER, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "userId",
"columnName": "user_id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "organizationId",
"columnName": "organization_id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "shouldHidePasswords",
"columnName": "should_hide_passwords",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "externalId",
"columnName": "external_id",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "isReadOnly",
"columnName": "read_only",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "canManage",
"columnName": "manage",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"id"
]
},
"indices": [
{
"name": "index_collections_user_id",
"unique": false,
"columnNames": [
"user_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_collections_user_id` ON `${TABLE_NAME}` (`user_id`)"
}
],
"foreignKeys": []
},
{
"tableName": "domains",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_id` TEXT NOT NULL, `domains_json` TEXT, PRIMARY KEY(`user_id`))",
"fields": [
{
"fieldPath": "userId",
"columnName": "user_id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "domainsJson",
"columnName": "domains_json",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"user_id"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "folders",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `user_id` TEXT NOT NULL, `name` TEXT, `revision_date` INTEGER NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "userId",
"columnName": "user_id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "revisionDate",
"columnName": "revision_date",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"id"
]
},
"indices": [
{
"name": "index_folders_user_id",
"unique": false,
"columnNames": [
"user_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_folders_user_id` ON `${TABLE_NAME}` (`user_id`)"
}
],
"foreignKeys": []
},
{
"tableName": "sends",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `user_id` TEXT NOT NULL, `send_type` TEXT NOT NULL, `send_json` TEXT NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "userId",
"columnName": "user_id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "sendType",
"columnName": "send_type",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "sendJson",
"columnName": "send_json",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"id"
]
},
"indices": [
{
"name": "index_sends_user_id",
"unique": false,
"columnNames": [
"user_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_sends_user_id` ON `${TABLE_NAME}` (`user_id`)"
}
],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'ee158c483edfe5102504670f3d9845d4')"
]
}
}

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- For beta variant, we don't have a matching variant of the Bitwarden Authenticator app.
Therefore, we leave the known app cert null here so that no clients can connect to
AuthenticatorBridgeService in the beta variant. If later another variant of the
Bitwarden Authenticator app is added, a SHA-256 digest of that variant's APK can be added here.
-->
<string-array name="known_authenticator_app_certs" />
</resources>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
<shortcut
android:enabled="true"
android:icon="@mipmap/ic_generator_shortcut"
android:shortcutId="bitwarden_password_generator"
android:shortcutLongLabel="@string/password_generator"
android:shortcutShortLabel="@string/password_generator">
<intent
android:action="android.intent.action.VIEW"
android:data="bitwarden://password_generator"
android:targetClass="com.x8bit.bitwarden.MainActivity"
android:targetPackage="com.x8bit.bitwarden.beta" />
</shortcut>
<shortcut
android:enabled="true"
android:icon="@mipmap/ic_vault_shortcut"
android:shortcutId="bitwarden_my_vault"
android:shortcutLongLabel="@string/my_vault"
android:shortcutShortLabel="@string/my_vault">
<intent
android:action="android.intent.action.VIEW"
android:data="bitwarden://my_vault"
android:targetClass="com.x8bit.bitwarden.MainActivity"
android:targetPackage="com.x8bit.bitwarden.beta" />
</shortcut>
</shortcuts>

View File

@@ -3,15 +3,6 @@
xmlns:tools="http://schemas.android.com/tools">
<application tools:ignore="MissingApplicationIcon">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="com.x8bit.bitwarden.fido2.ACTION_CREATE_PASSKEY" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<!-- Disable Crashlytics for debug builds -->
<meta-data
android:name="firebase_crashlytics_collection_enabled"

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="known_authenticator_app_certs">
<!-- This is the SHA-256 digest for the Authenticator App debug variant:-->
<item>13144ab52af797a88c2fe292674461ef1715e0e1e4f5f538f63f1c174696f476</item>
</string-array>
</resources>

View File

@@ -1,14 +0,0 @@
package com.x8bit.bitwarden.data.platform.manager
import com.x8bit.bitwarden.data.platform.datasource.disk.legacy.LegacyAppCenterMigrator
import com.x8bit.bitwarden.data.platform.repository.SettingsRepository
/**
* CrashLogsManager implementation for F-droid flavor builds.
*/
class CrashLogsManagerImpl(
settingsRepository: SettingsRepository,
legacyAppCenterMigrator: LegacyAppCenterMigrator,
) : CrashLogsManager {
override var isEnabled: Boolean = true
}

View File

@@ -0,0 +1,27 @@
package com.x8bit.bitwarden.data.platform.manager
import com.x8bit.bitwarden.BuildConfig
import com.x8bit.bitwarden.data.platform.datasource.disk.legacy.LegacyAppCenterMigrator
import com.x8bit.bitwarden.data.platform.repository.SettingsRepository
import com.x8bit.bitwarden.data.platform.repository.model.Environment
import timber.log.Timber
/**
* [LogsManager] implementation for F-droid flavor builds.
*/
class LogsManagerImpl(
settingsRepository: SettingsRepository,
legacyAppCenterMigrator: LegacyAppCenterMigrator,
) : LogsManager {
init {
if (BuildConfig.HAS_LOGS_ENABLED) {
Timber.plant(Timber.DebugTree())
}
}
override var isEnabled: Boolean = false
override fun setUserData(userId: String?, environmentType: Environment.Type) = Unit
override fun trackNonFatalException(throwable: Throwable) = Unit
}

View File

@@ -0,0 +1,12 @@
package com.x8bit.bitwarden.ui.platform.manager.review
import android.app.Activity
/**
* No-op implementation of [AppReviewManager] for F-Droid builds.
*/
class AppReviewManagerImpl(
activity: Activity,
) : AppReviewManager {
override fun promptForReview() = Unit
}

View File

@@ -15,6 +15,20 @@
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.READ_USER_DICTIONARY"/>
<!-- Protect access to AuthenticatorBridgeService using this custom permission.
Note that each build type uses a different value for knownCerts.
This in effect means that the only application that can connect to the debug/release/etc
variant AuthenticatorBridgeService is the debug/release/etc variant Bitwarden Authenticator
app. -->
<permission
android:name="${applicationId}.permission.AUTHENTICATOR_BRIDGE_SERVICE"
android:knownCerts="@array/known_authenticator_app_certs"
android:label="Bitwarden Bridge"
android:protectionLevel="signature|knownSigner"
tools:targetApi="s" />
<application
android:name=".BitwardenApplication"
@@ -55,8 +69,49 @@
<data android:mimeType="video/*" />
<data android:mimeType="text/*" />
</intent-filter>
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" />
<data android:host="vault.bitwarden.com" />
<data android:host="vault.bitwarden.eu" />
<data android:host="*.bitwarden.pw" />
<data android:pathPattern="/redirect-connector.*" />
</intent-filter>
<intent-filter>
<action android:name="com.x8bit.bitwarden.fido2.ACTION_CREATE_PASSKEY" />
<action android:name="com.x8bit.bitwarden.fido2.ACTION_GET_PASSKEY" />
<action android:name="com.x8bit.bitwarden.fido2.ACTION_UNLOCK_ACCOUNT" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="otpauth" />
<data android:host="totp" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="bitwarden" />
</intent-filter>
</activity>
<activity
android:name=".AccessibilityActivity"
android:exported="false"
android:launchMode="singleTop"
android:noHistory="true"
android:theme="@android:style/Theme.NoDisplay" />
<activity
android:name=".AutofillTotpCopyActivity"
android:exported="true"
@@ -141,6 +196,47 @@
</intent-filter>
</service>
<!--
The AccessibilityService name below refers to the legacy Xamarin app's service name. This
must always match in order for the app to properly query if it is providing accessibility
services.
-->
<!--suppress AndroidDomInspection -->
<service
android:name="com.x8bit.bitwarden.Accessibility.AccessibilityService"
android:exported="true"
android:label="@string/app_name"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
tools:ignore="MissingClass">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="@xml/accessibility_service" />
</service>
<!--
The CredentialProviderService name below refers to the legacy Xamarin app's service name.
This must always match in order for the app to properly query if it is providing credential
services.
-->
<!--suppress AndroidDomInspection -->
<service
android:name="com.x8bit.bitwarden.Autofill.CredentialProviderService"
android:enabled="true"
android:exported="true"
android:label="@string/bitwarden"
android:permission="android.permission.BIND_CREDENTIAL_PROVIDER_SERVICE"
tools:ignore="MissingClass">
<intent-filter>
<action android:name="android.service.credentials.CredentialProviderService" />
</intent-filter>
<meta-data
android:name="android.credentials.provider"
android:resource="@xml/provider" />
</service>
<!-- This is required to support in-app language picker in Android 12 (API 32) and below -->
<service
android:name="androidx.appcompat.app.AppLocalesMetadataHolderService"
@@ -150,12 +246,85 @@
android:name="autoStoreLocales"
android:value="true" />
</service>
<!--
The AutofillTileService name below refers to the legacy Xamarin app's service name.
This must always match in order for the app to properly query if it is providing autofill
tile services.
-->
<!--suppress AndroidDomInspection -->
<service
android:name="com.x8bit.bitwarden.AutofillTileService"
android:exported="true"
android:icon="@drawable/ic_notification"
android:label="@string/autofill"
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"
tools:ignore="MissingClass">
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>
</service>
<!--
The GeneratorTileService name below refers to the legacy Xamarin app's service name.
This must always match in order for the app to properly query if it is providing generator
tile services.
-->
<!--suppress AndroidDomInspection -->
<service
android:name="com.x8bit.bitwarden.GeneratorTileService"
android:exported="true"
android:icon="@drawable/ic_generator"
android:label="@string/password_generator"
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"
tools:ignore="MissingClass">
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>
</service>
<!--
The MyVaultTileService name below refers to the legacy Xamarin app's service name.
This must always match in order for the app to properly query if it is providing vault
tile services.
-->
<!--suppress AndroidDomInspection -->
<service
android:name="com.x8bit.bitwarden.MyVaultTileService"
android:exported="true"
android:icon="@drawable/ic_notification"
android:label="@string/my_vault"
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"
tools:ignore="MissingClass">
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>
</service>
<meta-data
android:name="android.content.APP_RESTRICTIONS"
android:resource="@xml/app_restrictions" />
<service
android:name="com.x8bit.bitwarden.data.platform.service.AuthenticatorBridgeService"
android:exported="true"
android:permission="${applicationId}.permission.AUTHENTICATOR_BRIDGE_SERVICE" />
</application>
<queries>
<intent>
<action android:name="android.media.action.IMAGE_CAPTURE" />
</intent>
<intent>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
</intent>
<!-- To Query Chrome Beta: -->
<package android:name="com.chrome.beta" />
<!-- To Query Chrome Stable: -->
<package android:name="com.android.chrome" />
</queries>
</manifest>

View File

@@ -0,0 +1,90 @@
{
"apps": [
{
"type": "android",
"info": {
"package_name": "io.github.forkmaintainers.iceraven",
"signatures": [
{
"build": "release",
"cert_fingerprint_sha256": "9C:0D:22:37:9F:48:7B:70:A4:F9:F8:BE:C0:17:3C:F9:1A:16:44:F0:8F:93:38:5B:5B:78:2C:E3:76:60:BA:81"
}
]
}
},
{
"type": "android",
"info": {
"package_name": "net.quetta.browser",
"signatures": [
{
"build": "release",
"cert_fingerprint_sha256": "BE:FE:E7:31:12:6A:A5:6E:7E:FD:AE:AF:5E:F3:FA:EA:44:1C:19:CC:E0:CA:EC:42:6B:65:BB:F8:2C:59:46:80"
}
]
}
},
{
"type": "android",
"info": {
"package_name": "org.chromium.chrome",
"signatures": [
{
"build": "release",
"cert_fingerprint_sha256": "A8:56:48:50:79:BC:B3:57:BF:BE:69:BA:19:A9:BA:43:CD:0A:D9:AB:22:67:52:C7:80:B6:88:8A:FD:48:21:6B"
}
]
}
},
{
"type": "android",
"info": {
"package_name": "org.cromite.cromite",
"signatures": [
{
"build": "release",
"cert_fingerprint_sha256": "63:3F:A4:1D:82:11:D6:D0:91:6A:81:9B:89:66:8C:6D:E9:2E:64:23:2D:A6:7F:9D:16:FD:81:C3:B7:E9:23:FF"
}
]
}
},
{
"type": "android",
"info": {
"package_name": "org.ironfoxoss.ironfox",
"signatures": [
{
"build": "release",
"cert_fingerprint_sha256": "C5:E2:91:B5:A5:71:F9:C8:CD:9A:97:99:C2:C9:4E:02:EC:97:03:94:88:93:F2:CA:75:6D:67:B9:42:04:F9:04"
}
]
}
},
{
"type": "android",
"info": {
"package_name": "org.mozilla.fenix",
"signatures": [
{
"build": "release",
"cert_fingerprint_sha256": "50:04:77:90:88:E7:F9:88:D5:BC:5C:C5:F8:79:8F:EB:F4:F8:CD:08:4A:1B:2A:46:EF:D4:C8:EE:4A:EA:F2:11"
}
]
}
},
{
"type": "android",
"info": {
"package_name": "org.mozilla.fennec_fdroid",
"signatures": [
{
"build": "release",
"cert_fingerprint_sha256": "06:66:53:58:EF:D8:BA:05:BE:23:6A:47:A1:2C:B0:95:8D:7D:75:DD:93:9D:77:C2:B3:1F:53:98:53:7E:BD:C5"
}
]
}
}
]
}

View File

@@ -475,7 +475,102 @@
}
]
}
},
{
"type": "android",
"info": {
"package_name": "com.talonsec.talon",
"signatures": [
{
"build": "release",
"cert_fingerprint_sha256": "A3:66:03:44:A6:F6:AF:CA:81:8C:BF:43:96:A2:3C:CF:D5:ED:7A:78:1B:B4:A3:D1:85:03:01:E2:F4:6D:23:83"
},
{
"build": "release",
"cert_fingerprint_sha256": "E2:A5:64:74:EA:23:7B:06:67:B6:F5:2C:DC:E9:04:5E:24:88:3B:AE:D0:82:59:9A:A2:DF:0B:60:3A:CF:6A:3B"
}
]
}
},
{
"type": "android",
"info": {
"package_name": "com.talonsec.talon_beta",
"signatures": [
{
"build": "release",
"cert_fingerprint_sha256": "F5:86:62:7A:32:C8:9F:E6:7E:00:6D:B1:8C:34:31:9E:01:7F:B3:B2:BE:D6:9D:01:01:B7:F9:43:E7:7C:48:AE"
},
{
"build": "release",
"cert_fingerprint_sha256": "9A:A1:25:D5:E5:5E:3F:B0:DE:96:72:D9:A9:5D:04:65:3F:49:4A:1E:C3:EE:76:1E:94:C4:4E:5D:2F:65:8E:2F"
}
]
}
},
{
"type": "android",
"info": {
"package_name": "com.duckduckgo.mobile.android.debug",
"signatures": [
{
"build": "release",
"cert_fingerprint_sha256": "C4:F0:9E:2B:D7:25:AD:F5:AD:92:0B:A2:80:27:66:AC:16:4A:C1:53:B3:EA:9E:08:48:B0:57:98:37:F7:6A:29"
}
]
}
},
{
"type": "android",
"info": {
"package_name": "com.duckduckgo.mobile.android",
"signatures": [
{
"build": "release",
"cert_fingerprint_sha256": "BB:7B:B3:1C:57:3C:46:A1:DA:7F:C5:C5:28:A6:AC:F4:32:10:84:56:FE:EC:50:81:0C:7F:33:69:4E:B3:D2:D4"
}
]
}
},
{
"type": "android",
"info": {
"package_name": "com.naver.whale",
"signatures": [
{
"build": "release",
"cert_fingerprint_sha256": "0B:8B:85:23:BB:4A:EF:FA:34:6E:4B:DD:4F:BF:7D:19:34:50:56:9A:A1:4A:AA:D4:AD:FD:94:A3:F7:B2:27:BB"
}
]
}
},
{
"type": "android",
"info": {
"package_name": "com.fido.fido2client",
"signatures": [
{
"build": "release",
"cert_fingerprint_sha256": "FC:98:DA:E6:3A:D3:96:26:C8:C6:7F:BE:83:F2:F0:6F:74:93:2A:9C:D1:46:B9:2C:EC:FC:6A:04:7A:90:43:86"
}
]
}
},
{
"type": "android",
"info": {
"package_name": "com.heytap.browser",
"signatures": [
{
"build": "release",
"cert_fingerprint_sha256": "AF:F8:A7:49:CF:0E:7D:75:44:65:D0:FB:FA:7B:8D:0C:64:5E:22:5C:10:C6:E2:32:AD:A0:D9:74:88:36:B8:E5"
},
{
"build": "release",
"cert_fingerprint_sha256": "A8:FE:A4:CA:FB:93:32:DA:26:B8:E6:81:08:17:C1:DA:90:A5:03:0E:35:A6:0A:79:E0:6C:90:97:AA:C6:A4:42"
}
]
}
}
]
}

View File

@@ -0,0 +1,17 @@
package com.x8bit.bitwarden
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.x8bit.bitwarden.data.platform.annotation.OmitFromCoverage
/**
* An activity to be launched and then immediately closed so that the OS Shade can be collapsed
* after the user clicks on the Autofill Quick Tile.
*/
@OmitFromCoverage
class AccessibilityActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
finish()
}
}

View File

@@ -3,37 +3,62 @@ package com.x8bit.bitwarden
import android.app.Service
import android.content.Intent
import android.os.Build
import androidx.annotation.Keep
import androidx.core.app.AppComponentFactory
import com.x8bit.bitwarden.data.autofill.BitwardenAutofillService
import com.x8bit.bitwarden.data.autofill.accessibility.BitwardenAccessibilityService
import com.x8bit.bitwarden.data.autofill.fido2.BitwardenFido2ProviderService
import com.x8bit.bitwarden.data.platform.annotation.OmitFromCoverage
private const val LEGACY_AUTOFILL_SERVICE_NAME = "com.x8bit.bitwarden.Autofill.AutofillService"
private const val LEGACY_CREDENTIAL_SERVICE_NAME =
"com.x8bit.bitwarden.Autofill.CredentialProviderService"
import com.x8bit.bitwarden.data.tiles.BitwardenAutofillTileService
import com.x8bit.bitwarden.data.tiles.BitwardenGeneratorTileService
import com.x8bit.bitwarden.data.tiles.BitwardenVaultTileService
/**
* A factory class that allows us to intercept when a manifest element is being instantiated
* and modify various characteristics before initialization.
*/
@Suppress("unused")
@Keep
@OmitFromCoverage
class BitwardenAppComponentFactory : AppComponentFactory() {
/**
* Used to intercept when the [BitwardenAutofillService] or [BitwardenFido2ProviderService] is
* being instantiated and modify which service is created. This is required because the
* [className] used in the manifest must match the legacy Xamarin app service name but the
* service name in this app is different.
* Used to intercept when certain legacy services are being instantiated and modify which
* service is created. This is required because the [className] used in the manifest must match
* the legacy Xamarin app service name but the service name in this app is different.
*
* Services currently being managed:
* * [BitwardenAccessibilityService]
* * [BitwardenAutofillService]
* * [BitwardenAutofillTileService]
* * [BitwardenFido2ProviderService]
* * [BitwardenVaultTileService]
* * [BitwardenGeneratorTileService]
*/
override fun instantiateServiceCompat(
cl: ClassLoader,
className: String,
intent: Intent?,
): Service = when (className) {
LEGACY_ACCESSIBILITY_SERVICE_NAME -> {
super.instantiateServiceCompat(
cl,
BitwardenAccessibilityService::class.java.name,
intent,
)
}
LEGACY_AUTOFILL_SERVICE_NAME -> {
super.instantiateServiceCompat(cl, BitwardenAutofillService::class.java.name, intent)
}
LEGACY_AUTOFILL_TILE_SERVICE_NAME -> {
super.instantiateServiceCompat(
cl,
BitwardenAutofillTileService::class.java.name,
intent,
)
}
LEGACY_CREDENTIAL_SERVICE_NAME -> {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
super.instantiateServiceCompat(
@@ -48,6 +73,18 @@ class BitwardenAppComponentFactory : AppComponentFactory() {
}
}
LEGACY_VAULT_TILE_SERVICE_NAME -> {
super.instantiateServiceCompat(cl, BitwardenVaultTileService::class.java.name, intent)
}
LEGACY_GENERATOR_TILE_SERVICE_NAME -> {
super.instantiateServiceCompat(
cl,
BitwardenGeneratorTileService::class.java.name,
intent,
)
}
else -> super.instantiateServiceCompat(cl, className, intent)
}
}

View File

@@ -3,8 +3,10 @@ package com.x8bit.bitwarden
import android.app.Application
import com.x8bit.bitwarden.data.auth.manager.AuthRequestNotificationManager
import com.x8bit.bitwarden.data.platform.annotation.OmitFromCoverage
import com.x8bit.bitwarden.data.platform.manager.CrashLogsManager
import com.x8bit.bitwarden.data.platform.manager.NetworkConfigManager
import com.x8bit.bitwarden.data.platform.manager.LogsManager
import com.x8bit.bitwarden.data.platform.manager.event.OrganizationEventManager
import com.x8bit.bitwarden.data.platform.manager.network.NetworkConfigManager
import com.x8bit.bitwarden.data.platform.manager.restriction.RestrictionManager
import dagger.hilt.android.HiltAndroidApp
import javax.inject.Inject
@@ -16,12 +18,18 @@ import javax.inject.Inject
class BitwardenApplication : Application() {
// Inject classes here that must be triggered on startup but are not otherwise consumed by
// other callers.
@Inject
lateinit var logsManager: LogsManager
@Inject
lateinit var networkConfigManager: NetworkConfigManager
@Inject
lateinit var crashLogsManager: CrashLogsManager
lateinit var authRequestNotificationManager: AuthRequestNotificationManager
@Inject
lateinit var authRequestNotificationManager: AuthRequestNotificationManager
lateinit var organizationEventManager: OrganizationEventManager
@Inject
lateinit var restrictionManager: RestrictionManager
}

View File

@@ -0,0 +1,33 @@
package com.x8bit.bitwarden
/**
* The legacy name for the accessibility service.
*/
const val LEGACY_ACCESSIBILITY_SERVICE_NAME: String =
"com.x8bit.bitwarden.Accessibility.AccessibilityService"
/**
* The legacy name for the autofill service.
*/
const val LEGACY_AUTOFILL_SERVICE_NAME: String = "com.x8bit.bitwarden.Autofill.AutofillService"
/**
* The legacy name for the accessibility autofill tile service.
*/
const val LEGACY_AUTOFILL_TILE_SERVICE_NAME: String = "com.x8bit.bitwarden.AutofillTileService"
/**
* The legacy name for the credential service.
*/
const val LEGACY_CREDENTIAL_SERVICE_NAME: String =
"com.x8bit.bitwarden.Autofill.CredentialProviderService"
/**
* The legacy name for the generator tile service.
*/
const val LEGACY_GENERATOR_TILE_SERVICE_NAME: String = "com.x8bit.bitwarden.GeneratorTileService"
/**
* The legacy name for the vault tile service.
*/
const val LEGACY_VAULT_TILE_SERVICE_NAME: String = "com.x8bit.bitwarden.MyVaultTileService"

View File

@@ -2,26 +2,33 @@ package com.x8bit.bitwarden
import android.content.Intent
import android.os.Bundle
import android.view.KeyEvent
import android.view.MotionEvent
import android.view.WindowManager
import android.widget.Toast
import androidx.activity.compose.setContent
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.core.os.LocaleListCompat
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.lifecycleScope
import androidx.navigation.compose.rememberNavController
import com.x8bit.bitwarden.data.autofill.accessibility.manager.AccessibilityCompletionManager
import com.x8bit.bitwarden.data.autofill.manager.AutofillActivityManager
import com.x8bit.bitwarden.data.autofill.manager.AutofillCompletionManager
import com.x8bit.bitwarden.data.platform.annotation.OmitFromCoverage
import com.x8bit.bitwarden.data.platform.manager.util.ObserveScreenDataEffect
import com.x8bit.bitwarden.data.platform.repository.SettingsRepository
import com.x8bit.bitwarden.ui.platform.base.util.EventsEffect
import com.x8bit.bitwarden.ui.platform.composition.LocalManagerProvider
import com.x8bit.bitwarden.ui.platform.feature.debugmenu.manager.DebugMenuLaunchManager
import com.x8bit.bitwarden.ui.platform.feature.debugmenu.navigateToDebugMenuScreen
import com.x8bit.bitwarden.ui.platform.feature.rootnav.RootNavScreen
import com.x8bit.bitwarden.ui.platform.theme.BitwardenTheme
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import javax.inject.Inject
/**
@@ -39,16 +46,21 @@ class MainActivity : AppCompatActivity() {
@Inject
lateinit var autofillCompletionManager: AutofillCompletionManager
@Inject
lateinit var accessibilityCompletionManager: AccessibilityCompletionManager
@Inject
lateinit var settingsRepository: SettingsRepository
@Inject
lateinit var debugLaunchManager: DebugMenuLaunchManager
@Suppress("LongMethod")
override fun onCreate(savedInstanceState: Bundle?) {
var shouldShowSplashScreen = true
installSplashScreen().setKeepOnScreenCondition { shouldShowSplashScreen }
super.onCreate(savedInstanceState)
observeViewModelEvents()
if (savedInstanceState == null) {
mainViewModel.trySendAction(
MainAction.ReceiveFirstIntent(
@@ -57,19 +69,62 @@ class MainActivity : AppCompatActivity() {
)
}
// Within the app the language will change dynamically and will be managed
// by the OS, but we need to ensure we properly set the language when
// upgrading from older versions that handle this differently.
// Within the app the language and theme will change dynamically and will be managed by the
// OS, but we need to ensure we properly set the values when upgrading from older versions
// that handle this differently or when the activity restarts.
settingsRepository.appLanguage.localeName?.let { localeName ->
val localeList = LocaleListCompat.forLanguageTags(localeName)
AppCompatDelegate.setApplicationLocales(localeList)
}
AppCompatDelegate.setDefaultNightMode(settingsRepository.appTheme.osValue)
setContent {
val state by mainViewModel.stateFlow.collectAsStateWithLifecycle()
val navController = rememberNavController()
EventsEffect(viewModel = mainViewModel) { event ->
when (event) {
is MainEvent.CompleteAccessibilityAutofill -> {
handleCompleteAccessibilityAutofill(event)
}
is MainEvent.CompleteAutofill -> handleCompleteAutofill(event)
MainEvent.Recreate -> handleRecreate()
MainEvent.NavigateToDebugMenu -> navController.navigateToDebugMenuScreen()
is MainEvent.ShowToast -> {
Toast
.makeText(
baseContext,
event.message.invoke(resources),
Toast.LENGTH_SHORT,
)
.show()
}
is MainEvent.UpdateAppLocale -> {
AppCompatDelegate.setApplicationLocales(
LocaleListCompat.forLanguageTags(event.localeName),
)
}
is MainEvent.UpdateAppTheme -> {
AppCompatDelegate.setDefaultNightMode(event.osTheme)
}
}
}
updateScreenCapture(isScreenCaptureAllowed = state.isScreenCaptureAllowed)
LocalManagerProvider {
ObserveScreenDataEffect(
onDataUpdate = remember(mainViewModel) {
{
mainViewModel.trySendAction(
MainAction.ResumeScreenDataReceived(it),
)
}
},
)
BitwardenTheme(theme = state.theme) {
RootNavScreen(
onSplashScreenRemoved = { shouldShowSplashScreen = false },
navController = navController,
)
}
}
@@ -92,23 +147,27 @@ class MainActivity : AppCompatActivity() {
currentFocus?.clearFocus()
}
private fun observeViewModelEvents() {
mainViewModel
.eventFlow
.onEach { event ->
when (event) {
is MainEvent.CompleteAutofill -> {
handleCompleteAutofill(event)
}
override fun dispatchTouchEvent(event: MotionEvent): Boolean = debugLaunchManager
.actionOnInputEvent(event = event, action = ::sendOpenDebugMenuEvent)
.takeIf { it }
?: super.dispatchTouchEvent(event)
MainEvent.Recreate -> handleRecreate()
override fun dispatchKeyEvent(event: KeyEvent): Boolean = debugLaunchManager
.actionOnInputEvent(event = event, action = ::sendOpenDebugMenuEvent)
.takeIf { it }
?: super.dispatchKeyEvent(event)
is MainEvent.ScreenCaptureSettingChange -> {
handleScreenCaptureSettingChange(event)
}
}
}
.launchIn(lifecycleScope)
private fun sendOpenDebugMenuEvent() {
mainViewModel.trySendAction(MainAction.OpenDebugMenu)
}
private fun handleCompleteAccessibilityAutofill(
event: MainEvent.CompleteAccessibilityAutofill,
) {
accessibilityCompletionManager.completeAccessibilityAutofill(
activity = this,
cipherView = event.cipherView,
)
}
private fun handleCompleteAutofill(event: MainEvent.CompleteAutofill) {
@@ -118,15 +177,15 @@ class MainActivity : AppCompatActivity() {
)
}
private fun handleScreenCaptureSettingChange(event: MainEvent.ScreenCaptureSettingChange) {
if (event.isAllowed) {
private fun handleRecreate() {
recreate()
}
private fun updateScreenCapture(isScreenCaptureAllowed: Boolean) {
if (isScreenCaptureAllowed) {
window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
} else {
window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
}
}
private fun handleRecreate() {
recreate()
}
}

View File

@@ -5,32 +5,52 @@ import android.os.Parcelable
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.viewModelScope
import com.bitwarden.vault.CipherView
import com.x8bit.bitwarden.data.auth.manager.AddTotpItemFromAuthenticatorManager
import com.x8bit.bitwarden.data.auth.repository.AuthRepository
import com.x8bit.bitwarden.data.auth.repository.model.EmailTokenResult
import com.x8bit.bitwarden.data.auth.util.getCompleteRegistrationDataIntentOrNull
import com.x8bit.bitwarden.data.auth.util.getPasswordlessRequestDataIntentOrNull
import com.x8bit.bitwarden.data.autofill.fido2.util.getFido2CredentialRequestOrNull
import com.x8bit.bitwarden.data.autofill.accessibility.manager.AccessibilitySelectionManager
import com.x8bit.bitwarden.data.autofill.fido2.manager.Fido2CredentialManager
import com.x8bit.bitwarden.data.autofill.fido2.util.getFido2AssertionRequestOrNull
import com.x8bit.bitwarden.data.autofill.fido2.util.getFido2CreateCredentialRequestOrNull
import com.x8bit.bitwarden.data.autofill.fido2.util.getFido2GetCredentialsRequestOrNull
import com.x8bit.bitwarden.data.autofill.manager.AutofillSelectionManager
import com.x8bit.bitwarden.data.autofill.util.getAutofillSaveItemOrNull
import com.x8bit.bitwarden.data.autofill.util.getAutofillSelectionDataOrNull
import com.x8bit.bitwarden.data.platform.manager.AppResumeManager
import com.x8bit.bitwarden.data.platform.manager.SpecialCircumstanceManager
import com.x8bit.bitwarden.data.platform.manager.garbage.GarbageCollectionManager
import com.x8bit.bitwarden.data.platform.manager.model.AppResumeScreenData
import com.x8bit.bitwarden.data.platform.manager.model.CompleteRegistrationData
import com.x8bit.bitwarden.data.platform.manager.model.SpecialCircumstance
import com.x8bit.bitwarden.data.platform.repository.EnvironmentRepository
import com.x8bit.bitwarden.data.platform.repository.SettingsRepository
import com.x8bit.bitwarden.data.platform.util.isAddTotpLoginItemFromAuthenticator
import com.x8bit.bitwarden.data.vault.manager.model.VaultStateEvent
import com.x8bit.bitwarden.data.vault.repository.VaultRepository
import com.x8bit.bitwarden.ui.platform.base.BaseViewModel
import com.x8bit.bitwarden.ui.platform.base.util.Text
import com.x8bit.bitwarden.ui.platform.base.util.asText
import com.x8bit.bitwarden.ui.platform.feature.settings.appearance.model.AppTheme
import com.x8bit.bitwarden.ui.platform.manager.intent.IntentManager
import com.x8bit.bitwarden.ui.platform.util.isAccountSecurityShortcut
import com.x8bit.bitwarden.ui.platform.util.isMyVaultShortcut
import com.x8bit.bitwarden.ui.platform.util.isPasswordGeneratorShortcut
import com.x8bit.bitwarden.ui.vault.model.TotpData
import com.x8bit.bitwarden.ui.vault.util.getTotpDataOrNull
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.parcelize.Parcelize
import java.time.Clock
import javax.inject.Inject
private const val SPECIAL_CIRCUMSTANCE_KEY = "special-circumstance"
@@ -41,17 +61,24 @@ private const val SPECIAL_CIRCUMSTANCE_KEY = "special-circumstance"
@Suppress("LongParameterList", "TooManyFunctions")
@HiltViewModel
class MainViewModel @Inject constructor(
accessibilitySelectionManager: AccessibilitySelectionManager,
autofillSelectionManager: AutofillSelectionManager,
private val addTotpItemFromAuthenticatorManager: AddTotpItemFromAuthenticatorManager,
private val specialCircumstanceManager: SpecialCircumstanceManager,
private val garbageCollectionManager: GarbageCollectionManager,
private val fido2CredentialManager: Fido2CredentialManager,
private val intentManager: IntentManager,
settingsRepository: SettingsRepository,
vaultRepository: VaultRepository,
private val vaultRepository: VaultRepository,
private val authRepository: AuthRepository,
private val environmentRepository: EnvironmentRepository,
private val savedStateHandle: SavedStateHandle,
private val appResumeManager: AppResumeManager,
private val clock: Clock,
) : BaseViewModel<MainState, MainEvent, MainAction>(
MainState(
initialState = MainState(
theme = settingsRepository.appTheme,
isScreenCaptureAllowed = settingsRepository.isScreenCaptureAllowed,
),
) {
private var specialCircumstance: SpecialCircumstance?
@@ -69,6 +96,12 @@ class MainViewModel @Inject constructor(
.onEach { specialCircumstance = it }
.launchIn(viewModelScope)
accessibilitySelectionManager
.accessibilitySelectionFlow
.map { MainAction.Internal.AccessibilitySelectionReceive(it) }
.onEach(::sendAction)
.launchIn(viewModelScope)
autofillSelectionManager
.autofillSelectionFlow
.onEach { trySendAction(MainAction.Internal.AutofillSelectionReceive(it)) }
@@ -78,12 +111,16 @@ class MainViewModel @Inject constructor(
.appThemeStateFlow
.onEach { trySendAction(MainAction.Internal.ThemeUpdate(it)) }
.launchIn(viewModelScope)
settingsRepository
.appLanguageStateFlow
.map { MainEvent.UpdateAppLocale(it.localeName) }
.onEach(::sendEvent)
.launchIn(viewModelScope)
settingsRepository
.isScreenCaptureAllowedStateFlow
.onEach { isAllowed ->
sendEvent(MainEvent.ScreenCaptureSettingChange(isAllowed))
}
.map { MainAction.Internal.ScreenCaptureUpdate(it) }
.onEach(::trySendAction)
.launchIn(viewModelScope)
authRepository
@@ -108,6 +145,10 @@ class MainViewModel @Inject constructor(
.onEach {
when (it) {
is VaultStateEvent.Locked -> {
// Similar to account switching, triggering this action too soon can
// interfere with animations or navigation logic, so we will delay slightly.
@Suppress("MagicNumber")
delay(500)
trySendAction(MainAction.Internal.VaultUnlockStateChange)
}
@@ -115,25 +156,64 @@ class MainViewModel @Inject constructor(
}
}
.launchIn(viewModelScope)
// On app launch, mark all active users as having previously logged in.
// This covers any users who are active prior to this value being recorded.
viewModelScope.launch {
val userState = authRepository
.userStateFlow
.first()
userState
?.accounts
?.forEach {
settingsRepository.storeUserHasLoggedInValue(it.userId)
}
}
}
override fun handleAction(action: MainAction) {
when (action) {
is MainAction.Internal.AccessibilitySelectionReceive -> {
handleAccessibilitySelectionReceive(action)
}
is MainAction.Internal.AutofillSelectionReceive -> {
handleAutofillSelectionReceive(action)
}
is MainAction.Internal.CurrentUserStateChange -> handleCurrentUserStateChange()
is MainAction.Internal.ScreenCaptureUpdate -> handleScreenCaptureUpdate(action)
is MainAction.Internal.ThemeUpdate -> handleAppThemeUpdated(action)
is MainAction.Internal.VaultUnlockStateChange -> handleVaultUnlockStateChange()
is MainAction.ReceiveFirstIntent -> handleFirstIntentReceived(action)
is MainAction.ReceiveNewIntent -> handleNewIntentReceived(action)
MainAction.OpenDebugMenu -> handleOpenDebugMenu()
is MainAction.ResumeScreenDataReceived -> handleAppResumeDataUpdated(action)
}
}
private fun handleAppResumeDataUpdated(action: MainAction.ResumeScreenDataReceived) {
when (val data = action.screenResumeData) {
null -> appResumeManager.clearResumeScreen()
else -> appResumeManager.setResumeScreen(data)
}
}
private fun handleOpenDebugMenu() {
sendEvent(MainEvent.NavigateToDebugMenu)
}
private fun handleAccessibilitySelectionReceive(
action: MainAction.Internal.AccessibilitySelectionReceive,
) {
specialCircumstanceManager.specialCircumstance = null
sendEvent(MainEvent.CompleteAccessibilityAutofill(cipherView = action.cipherView))
}
private fun handleAutofillSelectionReceive(
action: MainAction.Internal.AutofillSelectionReceive,
) {
specialCircumstanceManager.specialCircumstance = null
sendEvent(MainEvent.CompleteAutofill(cipherView = action.cipherView))
}
@@ -141,8 +221,13 @@ class MainViewModel @Inject constructor(
recreateUiAndGarbageCollect()
}
private fun handleScreenCaptureUpdate(action: MainAction.Internal.ScreenCaptureUpdate) {
mutableStateFlow.update { it.copy(isScreenCaptureAllowed = action.isScreenCaptureEnabled) }
}
private fun handleAppThemeUpdated(action: MainAction.Internal.ThemeUpdate) {
mutableStateFlow.update { it.copy(theme = action.theme) }
sendEvent(MainEvent.UpdateAppTheme(osTheme = action.theme.osValue))
}
private fun handleVaultUnlockStateChange() {
@@ -163,6 +248,7 @@ class MainViewModel @Inject constructor(
)
}
@Suppress("LongMethod", "CyclomaticComplexMethod")
private fun handleIntent(
intent: Intent,
isFirstIntent: Boolean,
@@ -171,11 +257,39 @@ class MainViewModel @Inject constructor(
val autofillSaveItem = intent.getAutofillSaveItemOrNull()
val autofillSelectionData = intent.getAutofillSelectionDataOrNull()
val shareData = intentManager.getShareDataFromIntent(intent)
val totpData: TotpData? =
// First grab TOTP URI directly from the intent data:
intent.getTotpDataOrNull()
?: run {
// Then check to see if the intent is coming from the Authenticator app:
if (intent.isAddTotpLoginItemFromAuthenticator()) {
addTotpItemFromAuthenticatorManager.pendingAddTotpLoginItemData.also {
// Clear pending add TOTP data so it is only handled once:
addTotpItemFromAuthenticatorManager.pendingAddTotpLoginItemData = null
}
} else {
null
}
}
val hasGeneratorShortcut = intent.isPasswordGeneratorShortcut
val hasVaultShortcut = intent.isMyVaultShortcut
val fido2CredentialRequestData = intent.getFido2CredentialRequestOrNull()
val hasAccountSecurityShortcut = intent.isAccountSecurityShortcut
val fido2CreateCredentialRequestData = intent.getFido2CreateCredentialRequestOrNull()
val completeRegistrationData = intent.getCompleteRegistrationDataIntentOrNull()
val fido2CredentialAssertionRequest = intent.getFido2AssertionRequestOrNull()
val fido2GetCredentialsRequest = intent.getFido2GetCredentialsRequestOrNull()
when {
passwordlessRequestData != null -> {
authRepository.activeUserId?.let {
if (it != passwordlessRequestData.userId &&
!vaultRepository.isVaultUnlocked(it)
) {
// We only switch the account here if the current user's vault is not
// unlocked, otherwise prompt the user to allow us to change the account
// in the LoginApprovalScreen
authRepository.switchAccount(passwordlessRequestData.userId)
}
}
specialCircumstanceManager.specialCircumstance =
SpecialCircumstance.PasswordlessRequest(
passwordlessRequestData = passwordlessRequestData,
@@ -185,6 +299,10 @@ class MainViewModel @Inject constructor(
)
}
completeRegistrationData != null -> {
handleCompleteRegistrationData(completeRegistrationData)
}
autofillSaveItem != null -> {
specialCircumstanceManager.specialCircumstance =
SpecialCircumstance.AutofillSave(
@@ -202,6 +320,11 @@ class MainViewModel @Inject constructor(
)
}
totpData != null -> {
specialCircumstanceManager.specialCircumstance =
SpecialCircumstance.AddTotpLoginItem(data = totpData)
}
shareData != null -> {
specialCircumstanceManager.specialCircumstance =
SpecialCircumstance.ShareNewSend(
@@ -212,20 +335,44 @@ class MainViewModel @Inject constructor(
)
}
fido2CredentialRequestData != null -> {
fido2CreateCredentialRequestData != null -> {
// Set the user's verification status when a new FIDO 2 request is received to force
// explicit verification if the user's vault is unlocked when the request is
// received.
fido2CreateCredentialRequestData.isUserVerified
?.let { isVerified -> fido2CredentialManager.isUserVerified = isVerified }
specialCircumstanceManager.specialCircumstance =
SpecialCircumstance.Fido2Save(
fido2CredentialRequest = fido2CredentialRequestData,
fido2CreateCredentialRequest = fido2CreateCredentialRequestData,
)
// Switch accounts if the selected user is not the active user.
if (authRepository.activeUserId != null &&
authRepository.activeUserId != fido2CredentialRequestData.userId
authRepository.activeUserId != fido2CreateCredentialRequestData.userId
) {
authRepository.switchAccount(fido2CredentialRequestData.userId)
authRepository.switchAccount(fido2CreateCredentialRequestData.userId)
}
}
fido2CredentialAssertionRequest != null -> {
// If device biometric verification was performed as part of single-tap
// authentication, set the user's verification state to the device result.
// Otherwise, retain the verification state as-is.
fido2CredentialAssertionRequest.isUserVerified
?.let { isVerified -> fido2CredentialManager.isUserVerified = isVerified }
specialCircumstanceManager.specialCircumstance =
SpecialCircumstance.Fido2Assertion(
fido2AssertionRequest = fido2CredentialAssertionRequest,
)
}
fido2GetCredentialsRequest != null -> {
specialCircumstanceManager.specialCircumstance =
SpecialCircumstance.Fido2GetCredentials(
fido2GetCredentialsRequest = fido2GetCredentialsRequest,
)
}
hasGeneratorShortcut -> {
specialCircumstanceManager.specialCircumstance =
SpecialCircumstance.GeneratorShortcut
@@ -234,6 +381,11 @@ class MainViewModel @Inject constructor(
hasVaultShortcut -> {
specialCircumstanceManager.specialCircumstance = SpecialCircumstance.VaultShortcut
}
hasAccountSecurityShortcut -> {
specialCircumstanceManager.specialCircumstance =
SpecialCircumstance.AccountSecurityShortcut
}
}
}
@@ -241,6 +393,49 @@ class MainViewModel @Inject constructor(
sendEvent(MainEvent.Recreate)
garbageCollectionManager.tryCollect()
}
private fun handleCompleteRegistrationData(data: CompleteRegistrationData) {
viewModelScope.launch {
// Attempt to load the environment for the user if they have a pre-auth environment
// saved.
environmentRepository.loadEnvironmentForEmail(userEmail = data.email)
// Determine if the token is still valid.
val emailTokenResult = authRepository.validateEmailToken(
email = data.email,
token = data.verificationToken,
)
when (emailTokenResult) {
is EmailTokenResult.Error -> {
sendEvent(
MainEvent.ShowToast(
message = emailTokenResult
.message
?.asText()
?: R.string.there_was_an_issue_validating_the_registration_token
.asText(),
),
)
}
EmailTokenResult.Expired -> {
specialCircumstanceManager.specialCircumstance = SpecialCircumstance
.RegistrationEvent
.ExpiredRegistrationLink
}
EmailTokenResult.Success -> {
if (authRepository.activeUserId != null) {
authRepository.hasPendingAccountAddition = true
}
specialCircumstanceManager.specialCircumstance =
SpecialCircumstance.RegistrationEvent.CompleteRegistration(
completeRegistrationData = data,
timestamp = clock.millis(),
)
}
}
}
}
}
/**
@@ -249,6 +444,7 @@ class MainViewModel @Inject constructor(
@Parcelize
data class MainState(
val theme: AppTheme,
val isScreenCaptureAllowed: Boolean,
) : Parcelable
/**
@@ -265,10 +461,28 @@ sealed class MainAction {
*/
data class ReceiveNewIntent(val intent: Intent) : MainAction()
/**
* Receive event to open the debug menu.
*/
data object OpenDebugMenu : MainAction()
/**
* Receive event to save the app resume screen
*/
data class ResumeScreenDataReceived(val screenResumeData: AppResumeScreenData?) : MainAction()
/**
* Actions for internal use by the ViewModel.
*/
sealed class Internal : MainAction() {
/**
* Indicates the user has manually selected the given [cipherView] for accessibility
* autofill.
*/
data class AccessibilitySelectionReceive(
val cipherView: CipherView,
) : Internal()
/**
* Indicates the user has manually selected the given [cipherView] for autofill.
*/
@@ -281,6 +495,13 @@ sealed class MainAction {
*/
data object CurrentUserStateChange : Internal()
/**
* Indicates that the screen capture state has changed.
*/
data class ScreenCaptureUpdate(
val isScreenCaptureEnabled: Boolean,
) : Internal()
/**
* Indicates that the app theme has changed.
*/
@@ -299,19 +520,44 @@ sealed class MainAction {
* Represents events that are emitted by the [MainViewModel].
*/
sealed class MainEvent {
/**
* Event indicating that the user has chosen the given [cipherView] for accessibility autofill
* and that the process is ready to complete.
*/
data class CompleteAccessibilityAutofill(val cipherView: CipherView) : MainEvent()
/**
* Event indicating that the user has chosen the given [cipherView] for autofill and that the
* process is ready to complete.
*/
data class CompleteAutofill(val cipherView: CipherView) : MainEvent()
/**
* Event indicating a change in the screen capture setting.
*/
data class ScreenCaptureSettingChange(val isAllowed: Boolean) : MainEvent()
/**
* Event indicating that the UI should recreate itself.
*/
data object Recreate : MainEvent()
/**
* Navigate to the debug menu.
*/
data object NavigateToDebugMenu : MainEvent()
/**
* Show a toast with the given [message].
*/
data class ShowToast(val message: Text) : MainEvent()
/**
* Indicates that the app language has been updated.
*/
data class UpdateAppLocale(
val localeName: String?,
) : MainEvent()
/**
* Indicates that the app theme has been updated.
*/
data class UpdateAppTheme(
val osTheme: Int,
) : MainEvent()
}

View File

@@ -1,16 +1,26 @@
package com.x8bit.bitwarden.data.auth.datasource.disk
import com.x8bit.bitwarden.data.auth.datasource.disk.model.AccountTokensJson
import com.x8bit.bitwarden.data.auth.datasource.disk.model.NewDeviceNoticeState
import com.x8bit.bitwarden.data.auth.datasource.disk.model.OnboardingStatus
import com.x8bit.bitwarden.data.auth.datasource.disk.model.PendingAuthRequestJson
import com.x8bit.bitwarden.data.auth.datasource.disk.model.UserStateJson
import com.x8bit.bitwarden.data.vault.datasource.network.model.SyncResponseJson
import kotlinx.coroutines.flow.Flow
import java.time.Instant
/**
* Primary access point for disk information.
*/
@Suppress("TooManyFunctions")
interface AuthDiskSource {
/**
* The currently persisted authenticator sync symmetric key. This key is used for
* encrypting IPC traffic.
*/
var authenticatorSyncSymmetricKey: ByteArray?
/**
* Retrieves a unique ID for the application that is stored locally. This will generate a new
* one if it does not yet exist and it will only be reset for new installs or when clearing
@@ -45,12 +55,49 @@ interface AuthDiskSource {
*/
fun clearData(userId: String)
/**
* Get the authenticator sync unlock key. Null means there is no key, which means the user
* has not enabled authenticator syncing
*/
fun getAuthenticatorSyncUnlockKey(userId: String): String?
/**
* Store the authenticator sync unlock key. Storing a null key effectively disables
* authenticator syncing.
*/
fun storeAuthenticatorSyncUnlockKey(userId: String, authenticatorSyncUnlockKey: String?)
/**
* Retrieves the state indicating that the user should use a key connector.
*/
fun getShouldUseKeyConnector(userId: String): Boolean?
/**
* Retrieves the state indicating that the user should use a key connector as a flow.
*/
fun getShouldUseKeyConnectorFlow(userId: String): Flow<Boolean?>
/**
* Stores the boolean indicating that the user should use a key connector.
*/
fun storeShouldUseKeyConnector(userId: String, shouldUseKeyConnector: Boolean?)
/**
* Retrieves the state indicating that the user has completed login with TDE.
*/
fun getIsTdeLoginComplete(userId: String): Boolean?
/**
* Stores the boolean indicating that the user has completed login with TDE.
*/
fun storeIsTdeLoginComplete(userId: String, isTdeLoginComplete: Boolean?)
/**
* Retrieves the state indicating that the user has chosen to trust this device.
*
* Note: This indicates intent to trust the device, the device may not be trusted yet.
*/
fun getShouldTrustDevice(userId: String): Boolean
fun getShouldTrustDevice(userId: String): Boolean?
/**
* Stores the boolean indicating that the user has chosen to trust this device for the given
@@ -60,25 +107,6 @@ interface AuthDiskSource {
*/
fun storeShouldTrustDevice(userId: String, shouldTrustDevice: Boolean?)
/**
* Retrieves the "last active time" for the given [userId], in milliseconds.
*
* This time is intended to be derived from a call to
* [SystemClock.elapsedRealtime()](https://developer.android.com/reference/android/os/SystemClock#elapsedRealtime())
*/
fun getLastActiveTimeMillis(userId: String): Long?
/**
* Stores the [lastActiveTimeMillis] for the given [userId].
*
* This time is intended to be derived from a call to
* [SystemClock.elapsedRealtime()](https://developer.android.com/reference/android/os/SystemClock#elapsedRealtime())
*/
fun storeLastActiveTimeMillis(
userId: String,
lastActiveTimeMillis: Long?,
)
/**
* Retrieves the number of consecutive invalid lock attempts for the given [userId].
*/
@@ -145,6 +173,16 @@ interface AuthDiskSource {
pendingAuthRequest: PendingAuthRequestJson?,
)
/**
* Gets the biometrics initialization vector for the given [userId].
*/
fun getUserBiometricInitVector(userId: String): ByteArray?
/**
* Stores the biometrics initialization vector for the given [userId].
*/
fun storeUserBiometricInitVector(userId: String, iv: ByteArray?)
/**
* Gets the biometrics key for the given [userId].
*/
@@ -155,6 +193,11 @@ interface AuthDiskSource {
*/
fun storeUserBiometricUnlockKey(userId: String, biometricsKey: String?)
/**
* Gets the flow for the biometrics key for the given [userId].
*/
fun getUserBiometicUnlockKeyFlow(userId: String): Flow<String?>
/**
* Retrieves a pin-protected user key for the given [userId].
*/
@@ -172,6 +215,11 @@ interface AuthDiskSource {
inMemoryOnly: Boolean = false,
)
/**
* Retrieves a flow for the pin-protected user key for the given [userId].
*/
fun getPinProtectedUserKeyFlow(userId: String): Flow<String?>
/**
* Gets a two-factor auth token using a user's [email].
*/
@@ -264,4 +312,55 @@ interface AuthDiskSource {
* Stores the [accountTokens] for the given [userId].
*/
fun storeAccountTokens(userId: String, accountTokens: AccountTokensJson?)
/**
* Gets the onboarding status for the given [userId].
*/
fun getOnboardingStatus(userId: String): OnboardingStatus?
/**
* Stores the [onboardingStatus] for the given [userId].
*/
fun storeOnboardingStatus(userId: String, onboardingStatus: OnboardingStatus?)
/**
* Emits updates that track [getOnboardingStatus]. This will replay the last known value,
* if any exists.
*/
fun getOnboardingStatusFlow(userId: String): Flow<OnboardingStatus?>
/**
* Gets the show import logins flag for the given [userId].
*/
fun getShowImportLogins(userId: String): Boolean?
/**
* Stores the show import logins flag for the given [userId].
*/
fun storeShowImportLogins(userId: String, showImportLogins: Boolean?)
/**
* Emits updates that track [getShowImportLogins]. This will replay the last known value.
*/
fun getShowImportLoginsFlow(userId: String): Flow<Boolean?>
/**
* Gets the new device notice state for the given [userId].
*/
fun getNewDeviceNoticeState(userId: String): NewDeviceNoticeState
/**
* Stores the new device notice state for the given [userId].
*/
fun storeNewDeviceNoticeState(userId: String, newState: NewDeviceNoticeState?)
/**
* Gets the last lock timestamp for the given [userId].
*/
fun getLastLockTimestamp(userId: String): Instant?
/**
* Stores the last lock timestamp for the given [userId].
*/
fun storeLastLockTimestamp(userId: String, lastLockTimestamp: Instant?)
}

View File

@@ -2,6 +2,9 @@ package com.x8bit.bitwarden.data.auth.datasource.disk
import android.content.SharedPreferences
import com.x8bit.bitwarden.data.auth.datasource.disk.model.AccountTokensJson
import com.x8bit.bitwarden.data.auth.datasource.disk.model.NewDeviceNoticeDisplayStatus
import com.x8bit.bitwarden.data.auth.datasource.disk.model.NewDeviceNoticeState
import com.x8bit.bitwarden.data.auth.datasource.disk.model.OnboardingStatus
import com.x8bit.bitwarden.data.auth.datasource.disk.model.PendingAuthRequestJson
import com.x8bit.bitwarden.data.auth.datasource.disk.model.UserStateJson
import com.x8bit.bitwarden.data.platform.datasource.disk.BaseEncryptedDiskSource
@@ -12,12 +15,15 @@ import com.x8bit.bitwarden.data.vault.datasource.network.model.SyncResponseJson
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.onSubscription
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import java.time.Instant
import java.util.UUID
// These keys should be encrypted
private const val ACCOUNT_TOKENS_KEY = "accountTokens"
private const val AUTHENTICATOR_SYNC_SYMMETRIC_KEY = "authenticatorSyncSymmetric"
private const val AUTHENTICATOR_SYNC_UNLOCK_KEY = "authenticatorSyncUnlock"
private const val BIOMETRICS_INIT_VECTOR_KEY = "biometricInitializationVector"
private const val BIOMETRICS_UNLOCK_KEY = "userKeyBiometricUnlock"
private const val USER_AUTO_UNLOCK_KEY_KEY = "userKeyAutoUnlock"
private const val DEVICE_KEY_KEY = "deviceKey"
@@ -28,7 +34,6 @@ private const val UNIQUE_APP_ID_KEY = "appId"
private const val REMEMBERED_EMAIL_ADDRESS_KEY = "rememberedEmail"
private const val REMEMBERED_ORG_IDENTIFIER_KEY = "rememberedOrgIdentifier"
private const val STATE_KEY = "state"
private const val LAST_ACTIVE_TIME_KEY = "lastActiveTime"
private const val INVALID_UNLOCK_ATTEMPTS_KEY = "invalidUnlockAttempts"
private const val MASTER_KEY_ENCRYPTION_USER_KEY = "masterKeyEncryptedUserKey"
private const val MASTER_KEY_ENCRYPTION_PRIVATE_KEY = "encPrivateKey"
@@ -40,6 +45,12 @@ private const val TWO_FACTOR_TOKEN_KEY = "twoFactorToken"
private const val MASTER_PASSWORD_HASH_KEY = "keyHash"
private const val POLICIES_KEY = "policies"
private const val SHOULD_TRUST_DEVICE_KEY = "shouldTrustDevice"
private const val TDE_LOGIN_COMPLETE = "tdeLoginComplete"
private const val USES_KEY_CONNECTOR = "usesKeyConnector"
private const val ONBOARDING_STATUS_KEY = "onboardingStatus"
private const val SHOW_IMPORT_LOGINS_KEY = "showImportLogins"
private const val NEW_DEVICE_NOTICE_STATE = "newDeviceNoticeState"
private const val LAST_LOCK_TIMESTAMP = "lastLockTimestamp"
/**
* Primary implementation of [AuthDiskSource].
@@ -57,12 +68,21 @@ class AuthDiskSourceImpl(
AuthDiskSource {
private val inMemoryPinProtectedUserKeys = mutableMapOf<String, String?>()
private val mutableShouldUseKeyConnectorFlowMap =
mutableMapOf<String, MutableSharedFlow<Boolean?>>()
private val mutableOrganizationsFlowMap =
mutableMapOf<String, MutableSharedFlow<List<SyncResponseJson.Profile.Organization>?>>()
private val mutablePoliciesFlowMap =
mutableMapOf<String, MutableSharedFlow<List<SyncResponseJson.Policy>?>>()
private val mutableAccountTokensFlowMap =
mutableMapOf<String, MutableSharedFlow<AccountTokensJson?>>()
private val mutableOnboardingStatusFlowMap =
mutableMapOf<String, MutableSharedFlow<OnboardingStatus?>>()
private val mutableShowImportLoginsFlowMap = mutableMapOf<String, MutableSharedFlow<Boolean?>>()
private val mutableBiometricUnlockKeyFlowMap =
mutableMapOf<String, MutableSharedFlow<String?>>()
private val mutablePinProtectedUserKeyFlowMap =
mutableMapOf<String, MutableSharedFlow<String?>>()
private val mutableUserStateFlow = bufferedMutableSharedFlow<UserStateJson?>(replay = 1)
override var userState: UserStateJson?
@@ -85,6 +105,14 @@ class AuthDiskSourceImpl(
migrateAccountTokens()
}
override var authenticatorSyncSymmetricKey: ByteArray?
set(value) {
val asString = value?.let { value.toString(Charsets.ISO_8859_1) }
putEncryptedString(AUTHENTICATOR_SYNC_SYMMETRIC_KEY, asString)
}
get() = getEncryptedString(AUTHENTICATOR_SYNC_SYMMETRIC_KEY)
?.toByteArray(Charsets.ISO_8859_1)
override val uniqueAppId: String
get() = getString(key = UNIQUE_APP_ID_KEY) ?: generateAndStoreUniqueAppId()
@@ -111,7 +139,6 @@ class AuthDiskSourceImpl(
.onSubscription { emit(userState) }
override fun clearData(userId: String) {
storeLastActiveTimeMillis(userId = userId, lastActiveTimeMillis = null)
storeInvalidUnlockAttempts(userId = userId, invalidUnlockAttempts = null)
storeUserKey(userId = userId, userKey = null)
storeUserAutoUnlockKey(userId = userId, userAutoUnlockKey = null)
@@ -120,37 +147,67 @@ class AuthDiskSourceImpl(
storePrivateKey(userId = userId, privateKey = null)
storeOrganizationKeys(userId = userId, organizationKeys = null)
storeOrganizations(userId = userId, organizations = null)
storeUserBiometricInitVector(userId = userId, iv = null)
storeUserBiometricUnlockKey(userId = userId, biometricsKey = null)
storeMasterPasswordHash(userId = userId, passwordHash = null)
storePolicies(userId = userId, policies = null)
storeAccountTokens(userId = userId, accountTokens = null)
storeShouldUseKeyConnector(userId = userId, shouldUseKeyConnector = null)
storeIsTdeLoginComplete(userId = userId, isTdeLoginComplete = null)
storeAuthenticatorSyncUnlockKey(userId = userId, authenticatorSyncUnlockKey = null)
storeShowImportLogins(userId = userId, showImportLogins = null)
storeLastLockTimestamp(userId = userId, lastLockTimestamp = null)
// Do not remove the DeviceKey or PendingAuthRequest on logout, these are persisted
// indefinitely unless the TDE flow explicitly removes them.
// Do not remove OnboardingStatus we want to keep track of this even after logout.
}
override fun getShouldTrustDevice(userId: String): Boolean =
requireNotNull(
getBoolean(key = SHOULD_TRUST_DEVICE_KEY.appendIdentifier(userId), default = false),
override fun getAuthenticatorSyncUnlockKey(userId: String): String? =
getEncryptedString(AUTHENTICATOR_SYNC_UNLOCK_KEY.appendIdentifier(userId))
override fun storeAuthenticatorSyncUnlockKey(
userId: String,
authenticatorSyncUnlockKey: String?,
) {
putEncryptedString(
key = AUTHENTICATOR_SYNC_UNLOCK_KEY.appendIdentifier(userId),
value = authenticatorSyncUnlockKey,
)
}
override fun getShouldUseKeyConnectorFlow(userId: String): Flow<Boolean?> =
getMutableShouldUseKeyConnectorFlowMap(userId = userId)
.onSubscription { emit(getShouldUseKeyConnector(userId = userId)) }
override fun getShouldUseKeyConnector(
userId: String,
): Boolean? = getBoolean(key = USES_KEY_CONNECTOR.appendIdentifier(userId))
override fun storeShouldUseKeyConnector(userId: String, shouldUseKeyConnector: Boolean?) {
putBoolean(
key = USES_KEY_CONNECTOR.appendIdentifier(userId),
value = shouldUseKeyConnector,
)
getMutableShouldUseKeyConnectorFlowMap(userId = userId).tryEmit(shouldUseKeyConnector)
}
override fun getIsTdeLoginComplete(
userId: String,
): Boolean? = getBoolean(key = TDE_LOGIN_COMPLETE.appendIdentifier(userId))
override fun storeIsTdeLoginComplete(userId: String, isTdeLoginComplete: Boolean?) {
putBoolean(TDE_LOGIN_COMPLETE.appendIdentifier(userId), isTdeLoginComplete)
}
override fun getShouldTrustDevice(
userId: String,
): Boolean? = getBoolean(key = SHOULD_TRUST_DEVICE_KEY.appendIdentifier(userId))
override fun storeShouldTrustDevice(userId: String, shouldTrustDevice: Boolean?) {
putBoolean(SHOULD_TRUST_DEVICE_KEY.appendIdentifier(userId), shouldTrustDevice)
}
override fun getLastActiveTimeMillis(userId: String): Long? =
getLong(key = LAST_ACTIVE_TIME_KEY.appendIdentifier(userId))
override fun storeLastActiveTimeMillis(
userId: String,
lastActiveTimeMillis: Long?,
) {
putLong(
key = LAST_ACTIVE_TIME_KEY.appendIdentifier(userId),
value = lastActiveTimeMillis,
)
}
override fun getInvalidUnlockAttempts(userId: String): Int? =
getInt(key = INVALID_UNLOCK_ATTEMPTS_KEY.appendIdentifier(userId))
@@ -227,6 +284,17 @@ class AuthDiskSourceImpl(
)
}
override fun getUserBiometricInitVector(userId: String): ByteArray? =
getEncryptedString(key = BIOMETRICS_INIT_VECTOR_KEY.appendIdentifier(userId))
?.toByteArray(Charsets.ISO_8859_1)
override fun storeUserBiometricInitVector(userId: String, iv: ByteArray?) {
putEncryptedString(
key = BIOMETRICS_INIT_VECTOR_KEY.appendIdentifier(userId),
value = iv?.toString(Charsets.ISO_8859_1),
)
}
override fun getUserBiometricUnlockKey(userId: String): String? =
getEncryptedString(key = BIOMETRICS_UNLOCK_KEY.appendIdentifier(userId))
@@ -238,8 +306,13 @@ class AuthDiskSourceImpl(
key = BIOMETRICS_UNLOCK_KEY.appendIdentifier(userId),
value = biometricsKey,
)
getMutableBiometricUnlockKeyFlow(userId).tryEmit(biometricsKey)
}
override fun getUserBiometicUnlockKeyFlow(userId: String): Flow<String?> =
getMutableBiometricUnlockKeyFlow(userId)
.onSubscription { emit(getUserBiometricUnlockKey(userId = userId)) }
override fun getPinProtectedUserKey(userId: String): String? =
inMemoryPinProtectedUserKeys[userId]
?: getString(key = PIN_PROTECTED_USER_KEY_KEY.appendIdentifier(userId))
@@ -255,8 +328,13 @@ class AuthDiskSourceImpl(
key = PIN_PROTECTED_USER_KEY_KEY.appendIdentifier(userId),
value = pinProtectedUserKey,
)
getMutablePinProtectedUserKeyFlow(userId).tryEmit(pinProtectedUserKey)
}
override fun getPinProtectedUserKeyFlow(userId: String): Flow<String?> =
getMutablePinProtectedUserKeyFlow(userId)
.onSubscription { emit(getPinProtectedUserKey(userId = userId)) }
override fun getTwoFactorToken(email: String): String? =
getString(key = TWO_FACTOR_TOKEN_KEY.appendIdentifier(email))
@@ -376,6 +454,70 @@ class AuthDiskSourceImpl(
getMutableAccountTokensFlow(userId = userId).tryEmit(accountTokens)
}
override fun getOnboardingStatus(userId: String): OnboardingStatus? {
return getString(key = ONBOARDING_STATUS_KEY.appendIdentifier(userId))?.let {
json.decodeFromStringOrNull(it)
}
}
override fun storeOnboardingStatus(userId: String, onboardingStatus: OnboardingStatus?) {
putString(
key = ONBOARDING_STATUS_KEY.appendIdentifier(userId),
value = onboardingStatus?.let { json.encodeToString(it) },
)
getMutableOnboardingStatusFlow(userId = userId).tryEmit(onboardingStatus)
}
override fun getOnboardingStatusFlow(userId: String): Flow<OnboardingStatus?> {
return getMutableOnboardingStatusFlow(userId = userId)
.onSubscription { emit(getOnboardingStatus(userId = userId)) }
}
override fun getShowImportLogins(userId: String): Boolean? {
return getBoolean(SHOW_IMPORT_LOGINS_KEY.appendIdentifier(userId))
}
override fun storeShowImportLogins(userId: String, showImportLogins: Boolean?) {
putBoolean(
key = SHOW_IMPORT_LOGINS_KEY.appendIdentifier(userId),
value = showImportLogins,
)
getMutableShowImportLoginsFlow(userId = userId).tryEmit(showImportLogins)
}
override fun getShowImportLoginsFlow(userId: String): Flow<Boolean?> =
getMutableShowImportLoginsFlow(userId)
.onSubscription { emit(getShowImportLogins(userId)) }
override fun getNewDeviceNoticeState(userId: String): NewDeviceNoticeState {
return getString(key = NEW_DEVICE_NOTICE_STATE.appendIdentifier(userId))?.let {
json.decodeFromStringOrNull(it)
} ?: NewDeviceNoticeState(
displayStatus = NewDeviceNoticeDisplayStatus.HAS_NOT_SEEN,
lastSeenDate = null,
)
}
override fun storeNewDeviceNoticeState(userId: String, newState: NewDeviceNoticeState?) {
putString(
key = NEW_DEVICE_NOTICE_STATE.appendIdentifier(userId),
value = newState?.let { json.encodeToString(it) },
)
}
override fun getLastLockTimestamp(userId: String): Instant? {
return getLong(key = LAST_LOCK_TIMESTAMP.appendIdentifier(userId))?.let {
Instant.ofEpochMilli(it)
}
}
override fun storeLastLockTimestamp(userId: String, lastLockTimestamp: Instant?) {
putLong(
key = LAST_LOCK_TIMESTAMP.appendIdentifier(userId),
value = lastLockTimestamp?.toEpochMilli(),
)
}
private fun generateAndStoreUniqueAppId(): String =
UUID
.randomUUID()
@@ -384,6 +526,20 @@ class AuthDiskSourceImpl(
putString(key = UNIQUE_APP_ID_KEY, value = it)
}
private fun getMutableOnboardingStatusFlow(
userId: String,
): MutableSharedFlow<OnboardingStatus?> =
mutableOnboardingStatusFlowMap.getOrPut(userId) {
bufferedMutableSharedFlow(replay = 1)
}
private fun getMutableShouldUseKeyConnectorFlowMap(
userId: String,
): MutableSharedFlow<Boolean?> =
mutableShouldUseKeyConnectorFlowMap.getOrPut(userId) {
bufferedMutableSharedFlow(replay = 1)
}
private fun getMutableOrganizationsFlow(
userId: String,
): MutableSharedFlow<List<SyncResponseJson.Profile.Organization>?> =
@@ -405,6 +561,24 @@ class AuthDiskSourceImpl(
bufferedMutableSharedFlow(replay = 1)
}
private fun getMutableShowImportLoginsFlow(
userId: String,
): MutableSharedFlow<Boolean?> = mutableShowImportLoginsFlowMap.getOrPut(userId) {
bufferedMutableSharedFlow(replay = 1)
}
private fun getMutableBiometricUnlockKeyFlow(
userId: String,
): MutableSharedFlow<String?> = mutableBiometricUnlockKeyFlowMap.getOrPut(userId) {
bufferedMutableSharedFlow(replay = 1)
}
private fun getMutablePinProtectedUserKeyFlow(
userId: String,
): MutableSharedFlow<String?> = mutablePinProtectedUserKeyFlowMap.getOrPut(userId) {
bufferedMutableSharedFlow(replay = 1)
}
private fun migrateAccountTokens() {
userState
?.accounts

View File

@@ -2,8 +2,12 @@ package com.x8bit.bitwarden.data.auth.datasource.disk.model
import com.x8bit.bitwarden.data.auth.datasource.network.model.KdfTypeJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.UserDecryptionOptionsJson
import kotlinx.serialization.Contextual
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonNames
import java.time.ZonedDateTime
/**
* Represents the current account information for a given user.
@@ -33,6 +37,7 @@ data class AccountJson(
* @property userId The ID of the user.
* @property email The user's email address.
* @property isEmailVerified Whether or not the user's email is verified.
* @property isTwoFactorEnabled If the profile has two factor authentication enabled.
* @property name The user's name (if applicable).
* @property stamp The account's security stamp (if applicable).
* @property organizationId The ID of the associated organization (if applicable).
@@ -44,7 +49,9 @@ data class AccountJson(
* @property kdfMemory The amount of memory to use when calculating a password hash (MB).
* @property kdfParallelism The number of threads to use when calculating a password hash.
* @property userDecryptionOptions The options available to a user for decryption.
* @property creationDate The creation date of the account.
*/
@OptIn(ExperimentalSerializationApi::class)
@Serializable
data class Profile(
@SerialName("userId")
@@ -56,6 +63,9 @@ data class AccountJson(
@SerialName("emailVerified")
val isEmailVerified: Boolean?,
@SerialName("isTwoFactorEnabled")
val isTwoFactorEnabled: Boolean?,
@SerialName("name")
val name: String?,
@@ -86,8 +96,13 @@ data class AccountJson(
@SerialName("kdfParallelism")
val kdfParallelism: Int?,
@SerialName("accountDecryptionOptions")
@SerialName("userDecryptionOptions")
@JsonNames("accountDecryptionOptions")
val userDecryptionOptions: UserDecryptionOptionsJson?,
@SerialName("creationDate")
@Contextual
val creationDate: ZonedDateTime?,
)
/**

View File

@@ -7,6 +7,7 @@ import kotlinx.serialization.Serializable
* Represents URLs for various Bitwarden domains.
*
* @property base The overall base URL.
* @property keyUri A Uri containing the alias and host of the key used for mutual TLS.
* @property api Separate base URL for the "/api" domain (if applicable).
* @property identity Separate base URL for the "/identity" domain (if applicable).
* @property icon Separate base URL for the icon domain (if applicable).
@@ -19,6 +20,9 @@ data class EnvironmentUrlDataJson(
@SerialName("base")
val base: String,
@SerialName("keyUri")
val keyUri: String? = null,
@SerialName("api")
val api: String? = null,
@@ -37,6 +41,7 @@ data class EnvironmentUrlDataJson(
@SerialName("events")
val events: String? = null,
) {
@Suppress("UndocumentedPublicClass")
companion object {
/**
* Default [EnvironmentUrlDataJson] for the US region.
@@ -50,6 +55,7 @@ data class EnvironmentUrlDataJson(
*/
val DEFAULT_LEGACY_US: EnvironmentUrlDataJson = EnvironmentUrlDataJson(
base = "https://vault.bitwarden.com",
keyUri = null,
api = "https://api.bitwarden.com",
identity = "https://identity.bitwarden.com",
icon = "https://icons.bitwarden.net",
@@ -70,6 +76,7 @@ data class EnvironmentUrlDataJson(
*/
val DEFAULT_LEGACY_EU: EnvironmentUrlDataJson = EnvironmentUrlDataJson(
base = "https://vault.bitwarden.eu",
keyUri = null,
api = "https://api.bitwarden.eu",
identity = "https://identity.bitwarden.eu",
icon = "https://icons.bitwarden.eu",

View File

@@ -0,0 +1,60 @@
package com.x8bit.bitwarden.data.auth.datasource.disk.model
import kotlinx.serialization.Contextual
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import java.time.ZonedDateTime
/**
* Describes the current display status of the new device notice screen.
*/
@Serializable
enum class NewDeviceNoticeDisplayStatus {
/**
* The user has seen the screen and indicated they can access their email.
*/
@SerialName("canAccessEmail")
CAN_ACCESS_EMAIL,
/**
* The user has indicated they can access their email
* as specified by the Permanent mode of the notice.
*/
@SerialName("canAccessEmailPermanent")
CAN_ACCESS_EMAIL_PERMANENT,
/**
* The user has not seen the screen.
*/
@SerialName("hasNotSeen")
HAS_NOT_SEEN,
/**
* The user has seen the screen and selected "remind me later".
*/
@SerialName("hasSeen")
HAS_SEEN,
}
/**
* The state of the new device notice screen.
*/
@Suppress("MagicNumber")
@Serializable
data class NewDeviceNoticeState(
@SerialName("displayStatus")
val displayStatus: NewDeviceNoticeDisplayStatus,
@SerialName("lastSeenDate")
@Contextual
val lastSeenDate: ZonedDateTime?,
) {
/**
* Whether the [lastSeenDate] is at least 7 days old.
*/
val shouldDisplayNoticeIfSeen = lastSeenDate
?.isBefore(
ZonedDateTime.now().minusDays(7),
)
?: false
}

View File

@@ -0,0 +1,41 @@
package com.x8bit.bitwarden.data.auth.datasource.disk.model
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
/**
* Describes the current status of a user in the account onboarding steps.
*/
@Serializable
enum class OnboardingStatus {
/**
* Onboarding has not yet started.
*/
@SerialName("notStarted")
NOT_STARTED,
/**
* The user is completing the account lock setup.
*/
@SerialName("accountLockSetup")
ACCOUNT_LOCK_SETUP,
/**
* The user is completing the auto fill service setup.
*/
@SerialName("autofillSetup")
AUTOFILL_SETUP,
/**
* The user is completing the final step of the onboarding process.
*/
@SerialName("finalStep")
FINAL_STEP,
/**
* The user has completed all onboarding steps.
*/
@SerialName("complete")
COMPLETE,
}

View File

@@ -7,13 +7,21 @@ import kotlinx.serialization.Serializable
* Container for the user's API tokens.
*
* @property requestId The ID of the pending Auth Request.
* @property requestPrivateKey The private of the pending Auth Request.
* @property requestPrivateKey The private key of the pending Auth Request.
* @property requestAccessCode The access code of the pending Auth Request.
* @property requestFingerprint The fingerprint of the pending Auth Request.
*/
@Serializable
data class PendingAuthRequestJson(
@SerialName("Id")
@SerialName("id")
val requestId: String,
@SerialName("PrivateKey")
@SerialName("privateKey")
val requestPrivateKey: String,
@SerialName("accessCode")
val requestAccessCode: String,
@SerialName("fingerprint")
val requestFingerprint: String,
)

View File

@@ -1,21 +0,0 @@
package com.x8bit.bitwarden.data.auth.datasource.network.api
import com.x8bit.bitwarden.data.auth.datasource.network.model.PasswordHintRequestJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.ResendEmailRequestJson
import retrofit2.http.Body
import retrofit2.http.POST
/**
* Defines raw calls under the /accounts API.
*/
interface AccountsApi {
@POST("/accounts/password-hint")
suspend fun passwordHintRequest(
@Body body: PasswordHintRequestJson,
): Result<Unit>
@POST("/two-factor/send-email-login")
suspend fun resendVerificationCodeEmail(
@Body body: ResendEmailRequestJson,
): Result<Unit>
}

View File

@@ -5,6 +5,7 @@ import com.x8bit.bitwarden.data.auth.datasource.network.model.DeleteAccountReque
import com.x8bit.bitwarden.data.auth.datasource.network.model.ResetPasswordRequestJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.SetPasswordRequestJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.VerifyOtpRequestJson
import com.x8bit.bitwarden.data.platform.datasource.network.model.NetworkResult
import retrofit2.http.Body
import retrofit2.http.HTTP
import retrofit2.http.POST
@@ -13,41 +14,48 @@ import retrofit2.http.POST
* Defines raw calls under the /accounts API with authentication applied.
*/
interface AuthenticatedAccountsApi {
/**
* Converts the currently active account to a key-connector account.
*/
@POST("/accounts/convert-to-key-connector")
suspend fun convertToKeyConnector(): NetworkResult<Unit>
/**
* Creates the keys for the current account.
*/
@POST("/accounts/keys")
suspend fun createAccountKeys(@Body body: CreateAccountKeysRequest): Result<Unit>
suspend fun createAccountKeys(@Body body: CreateAccountKeysRequest): NetworkResult<Unit>
/**
* Deletes the current account.
*/
@HTTP(method = "DELETE", path = "/accounts", hasBody = true)
suspend fun deleteAccount(@Body body: DeleteAccountRequestJson): Result<Unit>
suspend fun deleteAccount(@Body body: DeleteAccountRequestJson): NetworkResult<Unit>
@POST("/accounts/request-otp")
suspend fun requestOtp(): Result<Unit>
suspend fun requestOtp(): NetworkResult<Unit>
@POST("/accounts/verify-otp")
suspend fun verifyOtp(
@Body body: VerifyOtpRequestJson,
): Result<Unit>
): NetworkResult<Unit>
/**
* Resets the temporary password.
*/
@HTTP(method = "PUT", path = "/accounts/update-temp-password", hasBody = true)
suspend fun resetTempPassword(@Body body: ResetPasswordRequestJson): Result<Unit>
suspend fun resetTempPassword(@Body body: ResetPasswordRequestJson): NetworkResult<Unit>
/**
* Resets the password.
*/
@HTTP(method = "POST", path = "/accounts/password", hasBody = true)
suspend fun resetPassword(@Body body: ResetPasswordRequestJson): Result<Unit>
suspend fun resetPassword(@Body body: ResetPasswordRequestJson): NetworkResult<Unit>
/**
* Sets the password.
*/
@POST("/accounts/set-password")
suspend fun setPassword(@Body body: SetPasswordRequestJson): Result<Unit>
suspend fun setPassword(@Body body: SetPasswordRequestJson): NetworkResult<Unit>
}

View File

@@ -3,6 +3,7 @@ package com.x8bit.bitwarden.data.auth.datasource.network.api
import com.x8bit.bitwarden.data.auth.datasource.network.model.AuthRequestRequestJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.AuthRequestUpdateRequestJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.AuthRequestsResponseJson
import com.x8bit.bitwarden.data.platform.datasource.network.model.NetworkResult
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.Header
@@ -22,7 +23,7 @@ interface AuthenticatedAuthRequestsApi {
suspend fun createAdminAuthRequest(
@Header("Device-Identifier") deviceIdentifier: String,
@Body body: AuthRequestRequestJson,
): Result<AuthRequestsResponseJson.AuthRequest>
): NetworkResult<AuthRequestsResponseJson.AuthRequest>
/**
* Updates an authentication request.
@@ -31,13 +32,13 @@ interface AuthenticatedAuthRequestsApi {
suspend fun updateAuthRequest(
@Path("id") userId: String,
@Body body: AuthRequestUpdateRequestJson,
): Result<AuthRequestsResponseJson.AuthRequest>
): NetworkResult<AuthRequestsResponseJson.AuthRequest>
/**
* Gets a list of auth requests for this device.
*/
@GET("/auth-requests")
suspend fun getAuthRequests(): Result<AuthRequestsResponseJson>
suspend fun getAuthRequests(): NetworkResult<AuthRequestsResponseJson>
/**
* Retrieves an existing authentication request by ID.
@@ -45,5 +46,5 @@ interface AuthenticatedAuthRequestsApi {
@GET("/auth-requests/{requestId}")
suspend fun getAuthRequest(
@Path("requestId") requestId: String,
): Result<AuthRequestsResponseJson.AuthRequest>
): NetworkResult<AuthRequestsResponseJson.AuthRequest>
}

View File

@@ -3,6 +3,7 @@ package com.x8bit.bitwarden.data.auth.datasource.network.api
import androidx.annotation.Keep
import com.x8bit.bitwarden.data.auth.datasource.network.model.TrustedDeviceKeysRequestJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.TrustedDeviceKeysResponseJson
import com.x8bit.bitwarden.data.platform.datasource.network.model.NetworkResult
import retrofit2.http.Body
import retrofit2.http.PUT
import retrofit2.http.Path
@@ -16,5 +17,5 @@ interface AuthenticatedDevicesApi {
suspend fun updateTrustedDeviceKeys(
@Path(value = "appId") appId: String,
@Body request: TrustedDeviceKeysRequestJson,
): Result<TrustedDeviceKeysResponseJson>
): NetworkResult<TrustedDeviceKeysResponseJson>
}

View File

@@ -0,0 +1,20 @@
package com.x8bit.bitwarden.data.auth.datasource.network.api
import androidx.annotation.Keep
import com.x8bit.bitwarden.data.auth.datasource.network.model.KeyConnectorMasterKeyRequestJson
import com.x8bit.bitwarden.data.platform.datasource.network.model.NetworkResult
import retrofit2.http.Body
import retrofit2.http.POST
import retrofit2.http.Url
/**
* Defines raw calls specific for key connectors that use custom urls.
*/
@Keep
interface AuthenticatedKeyConnectorApi {
@POST
suspend fun storeMasterKeyToKeyConnector(
@Url url: String,
@Body body: KeyConnectorMasterKeyRequestJson,
): NetworkResult<Unit>
}

View File

@@ -3,6 +3,7 @@ package com.x8bit.bitwarden.data.auth.datasource.network.api
import com.x8bit.bitwarden.data.auth.datasource.network.model.OrganizationAutoEnrollStatusResponseJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.OrganizationKeysResponseJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.OrganizationResetPasswordEnrollRequestJson
import com.x8bit.bitwarden.data.platform.datasource.network.model.NetworkResult
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.PUT
@@ -20,7 +21,7 @@ interface AuthenticatedOrganizationApi {
@Path("orgId") organizationId: String,
@Path("userId") userId: String,
@Body body: OrganizationResetPasswordEnrollRequestJson,
): Result<Unit>
): NetworkResult<Unit>
/**
* Checks whether this organization auto enrolls users in password reset.
@@ -28,7 +29,7 @@ interface AuthenticatedOrganizationApi {
@GET("/organizations/{identifier}/auto-enroll-status")
suspend fun getOrganizationAutoEnrollResponse(
@Path("identifier") organizationIdentifier: String,
): Result<OrganizationAutoEnrollStatusResponseJson>
): NetworkResult<OrganizationAutoEnrollStatusResponseJson>
/**
* Gets the public and private keys for this organization.
@@ -36,5 +37,5 @@ interface AuthenticatedOrganizationApi {
@GET("/organizations/{id}/keys")
suspend fun getOrganizationKeys(
@Path("id") organizationId: String,
): Result<OrganizationKeysResponseJson>
): NetworkResult<OrganizationKeysResponseJson>
}

View File

@@ -1,5 +1,6 @@
package com.x8bit.bitwarden.data.auth.datasource.network.api
import com.x8bit.bitwarden.data.platform.datasource.network.model.NetworkResult
import okhttp3.ResponseBody
import retrofit2.http.GET
import retrofit2.http.Path
@@ -14,5 +15,5 @@ interface HaveIBeenPwnedApi {
suspend fun fetchBreachedPasswords(
@Path("hashPrefix")
hashPrefix: String,
): Result<ResponseBody>
): NetworkResult<ResponseBody>
}

View File

@@ -1,19 +0,0 @@
package com.x8bit.bitwarden.data.auth.datasource.network.api
import com.x8bit.bitwarden.data.auth.datasource.network.model.OrganizationDomainSsoDetailsRequestJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.OrganizationDomainSsoDetailsResponseJson
import retrofit2.http.Body
import retrofit2.http.POST
/**
* Defines raw calls under the /organizations API.
*/
interface OrganizationApi {
/**
* Checks for the claimed domain organization of an email for SSO purposes.
*/
@POST("/organizations/domain/sso/details")
suspend fun getClaimedDomainOrganizationDetails(
@Body body: OrganizationDomainSsoDetailsRequestJson,
): Result<OrganizationDomainSsoDetailsResponseJson>
}

View File

@@ -0,0 +1,37 @@
package com.x8bit.bitwarden.data.auth.datasource.network.api
import com.x8bit.bitwarden.data.auth.datasource.network.model.KeyConnectorKeyRequestJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.PasswordHintRequestJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.ResendEmailRequestJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.ResendNewDeviceOtpRequestJson
import com.x8bit.bitwarden.data.platform.datasource.network.model.NetworkResult
import com.x8bit.bitwarden.data.platform.datasource.network.util.HEADER_KEY_AUTHORIZATION
import retrofit2.http.Body
import retrofit2.http.Header
import retrofit2.http.POST
/**
* Defines raw calls under the /accounts API.
*/
interface UnauthenticatedAccountsApi {
@POST("/accounts/password-hint")
suspend fun passwordHintRequest(
@Body body: PasswordHintRequestJson,
): NetworkResult<Unit>
@POST("/two-factor/send-email-login")
suspend fun resendVerificationCodeEmail(
@Body body: ResendEmailRequestJson,
): NetworkResult<Unit>
@POST("/accounts/set-key-connector-key")
suspend fun setKeyConnectorKey(
@Body body: KeyConnectorKeyRequestJson,
@Header(HEADER_KEY_AUTHORIZATION) bearerToken: String,
): NetworkResult<Unit>
@POST("/accounts/resend-new-device-otp")
suspend fun resendNewDeviceOtp(
@Body body: ResendNewDeviceOtpRequestJson,
): NetworkResult<Unit>
}

View File

@@ -2,6 +2,7 @@ package com.x8bit.bitwarden.data.auth.datasource.network.api
import com.x8bit.bitwarden.data.auth.datasource.network.model.AuthRequestRequestJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.AuthRequestsResponseJson
import com.x8bit.bitwarden.data.platform.datasource.network.model.NetworkResult
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.Header
@@ -21,7 +22,7 @@ interface UnauthenticatedAuthRequestsApi {
suspend fun createAuthRequest(
@Header("Device-Identifier") deviceIdentifier: String,
@Body body: AuthRequestRequestJson,
): Result<AuthRequestsResponseJson.AuthRequest>
): NetworkResult<AuthRequestsResponseJson.AuthRequest>
/**
* Queries for updates to a given auth request.
@@ -30,5 +31,5 @@ interface UnauthenticatedAuthRequestsApi {
suspend fun getAuthRequestUpdate(
@Path("requestId") requestId: String,
@Query("code") accessCode: String,
): Result<AuthRequestsResponseJson.AuthRequest>
): NetworkResult<AuthRequestsResponseJson.AuthRequest>
}

View File

@@ -1,5 +1,6 @@
package com.x8bit.bitwarden.data.auth.datasource.network.api
import com.x8bit.bitwarden.data.platform.datasource.network.model.NetworkResult
import retrofit2.http.GET
import retrofit2.http.Header
@@ -11,5 +12,5 @@ interface UnauthenticatedDevicesApi {
suspend fun getIsKnownDevice(
@Header(value = "X-Request-Email") emailAddress: String,
@Header(value = "X-Device-Identifier") deviceId: String,
): Result<Boolean>
): NetworkResult<Boolean>
}

View File

@@ -5,8 +5,13 @@ import com.x8bit.bitwarden.data.auth.datasource.network.model.PreLoginRequestJso
import com.x8bit.bitwarden.data.auth.datasource.network.model.PreLoginResponseJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.PrevalidateSsoResponseJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.RefreshTokenResponseJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.RegisterFinishRequestJson
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.VerifyEmailTokenRequestJson
import com.x8bit.bitwarden.data.platform.datasource.network.model.NetworkResult
import kotlinx.serialization.json.JsonPrimitive
import retrofit2.Call
import retrofit2.http.Body
import retrofit2.http.Field
@@ -19,7 +24,7 @@ import retrofit2.http.Query
/**
* Defines raw calls under the /identity API.
*/
interface IdentityApi {
interface UnauthenticatedIdentityApi {
@POST("/connect/token")
@Suppress("LongParameterList")
@@ -42,12 +47,13 @@ interface IdentityApi {
@Field(value = "twoFactorProvider") twoFactorMethod: String?,
@Field(value = "twoFactorRemember") twoFactorRemember: String?,
@Field(value = "authRequest") authRequestId: String?,
): Result<GetTokenResponseJson.Success>
@Field(value = "newDeviceOtp") newDeviceOtp: String?,
): NetworkResult<GetTokenResponseJson.Success>
@GET("/sso/prevalidate")
suspend fun prevalidateSso(
@Query("domainHint") organizationIdentifier: String,
): Result<PrevalidateSsoResponseJson>
): NetworkResult<PrevalidateSsoResponseJson.Success>
/**
* This call needs to be synchronous so we need it to return a [Call] directly. The identity
@@ -62,8 +68,25 @@ interface IdentityApi {
): Call<RefreshTokenResponseJson>
@POST("/accounts/prelogin")
suspend fun preLogin(@Body body: PreLoginRequestJson): Result<PreLoginResponseJson>
suspend fun preLogin(@Body body: PreLoginRequestJson): NetworkResult<PreLoginResponseJson>
@POST("/accounts/register")
suspend fun register(@Body body: RegisterRequestJson): Result<RegisterResponseJson.Success>
suspend fun register(
@Body body: RegisterRequestJson,
): NetworkResult<RegisterResponseJson.Success>
@POST("/accounts/register/finish")
suspend fun registerFinish(
@Body body: RegisterFinishRequestJson,
): NetworkResult<RegisterResponseJson.Success>
@POST("/accounts/register/send-verification-email")
suspend fun sendVerificationEmail(
@Body body: SendVerificationEmailRequestJson,
): NetworkResult<JsonPrimitive?>
@POST("/accounts/register/verification-email-clicked")
suspend fun verifyEmailToken(
@Body body: VerifyEmailTokenRequestJson,
): NetworkResult<Unit>
}

View File

@@ -0,0 +1,31 @@
package com.x8bit.bitwarden.data.auth.datasource.network.api
import androidx.annotation.Keep
import com.x8bit.bitwarden.data.auth.datasource.network.model.KeyConnectorMasterKeyRequestJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.KeyConnectorMasterKeyResponseJson
import com.x8bit.bitwarden.data.platform.datasource.network.model.NetworkResult
import com.x8bit.bitwarden.data.platform.datasource.network.util.HEADER_KEY_AUTHORIZATION
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.Header
import retrofit2.http.POST
import retrofit2.http.Url
/**
* Defines raw calls specific for key connectors that use custom urls.
*/
@Keep
interface UnauthenticatedKeyConnectorApi {
@POST
suspend fun storeMasterKeyToKeyConnector(
@Url url: String,
@Header(HEADER_KEY_AUTHORIZATION) bearerToken: String,
@Body body: KeyConnectorMasterKeyRequestJson,
): NetworkResult<Unit>
@GET
suspend fun getMasterKeyFromKeyConnector(
@Url url: String,
@Header(HEADER_KEY_AUTHORIZATION) bearerToken: String,
): NetworkResult<KeyConnectorMasterKeyResponseJson>
}

View File

@@ -0,0 +1,30 @@
package com.x8bit.bitwarden.data.auth.datasource.network.api
import com.x8bit.bitwarden.data.auth.datasource.network.model.OrganizationDomainSsoDetailsRequestJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.OrganizationDomainSsoDetailsResponseJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.VerifiedOrganizationDomainSsoDetailsRequest
import com.x8bit.bitwarden.data.auth.datasource.network.model.VerifiedOrganizationDomainSsoDetailsResponse
import com.x8bit.bitwarden.data.platform.datasource.network.model.NetworkResult
import retrofit2.http.Body
import retrofit2.http.POST
/**
* Defines raw calls under the /organizations API.
*/
interface UnauthenticatedOrganizationApi {
/**
* Checks for the claimed domain organization of an email for SSO purposes.
*/
@POST("/organizations/domain/sso/details")
suspend fun getClaimedDomainOrganizationDetails(
@Body body: OrganizationDomainSsoDetailsRequestJson,
): NetworkResult<OrganizationDomainSsoDetailsResponseJson>
/**
* Checks for the verfied organization domains of an email for SSO purposes.
*/
@POST("/organizations/domain/sso/verified")
suspend fun getVerifiedOrganizationDomainsByEmail(
@Body body: VerifiedOrganizationDomainSsoDetailsRequest,
): NetworkResult<VerifiedOrganizationDomainSsoDetailsResponse>
}

View File

@@ -36,8 +36,12 @@ object AuthNetworkModule {
retrofits: Retrofits,
json: Json,
): AccountsService = AccountsServiceImpl(
accountsApi = retrofits.unauthenticatedApiRetrofit.create(),
unauthenticatedAccountsApi = retrofits.unauthenticatedApiRetrofit.create(),
authenticatedAccountsApi = retrofits.authenticatedApiRetrofit.create(),
unauthenticatedKeyConnectorApi = retrofits.createStaticRetrofit().create(),
authenticatedKeyConnectorApi = retrofits
.createStaticRetrofit(isAuthenticated = true)
.create(),
json = json,
)
@@ -64,7 +68,7 @@ object AuthNetworkModule {
retrofits: Retrofits,
json: Json,
): IdentityService = IdentityServiceImpl(
api = retrofits.unauthenticatedIdentityRetrofit.create(),
unauthenticatedIdentityApi = retrofits.unauthenticatedIdentityRetrofit.create(),
json = json,
)
@@ -73,10 +77,8 @@ object AuthNetworkModule {
fun providesHaveIBeenPwnedService(
retrofits: Retrofits,
): HaveIBeenPwnedService = HaveIBeenPwnedServiceImpl(
retrofits
.staticRetrofitBuilder
.baseUrl("https://api.pwnedpasswords.com")
.build()
api = retrofits
.createStaticRetrofit(baseUrl = "https://api.pwnedpasswords.com")
.create(),
)
@@ -95,6 +97,6 @@ object AuthNetworkModule {
retrofits: Retrofits,
): OrganizationService = OrganizationServiceImpl(
authenticatedOrganizationApi = retrofits.authenticatedApiRetrofit.create(),
organizationApi = retrofits.unauthenticatedApiRetrofit.create(),
unauthenticatedOrganizationApi = retrofits.unauthenticatedApiRetrofit.create(),
)
}

View File

@@ -21,5 +21,7 @@ enum class AuthRequestTypeJson {
}
@Keep
private class AuthRequestTypeSerializer :
BaseEnumeratedIntSerializer<AuthRequestTypeJson>(AuthRequestTypeJson.entries.toTypedArray())
private class AuthRequestTypeSerializer : BaseEnumeratedIntSerializer<AuthRequestTypeJson>(
className = "AuthRequestTypeJson",
values = AuthRequestTypeJson.entries.toTypedArray(),
)

View File

@@ -1,7 +1,9 @@
package com.x8bit.bitwarden.data.auth.datasource.network.model
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonNames
import kotlinx.serialization.json.JsonObject
/**
@@ -28,6 +30,7 @@ sealed class GetTokenResponseJson {
* this token will be cached and used for future auth requests.
* @property masterPasswordPolicyOptions The options available for a user's master password.
* @property userDecryptionOptions The options available to a user for decryption.
* @property keyConnectorUrl URL to the user's key connector.
*/
@Serializable
data class Success(
@@ -75,6 +78,9 @@ sealed class GetTokenResponseJson {
@SerialName("UserDecryptionOptions")
val userDecryptionOptions: UserDecryptionOptionsJson?,
@SerialName("KeyConnectorUrl")
val keyConnectorUrl: String?,
) : GetTokenResponseJson()
/**
@@ -88,18 +94,53 @@ sealed class GetTokenResponseJson {
/**
* Models json body of an invalid request.
*
* This model supports older versions of the error response model that used lower-case keys.
*/
@OptIn(ExperimentalSerializationApi::class)
@Serializable
data class Invalid(
@JsonNames("errorModel")
@SerialName("ErrorModel")
val errorModel: ErrorModel,
private val errorModel: ErrorModel?,
) : GetTokenResponseJson() {
/**
* The error message returned from the server, or null.
*/
val errorMessage: String? get() = errorModel?.errorMessage
/**
* The type of invalid responses that can be received.
*/
sealed class InvalidType {
/**
* Represents an invalid response indicating that a new device verification is required.
*/
data object NewDeviceVerification : InvalidType()
/**
* Represents generic invalid response
*/
data object GenericInvalid : InvalidType()
}
val invalidType: InvalidType
get() = if (errorMessage?.lowercase() == "new device verification required") {
InvalidType.NewDeviceVerification
} else {
InvalidType.GenericInvalid
}
/**
* The error body of an invalid request containing a message.
*
* This model supports older versions of the error response model that used lower-case
* keys.
*/
@Serializable
data class ErrorModel(
@JsonNames("message")
@SerialName("Message")
val errorMessage: String,
)

View File

@@ -18,5 +18,7 @@ enum class KdfTypeJson {
}
@Keep
private class KdfTypeSerializer :
BaseEnumeratedIntSerializer<KdfTypeJson>(KdfTypeJson.entries.toTypedArray())
private class KdfTypeSerializer : BaseEnumeratedIntSerializer<KdfTypeJson>(
className = "KdfTypeJson",
values = KdfTypeJson.entries.toTypedArray(),
)

View File

@@ -0,0 +1,33 @@
package com.x8bit.bitwarden.data.auth.datasource.network.model
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
/**
* Represents the request body used to create the key connector keys for an account.
*/
@Serializable
data class KeyConnectorKeyRequestJson(
@SerialName("key") val userKey: String,
@SerialName("keys") val keys: Keys,
@SerialName("kdf") val kdfType: KdfTypeJson,
@SerialName("kdfIterations") val kdfIterations: Int?,
@SerialName("kdfMemory") val kdfMemory: Int?,
@SerialName("kdfParallelism") val kdfParallelism: Int?,
@SerialName("orgIdentifier") val organizationIdentifier: String,
) {
/**
* A keys object containing public and private keys.
*
* @param publicKey the public key (encrypted).
* @param encryptedPrivateKey the private key (encrypted).
*/
@Serializable
data class Keys(
@SerialName("publicKey")
val publicKey: String,
@SerialName("encryptedPrivateKey")
val encryptedPrivateKey: String,
)
}

View File

@@ -0,0 +1,12 @@
package com.x8bit.bitwarden.data.auth.datasource.network.model
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
/**
* Represents the request body used to store the master key in the cloud.
*/
@Serializable
data class KeyConnectorMasterKeyRequestJson(
@SerialName("Key") val masterKey: String,
)

View File

@@ -0,0 +1,12 @@
package com.x8bit.bitwarden.data.auth.datasource.network.model
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
/**
* Represents the response body used to retrieve the master key from the cloud.
*/
@Serializable
data class KeyConnectorMasterKeyResponseJson(
@SerialName("key") val masterKey: String,
)

View File

@@ -1,15 +1,19 @@
package com.x8bit.bitwarden.data.auth.datasource.network.model
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonNames
/**
* Decryption options related to a user's key connector.
*
* @property keyConnectorUrl URL to the user's key connector.
*/
@OptIn(ExperimentalSerializationApi::class)
@Serializable
data class KeyConnectorUserDecryptionOptionsJson(
@SerialName("KeyConnectorUrl")
@SerialName("keyConnectorUrl")
@JsonNames("KeyConnectorUrl")
val keyConnectorUrl: String,
)

View File

@@ -9,17 +9,18 @@ import java.time.ZonedDateTime
* Response object returned when requesting organization domain SSO details.
*
* @property isSsoAvailable Whether or not SSO is available for this domain.
* @property domainName The organization's domain name.
* @property organizationIdentifier The organization's identifier.
* @property isSsoRequired Whether or not SSO is required.
* @property verifiedDate The date these details were verified.
* @property verifiedDate The date the domain was verified.
*/
@Serializable
data class OrganizationDomainSsoDetailsResponseJson(
@SerialName("ssoAvailable") val isSsoAvailable: Boolean,
@SerialName("domainName") val domainName: String,
@SerialName("organizationIdentifier") val organizationIdentifier: String,
@SerialName("ssoRequired") val isSsoRequired: Boolean,
@SerialName("ssoAvailable")
val isSsoAvailable: Boolean,
@SerialName("organizationIdentifier")
val organizationIdentifier: String,
@SerialName("verifiedDate")
@Contextual
@SerialName("verifiedDate") val verifiedDate: ZonedDateTime?,
val verifiedDate: ZonedDateTime?,
)

View File

@@ -7,6 +7,20 @@ import kotlinx.serialization.Serializable
* Response body from the SSO prevalidate request.
*/
@Serializable
data class PrevalidateSsoResponseJson(
@SerialName("token") val token: String?,
)
sealed class PrevalidateSsoResponseJson {
/**
* Models json body of a successful response.
*/
@Serializable
data class Success(
@SerialName("token") val token: String?,
) : PrevalidateSsoResponseJson()
/**
* Models json body of an error response.
*/
@Serializable
data class Error(
@SerialName("message") val message: String?,
) : PrevalidateSsoResponseJson()
}

View File

@@ -0,0 +1,64 @@
package com.x8bit.bitwarden.data.auth.datasource.network.model
import com.x8bit.bitwarden.data.auth.datasource.network.model.RegisterFinishRequestJson.Keys
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
/**
* Request body for register.
*
* @param email the email to be registered.
* @param emailVerificationToken token used to finish the registration process.
* @param masterPasswordHash the master password (encrypted).
* @param masterPasswordHint the hint for the master password (nullable).
* @param captchaResponse the captcha bypass token.
* @param userSymmetricKey the user key for the request (encrypted).
* @param userAsymmetricKeys a [Keys] object containing public and private keys.
* @param kdfType the kdf type represented as an [Int].
* @param kdfIterations the number of kdf iterations.
*/
@Serializable
data class RegisterFinishRequestJson(
@SerialName("email")
val email: String,
@SerialName("emailVerificationToken")
val emailVerificationToken: String,
@SerialName("masterPasswordHash")
val masterPasswordHash: String,
@SerialName("masterPasswordHint")
val masterPasswordHint: String?,
@SerialName("captchaResponse")
val captchaResponse: String?,
@SerialName("userSymmetricKey")
val userSymmetricKey: String,
@SerialName("userAsymmetricKeys")
val userAsymmetricKeys: Keys,
@SerialName("kdf")
val kdfType: KdfTypeJson,
@SerialName("kdfIterations")
val kdfIterations: UInt,
) {
/**
* A keys object containing public and private keys.
*
* @param publicKey the public key (encrypted).
* @param encryptedPrivateKey the private key (encrypted).
*/
@Serializable
data class Keys(
@SerialName("publicKey")
val publicKey: String,
@SerialName("encryptedPrivateKey")
val encryptedPrivateKey: String,
)
}

View File

@@ -1,7 +1,9 @@
package com.x8bit.bitwarden.data.auth.datasource.network.model
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonNames
/**
* Models response bodies for the register request.
@@ -46,26 +48,28 @@ sealed class RegisterResponseJson {
/**
* Represents the json body of an invalid register request.
*
* @param message
* @param validationErrors a map where each value is a list of error messages for each key.
* The values in the array should be used for display to the user, since the keys tend to come
* back as nonsense. (eg: empty string key)
*/
@OptIn(ExperimentalSerializationApi::class)
@Serializable
data class Invalid(
@SerialName("message")
val message: String?,
@JsonNames("message")
@SerialName("Message")
private val invalidMessage: String? = null,
@SerialName("validationErrors")
val validationErrors: Map<String, List<String>>?,
) : RegisterResponseJson()
/**
* A different register error with a message.
*/
@Serializable
data class Error(
@SerialName("Message")
val message: String?,
) : RegisterResponseJson()
private val validationErrors: Map<String, List<String>>?,
) : RegisterResponseJson() {
/**
* A generic error message.
*/
val message: String?
get() = validationErrors
?.values
?.firstOrNull()
?.firstOrNull()
?: invalidMessage
}
}

View File

@@ -0,0 +1,20 @@
package com.x8bit.bitwarden.data.auth.datasource.network.model
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
/**
* Hold the information necessary to resend the email with the
* new device verification code.
*
* @property email The user's email address.
* @property passwordHash The master password hash
*/
@Serializable
data class ResendNewDeviceOtpRequestJson(
@SerialName("Email")
val email: String,
@SerialName("MasterPasswordHash")
val passwordHash: String?,
)

View File

@@ -0,0 +1,23 @@
package com.x8bit.bitwarden.data.auth.datasource.network.model
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
/**
* Request body for send verification email.
*
* @param email the email to be registered.
* @param name the name to be registered.
* @param receiveMarketingEmails the answer to receive marketing emails.
*/
@Serializable
data class SendVerificationEmailRequestJson(
@SerialName("email")
val email: String,
@SerialName("name")
val name: String?,
@SerialName("receiveMarketingEmails")
val receiveMarketingEmails: Boolean,
)

View File

@@ -0,0 +1,45 @@
package com.x8bit.bitwarden.data.auth.datasource.network.model
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
/**
* The response body for sending a verification email.
*/
@Serializable
sealed class SendVerificationEmailResponseJson {
/**
* Models a successful json response.
*
* @param emailVerificationToken the token to verify the email.
*/
@Serializable
data class Success(
val emailVerificationToken: String?,
) : SendVerificationEmailResponseJson()
/**
* Represents the json body of an invalid request.
*
* @param validationErrors a map where each value is a list of error messages for each key.
* The values in the array should be used for display to the user, since the keys tend to come
* back as nonsense. (eg: empty string key)
*/
@Serializable
data class Invalid(
@SerialName("message")
private val invalidMessage: String? = null,
@SerialName("Message")
private val errorMessage: String? = null,
@SerialName("validationErrors")
val validationErrors: Map<String, List<String>>?,
) : SendVerificationEmailResponseJson() {
/**
* A generic error message.
*/
val message: String? get() = invalidMessage ?: errorMessage
}
}

View File

@@ -1,7 +1,9 @@
package com.x8bit.bitwarden.data.auth.datasource.network.model
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonNames
/**
* Decryption options related to a user's trusted device.
@@ -13,20 +15,26 @@ import kotlinx.serialization.Serializable
* @property hasManageResetPasswordPermission Whether or not the user has manage reset password
* permission.
*/
@OptIn(ExperimentalSerializationApi::class)
@Serializable
data class TrustedDeviceUserDecryptionOptionsJson(
@SerialName("EncryptedPrivateKey")
@SerialName("encryptedPrivateKey")
@JsonNames("EncryptedPrivateKey")
val encryptedPrivateKey: String?,
@SerialName("EncryptedUserKey")
@SerialName("encryptedUserKey")
@JsonNames("EncryptedUserKey")
val encryptedUserKey: String?,
@SerialName("HasAdminApproval")
@SerialName("hasAdminApproval")
@JsonNames("HasAdminApproval")
val hasAdminApproval: Boolean,
@SerialName("HasLoginApprovingDevice")
@SerialName("hasLoginApprovingDevice")
@JsonNames("HasLoginApprovingDevice")
val hasLoginApprovingDevice: Boolean,
@SerialName("HasManageResetPasswordPermission")
@SerialName("hasManageResetPasswordPermission")
@JsonNames("HasManageResetPasswordPermission")
val hasManageResetPasswordPermission: Boolean,
)

View File

@@ -39,5 +39,7 @@ enum class TwoFactorAuthMethod(val value: UInt) {
}
@Keep
private class TwoFactorAuthMethodSerializer :
BaseEnumeratedIntSerializer<TwoFactorAuthMethod>(TwoFactorAuthMethod.entries.toTypedArray())
private class TwoFactorAuthMethodSerializer : BaseEnumeratedIntSerializer<TwoFactorAuthMethod>(
className = "TwoFactorAuthMethod",
values = TwoFactorAuthMethod.entries.toTypedArray(),
)

View File

@@ -1,7 +1,9 @@
package com.x8bit.bitwarden.data.auth.datasource.network.model
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonNames
/**
* The options available to a user for decryption.
@@ -12,14 +14,18 @@ import kotlinx.serialization.Serializable
* device.
* @property keyConnectorUserDecryptionOptions Decryption options related to a user's key connector.
*/
@OptIn(ExperimentalSerializationApi::class)
@Serializable
data class UserDecryptionOptionsJson(
@SerialName("HasMasterPassword")
@SerialName("hasMasterPassword")
@JsonNames("HasMasterPassword")
val hasMasterPassword: Boolean,
@SerialName("TrustedDeviceOption")
@SerialName("trustedDeviceOption")
@JsonNames("TrustedDeviceOption")
val trustedDeviceUserDecryptionOptions: TrustedDeviceUserDecryptionOptionsJson?,
@SerialName("KeyConnectorOption")
@SerialName("keyConnectorOption")
@JsonNames("KeyConnectorOption")
val keyConnectorUserDecryptionOptions: KeyConnectorUserDecryptionOptionsJson?,
)

View File

@@ -0,0 +1,14 @@
package com.x8bit.bitwarden.data.auth.datasource.network.model
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
/**
* Request body object when retrieving organization verified domain SSO info.
*
* @param email The email address to check against.
*/
@Serializable
data class VerifiedOrganizationDomainSsoDetailsRequest(
@SerialName("email") val email: String,
)

View File

@@ -0,0 +1,35 @@
package com.x8bit.bitwarden.data.auth.datasource.network.model
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
/**
* Response object returned when requesting organization verified domain SSO details.
*
* @property verifiedOrganizationDomainSsoDetails The list of verified organization domain SSO
* details.
*/
@Serializable
data class VerifiedOrganizationDomainSsoDetailsResponse(
@SerialName("data")
val verifiedOrganizationDomainSsoDetails: List<VerifiedOrganizationDomainSsoDetail>,
) {
/**
* Response body for an organization verified domain SSO details.
*
* @property organizationName The name of the organization.
* @property organizationIdentifier The identifier of the organization.
* @property domainName The name of the domain.
*/
@Serializable
data class VerifiedOrganizationDomainSsoDetail(
@SerialName("organizationName")
val organizationName: String,
@SerialName("organizationIdentifier")
val organizationIdentifier: String,
@SerialName("domainName")
val domainName: String,
)
}

View File

@@ -0,0 +1,18 @@
package com.x8bit.bitwarden.data.auth.datasource.network.model
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
/**
* Models the request body for verify email token endpoint.
*
* @param email the email address of the user to verify.
* @param token the provided email verification token.
*/
@Serializable
data class VerifyEmailTokenRequestJson(
@SerialName("email")
val email: String,
@SerialName("emailVerificationToken")
val token: String,
)

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