Compare commits

...

896 Commits

Author SHA1 Message Date
Patrick Honkonen
6719534494 [PM-21357] Migrate ModifierExtensions to ui module (#5215) 2025-05-19 20:02:52 +00:00
Patrick Honkonen
183584f678 [PM-21386] Fix typo in sync with Bitwarden message (#5220) 2025-05-19 17:26:09 +00:00
David Perez
046bb0fa39 PM-21080: Remove the isRemotelyConfigured flag (#5193) 2025-05-19 15:56:19 +00:00
David Perez
9508b4ba90 PM-21701: Remove segmented control from Add Send Screen and update the screen title (#5217) 2025-05-19 14:48:26 +00:00
Patrick Honkonen
07e4e6a806 [PM-21726] Move OmitFromCoverage to annotation module (#5214) 2025-05-19 13:19:16 +00:00
David Perez
4d142a6a5c PM-21133: Add View Send navigation (#5187) 2025-05-16 18:48:22 +00:00
Patrick Honkonen
f02a3a249b [PM-21703] Consolidate Robolectric and Compose test base classes (#5210) 2025-05-16 17:48:23 +00:00
David Perez
28149532a0 PM-21707: Allow nullable captcha token (#5213) 2025-05-16 16:58:12 +00:00
David Perez
7f5426dea0 PM-19770: Fix the verify email domains (#5212) 2025-05-16 15:49:13 +00:00
Patrick Honkonen
d7d703c977 [PM-21692] Move WindowSize and related util to ui module (#5208) 2025-05-16 15:38:45 +00:00
bw-ghapp[bot]
7fda5d799f Autosync Crowdin Translations (#5211)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2025-05-16 13:42:32 +00:00
Patrick Honkonen
3c1a0a352a [PM-21356] Migrate ui ListExtensions to ui module (#5200) 2025-05-15 21:45:50 +00:00
David Perez
cb0b135429 PM-21696: Make sure environment is up-to-date (#5209) 2025-05-15 21:44:44 +00:00
Patrick Honkonen
7422efd07a [PM-21366] Migrate BitwardenTheme to ui module (#5207) 2025-05-15 19:52:34 +00:00
Patrick Honkonen
27a9fc52b7 [PM-21657] Migrate Typography to the ui module (#5198) 2025-05-15 15:55:51 +00:00
Patrick Honkonen
c105c102a3 [PM-21359] Migrate StringExtensions to ui module (#5202) 2025-05-15 15:51:47 +00:00
Patrick Honkonen
c83bd8f4a8 [PM-21361] Delete unused ToastUtils (#5203) 2025-05-15 14:20:17 +00:00
Patrick Honkonen
d820b3345a [PM-21676] Relocate Authenticator local manager providers (#5206) 2025-05-15 14:09:39 +00:00
Patrick Honkonen
b71b01d48d [PM-21655] Migrate BitwardenShapes to ui module (#5197) 2025-05-15 13:47:05 +00:00
Patrick Honkonen
8a0f67c0e9 [PM-21361] Migrate TopAppBarScrollBehaviorExtensions to ui module (#5204) 2025-05-15 13:45:01 +00:00
Patrick Honkonen
b4d85e07ba [PM-21358] Migrate PaddingValuesExtensions.kt to ui module (#5201) 2025-05-15 13:40:09 +00:00
David Perez
dfd58822b7 PM-21445: Update the Send delete buttons (#5195) 2025-05-14 21:45:59 +00:00
Patrick Honkonen
f14a1404e3 [PM-21654] Migrate ColorScheme to ui module (#5196) 2025-05-14 21:11:28 +00:00
David Perez
f1950600a1 PM-21641: Allow delete and restore logic to be remotely configured (#5194) 2025-05-14 19:23:21 +00:00
Patrick Honkonen
7d6b6a5959 [PM-21575] Migrate AppTheme enum class to ui module (#5182) 2025-05-14 17:53:02 +00:00
David Perez
ea70191429 PM-21631: Update Edit Send Screen to navigate to Vault Unlocked root (#5190) 2025-05-14 17:51:56 +00:00
David Perez
db956b9b91 PM-21634: Update loading Dialog to be a real dialog (#5191) 2025-05-14 17:51:06 +00:00
David Perez
119812507a Remove logging from tests (#5192) 2025-05-14 17:50:55 +00:00
Patrick Honkonen
a97c962428 [DynamicColors] Update toggle button switch dynamic color scheme (#4886) 2025-05-14 14:17:33 +00:00
David Perez
456adf3158 PM-21610: Update SearchScreen and VaultItemListingScreen for better Sends support (#5188) 2025-05-14 13:57:29 +00:00
Patrick Honkonen
62cb962298 [DynamicColors] Add support for dynamic colors (#4850) 2025-05-13 21:59:44 +00:00
Patrick Honkonen
7f4e65d7e4 [PM-21567] Implement CredentialEntryBuilder interface (#5177) 2025-05-13 21:18:16 +00:00
David Perez
860a2e265f PM-21134, PM-21135, PM-21136, PM-21137: Create View Send Screen (#5178) 2025-05-13 18:47:43 +00:00
David Perez
6d68c3ae24 PM-21591: Add navigation routing for the ViewSendScreen (#5185) 2025-05-13 17:28:10 +00:00
David Perez
97b8c51ab3 PM-21598: Update multi-tonal illustrations and icons to support dynamic colors (#5186) 2025-05-13 17:01:47 +00:00
Patrick Honkonen
a2449a2f19 [PM-21574] Migrate CardStyle to the UI module (#5181) 2025-05-13 17:00:43 +00:00
Patrick Honkonen
1d73bbd440 [PM-21585] Display item folder location when only in a single folder (#5184) 2025-05-13 15:13:32 +00:00
Patrick Honkonen
da62244000 [PM-21573] Migrate EventsEffect to ui module (#5180) 2025-05-13 14:13:57 +00:00
Patrick Honkonen
11b767c98f [PM-21572] Migrate NoPersonalizedLearningInterceptor to ui module (#5179) 2025-05-12 21:48:50 +00:00
David Perez
cd4db467e3 Clean up lint warnings (#5176) 2025-05-12 17:52:56 +00:00
David Perez
7fdf165273 PM-21555: Fix crash on older server versions (#5174) 2025-05-12 16:21:55 +00:00
renovate[bot]
e49bab637c [deps]: Lock file maintenance (#5171)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-12 13:37:51 +00:00
renovate[bot]
14ac194cb7 [deps]: Update com.google.devtools.ksp to v2.1.20-2.0.1 (#5170)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-12 13:37:40 +00:00
aj-bw
578f96a944 BRE-609/android-pr-target-change (#5092) 2025-05-12 13:13:24 +00:00
David Perez
2c71ab7d27 PM-21445: Update Add Edit Sends UI (#5166) 2025-05-09 21:30:28 +00:00
David Perez
c5ee389231 PM-21351: Clear scemantics on new send button (#5165) 2025-05-09 20:51:14 +00:00
Patrick Honkonen
5037af07c7 [PM-21367] Support passkey requests with multiple options (#5161) 2025-05-09 18:23:59 +00:00
bw-ghapp[bot]
d6d1e8e97f Autosync Crowdin Translations (#5164)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2025-05-09 13:24:17 +00:00
David Perez
652168f946 PM-21397: Create initial View Send scaffold (#5163) 2025-05-08 22:55:07 +00:00
Patrick Honkonen
d4d5d2c2a8 [PM-21355] Migrate LifecycleEventEffect to ui module (#5162) 2025-05-08 22:06:59 +00:00
David Perez
ed148c2089 PM-21252: Create mock NavHostController for navigation testing (#5159) 2025-05-08 19:58:03 +00:00
Patrick Honkonen
564304616d [PM-21365] Migrate BitwardenColorScheme to ui module (#5158) 2025-05-08 19:48:51 +00:00
Patrick Honkonen
0d0b8d6780 [PM-21353] Migrate DensityExtensions to ui module (#5157) 2025-05-08 19:32:04 +00:00
David Perez
472e41f6bc PM-21351: Hide new send button from accessibility when on the empty sends screen (#5160) 2025-05-08 18:52:24 +00:00
Patrick Honkonen
fb9c68755a [PM-21328] Migrate BaseViewModelTest and MainDispatcherExtension to test fixtures (#5146) 2025-05-08 16:54:55 +00:00
David Perez
d7671f47ea PM-21348: Type-safe navigation for authenticator (#5156) 2025-05-08 16:31:10 +00:00
Patrick Honkonen
9c7270df69 [PM-21344] Migrate BackgroundEvent to ui module (#5155) 2025-05-08 16:08:07 +00:00
David Perez
733290569c Update Lifecycle library to v2.9.0 (#5150) 2025-05-08 15:21:34 +00:00
David Perez
cbaa8a329e Fix duplicated launched effect key (#5154) 2025-05-08 14:27:22 +00:00
David Perez
f968d7698a PM-21332: Move NavGraphBuilder extensions to common UI module (#5147) 2025-05-08 14:15:42 +00:00
Patrick Honkonen
68cd08b069 [PM-21325] Migrate BaseViewModel to ui module (#5145) 2025-05-08 14:06:16 +00:00
David Perez
84683894a6 Update AGP to 8.10.0 (#5152) 2025-05-08 13:44:09 +00:00
David Perez
ed2d9ecb80 Update Dagger Hilt to v2.56.2 (#5151) 2025-05-08 13:43:05 +00:00
David Perez
8f4d46954e Update the navigation component to v2.9.0 (#5149) 2025-05-08 13:40:13 +00:00
David Perez
a9fc6ff589 Update compose BOM to 2025.05.00 (#5148) 2025-05-08 13:39:42 +00:00
André Bispo
5c8f5670e4 [PM-21203] Old user migration login error. (#5136) 2025-05-07 21:25:32 +00:00
David Perez
eec88d4924 PM-21324: Move common UI transitions to UI module (#5144) 2025-05-07 21:14:47 +00:00
Patrick Honkonen
82da193e55 [PM-21199] Rename FIDO2 objects to reference CredentialManager (#5128) 2025-05-07 20:25:38 +00:00
David Perez
76fb85ac1f Update Compose BOM to 2025.04.01 (#5134) 2025-05-07 19:16:32 +00:00
Patrick Honkonen
625ac0ea5f Update mockk to version 1.14.2 (#5139) 2025-05-07 18:14:01 +00:00
David Perez
4e88833737 Clean up how we handle test coverage on navigation files (#5142) 2025-05-07 17:53:07 +00:00
David Perez
ecea2ef7c1 PM-21285: Ensure route data is serializable (#5141) 2025-05-07 16:53:14 +00:00
Patrick Honkonen
0eccc7197e Update Protocol Buffers library version (#5140) 2025-05-07 15:36:06 +00:00
David Perez
5dd34afe81 PM-19771: Allow forward slashes in emails (#5137) 2025-05-06 22:12:48 +00:00
Patrick Honkonen
5abcc5b1f7 [PM-17222] Enhance autofill accessibility processor (#5116) 2025-05-06 21:44:06 +00:00
David Perez
6fec95cb84 PM-21255: Implement type-safe navigation (#5131) 2025-05-06 20:46:53 +00:00
David Perez
1d68c1fdf6 Update Firebase BOM to v33.13.0 (#5135) 2025-05-06 20:22:23 +00:00
David Perez
0c2de427dc Update WorkManager to 2.10.1 (#5132) 2025-05-06 20:13:28 +00:00
David Perez
f932682949 PM-21110: Add a generate crash button to the debug menu (#5125) 2025-05-06 18:51:03 +00:00
David Perez
e1f432ea5d Update the Navigation component library (#5130) 2025-05-06 14:47:34 +00:00
Patrick Honkonen
31de7fc331 Remove unused FeatureFlagsConfiguration (#5129) 2025-05-06 00:56:18 +00:00
David Perez
07469672ba PM-21156: Fix ConfigService retrofit instance (#5126) 2025-05-05 14:51:47 +00:00
André Bispo
1a2beea770 [PM-18092] Update cipher delete restore permissions (#5075)
Co-authored-by: Patrick Honkonen <1883101+SaintPatrck@users.noreply.github.com>
2025-05-05 13:56:58 +00:00
aj-rosado
639ca02739 [PM-14222] Managed user account deletion prevention (#5114)
Co-authored-by: Matt Portune <mportune@macbook-work.lan>
2025-05-02 20:22:58 +00:00
Patrick Honkonen
186bea2d1d [PM-20127] Prevent double UV prompt during FIDO 2 operations (#5124) 2025-05-02 14:52:14 +00:00
bw-ghapp[bot]
3dc187da87 Autosync Crowdin Translations (#5122)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2025-05-02 13:14:01 +00:00
aj-rosado
69708c1285 [PM-20037] Remove native-carousel-flow feature flag (#5121) 2025-05-01 21:48:25 +00:00
Patrick Honkonen
ad1566f4b0 [PM-14846] Improve IP Address and Port Handling in StringExtensions (#5118) 2025-05-01 20:39:01 +00:00
David Perez
32d0ca7bcd PM-21088: Remove the unused IgnoreEnvironmentCheck feature flag (#5119) 2025-05-01 16:49:58 +00:00
André Bispo
0353f0c153 [PM-20466] Invalid master password returns generic error. (#5100) 2025-05-01 14:37:59 +00:00
Patrick Honkonen
7436122953 [PM-19846] Mark network module implementation details internal (#5115) 2025-05-01 14:26:19 +00:00
Patrick Honkonen
23ef5b38fe [PM-20508] Centralize passkey credential entry creation (#5033) 2025-04-30 15:31:27 +00:00
Patrick Honkonen
fe1fe770c7 Use Google's Digital Asset Links API to verify digital asset links (#5101) 2025-04-30 13:39:04 +00:00
David Perez
240bca3c2f PM-20552: Ensure userState does not emit while the active user is unlocking (#5112) 2025-04-29 20:56:31 +00:00
David Perez
8c7cc27c5d PM-20966: Log app state changes (#5110) 2025-04-29 20:56:15 +00:00
Patrick Honkonen
a4aa9837a6 [PM-17686] Allow overwriting TLS certificates (#5111) 2025-04-28 21:44:41 +00:00
Patrick Honkonen
b901de9ddf Correct indention in app/strings.xml (#5109) 2025-04-28 18:24:33 +00:00
Patrick Honkonen
96df23f0af Drop all tables when performing destructive migration in Authenticator (#5108) 2025-04-28 15:28:59 +00:00
renovate[bot]
0eb149941d [deps]: Update gh minor (#5102)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-28 14:23:36 +00:00
renovate[bot]
6f44e64375 [deps]: Update kotlin (#5103)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-28 14:22:46 +00:00
renovate[bot]
cda86b842e [deps]: Lock file maintenance (#5106)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-28 13:32:05 +00:00
renovate[bot]
e1608b426d [deps]: Update sonarsource/sonarqube-scan-action action to v5 (#5105)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-28 13:28:19 +00:00
renovate[bot]
b6017baf54 [deps]: Update actions/create-github-app-token action to v2 (#5104)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-28 13:21:09 +00:00
Patrick Honkonen
0f6d15d6a6 [PM-20549] Introduce BitwardenServiceClient (#5091) 2025-04-25 20:26:01 +00:00
André Bispo
cd11164544 [PM-18942] Force sync for revoke/restore notification. (#5098) 2025-04-25 16:14:17 +00:00
David Perez
1b9d2bfab4 Omit navigation files from test coverage (#5095) 2025-04-25 15:46:54 +00:00
bw-ghapp[bot]
373b789fbb Autosync Crowdin Translations (#5096)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2025-04-25 14:08:02 +00:00
André Bispo
985e576a82 [PM-20148] Remove app-review-prompt feature flag. (#5093) 2025-04-24 20:18:50 +00:00
David Perez
b11e4481f9 PM-20365: Add pre-auth settings support (#5094) 2025-04-24 17:48:03 +00:00
David Perez
5ac0f2b111 Update to AGP 8.9.2 (#5089) 2025-04-23 19:54:09 +00:00
David Perez
37a0d19efc PM-20400: Display snackbar confirming log deletion (#5088) 2025-04-23 19:53:44 +00:00
David Perez
54983bc92e Add helper for concurrent map (#5086) 2025-04-23 19:53:05 +00:00
David Perez
36989875a6 Update to Junit 5.12.2 (#5087) 2025-04-23 19:52:48 +00:00
David Perez
88b0fe59bb PM-20516: Update NetworkConnectionManager (#5085) 2025-04-23 19:52:29 +00:00
David Perez
e4d0c48eed PM-20510: Log whenever the screen changes (#5083) 2025-04-23 19:47:06 +00:00
Patrick Honkonen
bd364a1108 Update Room dependency to version 2.7.1 (#5090) 2025-04-23 19:10:19 +00:00
Patrick Honkonen
39b88d6064 [PM-20389] Define and implement network module CertificateProvider (#5073) 2025-04-22 19:14:06 +00:00
David Perez
da709e039b PM-19809: Update flight recorder tooltip url (#5082) 2025-04-22 19:12:09 +00:00
David Perez
31311964d0 Cleanup minor lint warnings (#5081) 2025-04-21 21:35:05 +00:00
David Perez
8cbd7369c5 PM-19594: Add flight recorder banner (#5079) 2025-04-21 14:46:53 +00:00
David Perez
2a1669cf87 PM-20426: Update Block Autofill UI (#5078) 2025-04-21 14:04:05 +00:00
David Perez
4c4007a734 PM-20385: Delete confirmation dialog should dismiss on confirmation (#5077) 2025-04-21 14:03:45 +00:00
David Perez
70dc82d1b6 PM-20422: Update tab navigation (#5076) 2025-04-21 14:03:20 +00:00
bw-ghapp[bot]
021ece138b Autosync Crowdin Translations (#5074)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2025-04-18 14:30:44 +00:00
aj-rosado
bee09de972 [PM-18936] Show key connector domain (#5034) 2025-04-17 19:20:50 +00:00
David Perez
33da0d8138 PM-20375: Events to use their own scope (#5072) 2025-04-17 17:52:20 +00:00
Patrick Honkonen
d5d8da2410 [PM-20373] Migrate Digital Asset Link API to network module (#5071) 2025-04-17 16:55:01 +00:00
Patrick Honkonen
3722a45359 [PM-20305] Migrate BaseUrlInterceptor and BaseUrlInterceptors to network module (#5068) 2025-04-17 16:28:05 +00:00
Patrick Honkonen
f23079b5ac [PM-20196] Migrate SyncService to the network module (#5056) 2025-04-17 15:59:33 +00:00
David Perez
524ddb6d0c Update Androidx libraries (#5070) 2025-04-17 14:38:38 +00:00
Patrick Honkonen
0d40d1e569 [PM-20195] Migrate SendsService to network module (#5055) 2025-04-17 13:54:30 +00:00
David Perez
4f65044179 PM-19593: Update expiration string to be 'Expires on <date>' (#5069) 2025-04-16 18:56:34 +00:00
David Perez
d67e74e48b PM-19620: Auto-delete flight recorder logs after 30 days (#5062) 2025-04-16 17:09:31 +00:00
Patrick Honkonen
b760b58669 Update user-agent header in Authenticator app (#5067) 2025-04-16 17:03:08 +00:00
Patrick Honkonen
36e6fbc14c [PM-20193] Migrate DownloadService to network module (#5053) 2025-04-16 16:46:30 +00:00
Patrick Honkonen
0be26c1eda [PM-20306] Migrate Auth Token Interceptor (#5065) 2025-04-16 16:41:43 +00:00
Patrick Honkonen
3311086dfc [PM-20309] Migrate Environment and EnvironmentUrlDataJson to data module (#5063) 2025-04-16 16:37:29 +00:00
David Perez
c912a3f12a PM-19622: Add ability to share flight recorder logs (#5060) 2025-04-16 15:43:14 +00:00
David Perez
e67790438e Update to latest Mockk (#5066) 2025-04-16 15:37:58 +00:00
Patrick Honkonen
ff72efe0ed [PM-20127] Only prompt passkey user verification once (#5026) 2025-04-16 15:35:25 +00:00
Patrick Honkonen
9dd71eaea2 [PM-20304] Migrate HeadersInterceptor to network module (#5061) 2025-04-16 15:09:00 +00:00
Patrick Honkonen
2d416eade5 [PM-20192] Migrate CiphersService to network module (#5052) 2025-04-16 15:08:17 +00:00
Patrick Honkonen
83de8b888d [PM-20191] Migrate OrganizationService to network module (#5049) 2025-04-15 19:42:21 +00:00
Patrick Honkonen
e35be360d7 [PM-20190] Migrate NewAuthRequestService to network module (#5048) 2025-04-15 18:20:25 +00:00
Patrick Honkonen
899689ba7b [PM-20189] Migrate IdentityService and related components to network module (#5047) 2025-04-15 16:35:47 +00:00
Patrick Honkonen
71237cb3a7 Make MobileErrorReporting flag remotely configured (#5015) 2025-04-15 16:07:49 +00:00
Álison Fernandes
18c7333cf3 Revert "[PM-19821] Consolidate scan.yml and scan-ci.yml" (#5058) 2025-04-15 14:42:01 +00:00
Patrick Honkonen
b6d9bee266 Update fastlane (#5025) 2025-04-15 14:23:57 +00:00
Patrick Honkonen
868f8091d2 [PM-20188] Migrate HaveIBeenPwnedService to network module (#5046) 2025-04-15 14:01:21 +00:00
Patrick Honkonen
dcd2d26d6c [PM-20187] Migrate DevicesService to the network module (#5040) 2025-04-14 21:28:34 +00:00
Patrick Honkonen
548c9ee092 [PM-20194] Migrate FolderService and related models to network module (#5054) 2025-04-14 20:55:50 +00:00
David Perez
186741e052 Use explicit timezone in tests (#5057) 2025-04-14 20:52:25 +00:00
André Bispo
d989c61bc2 [PM-19613] Save attachment error message update (#5013) 2025-04-14 20:50:59 +00:00
David Perez
8f311861e3 PM-19593: Display all flight recorder logs (#5050) 2025-04-14 20:00:20 +00:00
David Perez
942b95927f Limit network logs in production (#5051) 2025-04-14 18:29:56 +00:00
Patrick Honkonen
f087b6aac7 [PM-20186] Migrate AuthRequestsService to the network module (#5039) 2025-04-14 18:28:55 +00:00
Patrick Honkonen
87ef0e2961 [PM-20066] Migrate EventService and EventServiceImpl to network module (#5036) 2025-04-14 14:31:17 +00:00
David Perez
b60f30d8a1 PM-19592: Enabled and disable flight recorder (#5035) 2025-04-14 14:17:55 +00:00
github-actions[bot]
c553d2caec Update Google privileged browsers list (#5045)
Co-authored-by: GitHub Actions Bot <actions@github.com>
Co-authored-by: Patrick Honkonen <phonkonen@bitwarden.com>
2025-04-14 13:47:21 +00:00
Patrick Honkonen
d1ba730012 [PM-20185] Migrate AccountService to network module (#5038) 2025-04-11 21:33:05 +00:00
Patrick Honkonen
944eb64562 [PM-20067] Migrate PushService to the network module (#5037) 2025-04-11 21:09:14 +00:00
David Perez
12ce1e5229 PM-20133: Add initial logging logic (#5029) 2025-04-11 17:33:06 +00:00
David Perez
b72da1ba69 PM-20172: Display errors from WebAuthN results (#5032) 2025-04-11 15:53:40 +00:00
Patrick Honkonen
ed97695228 [PM-20073] Migrate SyncApi to the network module (#5028) 2025-04-11 14:18:09 +00:00
bw-ghapp[bot]
05b1266b1b Autosync Crowdin Translations (#5030)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2025-04-11 13:08:49 +00:00
Patrick Honkonen
8153b25d89 [PM-20072] Migrate SendsApi to network module (#5027) 2025-04-11 13:05:11 +00:00
Patrick Honkonen
2fd5ab6f8d [PM-20071] Migrate FoldersApi to network module (#5023) 2025-04-10 22:30:25 +00:00
Patrick Honkonen
392695cb54 [PM-20069] Migrate CiphersApi to network module (#5021) 2025-04-10 21:09:21 +00:00
David Perez
d7f771990e PM-20123: Add flight recorder metadata (#5024) 2025-04-10 20:57:24 +00:00
Patrick Honkonen
dd0f08d759 [PM-19864] Migrate UnauthenticatedOrganizationApi to network module (#5019) 2025-04-10 20:42:26 +00:00
Patrick Honkonen
dd9ca853a7 [PM-20070] Migrate DownloadApi to network module (#5022) 2025-04-10 20:09:44 +00:00
Patrick Honkonen
2ef0ca3620 [PM-20068] Migrate AzureApi to network module (#5020) 2025-04-10 20:03:47 +00:00
Patrick Honkonen
97ef0ec004 [PM-19863] Migrate UnauthenticatedKeyConnectorApi to network module (#5018) 2025-04-10 19:16:04 +00:00
Patrick Honkonen
9d7df2bc10 [PM-19862] Migrate UnauthenticatedIdentityApi to the network module (#5017) 2025-04-10 15:19:46 +00:00
Patrick Honkonen
cb05787256 [PM-19861] Migrate UnauthenticatedDevicesApi to network module (#5016) 2025-04-10 15:15:50 +00:00
Patrick Honkonen
8767f2dd24 Update androidx.credentials (#4919) 2025-04-09 15:35:06 +00:00
David Perez
bf1ed690a4 PM-20005: Make the BitwardenOverflowActionItem more generic (#5011) 2025-04-09 15:04:53 +00:00
Patrick Honkonen
a12f325815 [PM-19958] Migrate Text to the UI module (#5010) 2025-04-08 20:33:45 +00:00
Auj625197595
c2872b6b9b [PM-18559] add kitobrowser series support (#4770)
Co-authored-by: Patrick Honkonen <1883101+SaintPatrck@users.noreply.github.com>
2025-04-08 19:53:12 +00:00
Patrick Honkonen
622d68e40c [PM-19952] Provide SharedPreference from the data module (#5006) 2025-04-08 19:46:16 +00:00
David Perez
6ebece1b1e PM-19978: Build out flight recorder UI (#5009) 2025-04-08 19:11:05 +00:00
Patrick Honkonen
c540d3ef47 [PM-19951] Move EncryptedPreferences to the correct di package (#5004) 2025-04-08 17:00:04 +00:00
Patrick Honkonen
385f5efac5 [PM-19959] Introduce a new UI module (#5008) 2025-04-08 16:12:12 +00:00
Patrick Honkonen
6668af58d2 [PM-19949] Provide ConfigDiskSource from data module (#5003) 2025-04-08 16:03:04 +00:00
Patrick Honkonen
c5e216783e [PM-19948] Migrate ServerConfigRepository to data module (#5002) 2025-04-07 21:58:39 +00:00
Álison Fernandes
acf222d151 [PM-19821] Consolidate scan.yml and scan-ci.yml (#4969)
Co-authored-by: Matt Andreko <mandreko@bitwarden.com>
2025-04-07 20:19:29 +00:00
Patrick Honkonen
1df96fdb62 [PM-19947] Provide system clock in the core module (#5000) 2025-04-07 20:03:53 +00:00
David Perez
942f6e2475 PM-19938: Add empty and loading state to the recorded logs screen (#5001) 2025-04-07 18:33:15 +00:00
Patrick Honkonen
2176b61cd3 [PM-19905] Migrate DispatcherManager to data module (#4999) 2025-04-07 18:16:04 +00:00
David Perez
4a63a709b8 PM-19937: Make navigation rail scrollable (#5005) 2025-04-07 18:15:23 +00:00
Patrick Honkonen
62cfcbbd72 Remove unused FeatureFlagRepository and FeatureFlagDiskSource (#4998) 2025-04-07 13:07:13 +00:00
Patrick Honkonen
538f1feb2e [PM-19872] Migrate UnencryptedPreferences to data module (#4994) 2025-04-04 20:09:20 +00:00
David Perez
70e42a27db Bump internal version name (#4997) 2025-04-04 19:45:45 +00:00
David Perez
4d9a19f43c PM-19645: Remove the new device UI email access flow (#4996) 2025-04-04 19:41:34 +00:00
Patrick Honkonen
dda8237ce5 [PM-19870] Migrate ServerConfig and ConfigDiskSource to the data module (#4992) 2025-04-04 18:33:54 +00:00
Patrick Honkonen
c4f54ee93c [PM-19860] Migrate UnauthenticateAuthRequestsApi and models to network module (#4990) 2025-04-04 17:33:55 +00:00
Patrick Honkonen
cac22346dd [PM-19859] Migrate UnauthenticatedAccountsApi and models to network module (#4989) 2025-04-04 16:45:20 +00:00
Patrick Honkonen
3f35ace6e9 [PM-19871] Migrate EncryptedPreferences to data module (#4993) 2025-04-04 14:38:50 +00:00
Patrick Honkonen
d1e4078c5a [PM-19851] Migrate network AuthenticatedAccountsApi to network module (#4982) 2025-04-04 14:17:37 +00:00
bw-ghapp[bot]
241a89fe13 Autosync Crowdin Translations (#4995)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2025-04-04 13:55:25 +00:00
David Perez
4df1b245e8 PM-19873: Migrate the screen capture feature from user-scoped to app-scoped (#4972) 2025-04-03 22:02:53 +00:00
Patrick Honkonen
853069ee1c [PM-19866] Migrate BaseEncryptedDiskSource to data module (#4991) 2025-04-03 21:52:54 +00:00
Patrick Honkonen
1149e91dd5 [PM-19858] Migrate HaveIBeenPwnedApi to network module (#4988) 2025-04-03 21:34:39 +00:00
Patrick Honkonen
d5de173431 [PM-19857] Migrate AuthenticatedOrganizationApi and models to network module (#4987) 2025-04-03 21:34:35 +00:00
Patrick Honkonen
f6d5302a73 [PM-19856] Migrate KeyConnectorApi and models to network module (#4986) 2025-04-03 21:34:30 +00:00
Patrick Honkonen
0ea7d00e93 [PM-19855] Migrate AuthenticatedDevicesApi and models to network module (#4985) 2025-04-03 21:34:10 +00:00
Patrick Honkonen
ebdf5f816a [PM-19854] Migrate AuthenticatedAuthRequestsApi to network module (#4984) 2025-04-03 21:33:32 +00:00
Patrick Honkonen
85109a2e4b [PM-19849] Move PushApi and PushTokenRequest to network module (#4979) 2025-04-03 21:18:12 +00:00
Patrick Honkonen
5017e935d7 [PM-19845] Migrate BaseDiskSource to data module (#4978) 2025-04-03 19:34:52 +00:00
David Perez
ce0aa7adda Update Firbase BOM to the latest version (33.12.0) (#4981) 2025-04-03 18:44:10 +00:00
David Perez
111d141fac PM-19850: Update dialog scrim (#4980) 2025-04-03 18:32:43 +00:00
Patrick Honkonen
4676f4bf8c [PM-19841] Migrate Event API and models to network module (#4976) 2025-04-03 18:22:53 +00:00
Patrick Honkonen
321a764f20 [PM-19831] Migrate ConfigService to network module (#4971) 2025-04-03 18:15:51 +00:00
David Perez
5d4df86bc9 PM-19812: Navigation Rail design feedback (#4977) 2025-04-03 17:37:03 +00:00
Patrick Honkonen
291c568583 [PM-19840] Migrate BaseEnumeratedIntSerializer to core module (#4975) 2025-04-03 16:06:36 +00:00
Patrick Honkonen
7938c8c2bb [PM-19832] Create data module (#4973) 2025-04-03 14:42:12 +00:00
David Perez
1fecd4af5f PM-19591: Initial flight recorder UI (#4970) 2025-04-03 13:42:13 +00:00
David Perez
1e6f896328 PM-19830: Updating padding for last sync time label (#4974) 2025-04-03 13:41:38 +00:00
Patrick Honkonen
e67a143474 [PM-19813] Migrate BaseServiceTest to Network module and enable test fixtures (#4967) 2025-04-02 21:12:36 +00:00
David Perez
a6862bb791 PM-19812: Add navigation rail (#4966) 2025-04-02 21:04:29 +00:00
Patrick Honkonen
d70e658c8b [PM-19783] Migrate ConfigApi and ConfigResponseJson to network module (#4964) 2025-04-02 20:07:41 +00:00
Álison Fernandes
f43702cb83 Set SARIF upload branch to the merge commit ref/sha retrieved from GH CLI (#4958) 2025-04-02 19:32:59 +00:00
Patrick Honkonen
20bda929b3 [PM-19820] Replace ResultCallAdapterFactory in authenticator module (#4968) 2025-04-02 18:48:45 +00:00
Patrick Honkonen
ce139623d6 [PM-19793] Migrate ZonedDateTimeSerializer to core module (#4960) 2025-04-02 17:42:51 +00:00
David Perez
8e7de92609 PM-19807: Remove IconResource class (#4963) 2025-04-02 15:21:58 +00:00
Patrick Honkonen
b82b1ad570 Update CODEOWNERS (#4965) 2025-04-02 15:19:29 +00:00
Patrick Honkonen
56cce8ffdd [PM-19782] Migrate network error handling to network module (#4957) 2025-04-02 15:04:59 +00:00
Patrick Honkonen
7abae5e86a Update network module minSdk version (#4961) 2025-04-02 14:18:35 +00:00
Patrick Honkonen
862384db3a [PM-19738] Migrate NetworkResultCallAdapter to network module (#4949) 2025-04-02 13:40:43 +00:00
David Perez
01c4a3db03 PM-19705: Log reason for logout (#4959) 2025-04-02 13:00:17 +00:00
David Perez
e5ddeb44fd PM-19645: Remove new device feature flags (#4950) 2025-04-02 12:59:48 +00:00
David Perez
a476436bff Update the Hilt and Androidx dependencies (#4954) 2025-04-01 21:40:22 +00:00
Álison Fernandes
d3e14e8f52 [PM-19772] Remove scan-authenticator.yml (#4952) 2025-04-01 17:20:19 +00:00
Álison Fernandes
36fa907d87 Remove scan-authenticator.yml 2025-04-01 17:50:35 +01:00
Phil Cappelli
a4ee8017ae PM-19131 - Custom hidden fields not working properly if TOTP also configured (#4916) 2025-04-01 16:38:18 +00:00
Patrick Honkonen
aa35e2f93c [PM-19625] Migrate DataStateExtensions to core module (#4943) 2025-04-01 16:09:20 +00:00
Philip Cappelli
40179429bf Merge branch 'main' into phil/PM-19131-Custom-hidden-fields-not-working-properly-if-TOTP-also-configured 2025-04-01 11:59:15 -04:00
Philip Cappelli
bdf50fd1a6 PR comments 2025-04-01 11:59:03 -04:00
Patrick Honkonen
445d6ec3b8 [PM-19738] Create network module (#4948) 2025-04-01 14:32:54 +00:00
Patrick Honkonen
c304a4306f [PM-19627] Migrate JsonExtensions to core module (#4932) 2025-04-01 14:14:40 +00:00
Philip Cappelli
f82bda5bce lint fixes 2025-03-31 17:21:28 -04:00
Patrick Honkonen
a2f4e4f3b5 [PM-19738] Create network module
Create a library module responsible for communicating with the Bitwarden network API.

Additionally, the following changes were made to checks and workflows:
- Updated `build.gradle.kts` to include Kover for the `network` module.
- Updated `Fastfile` to include lint, test and kover report generation tasks for the `network` module.
2025-03-31 17:19:51 -04:00
Philip Cappelli
d4c079140d remove space 2025-03-31 17:09:30 -04:00
Philip Cappelli
f1c82eb027 Merge branch 'main' into phil/PM-19131-Custom-hidden-fields-not-working-properly-if-TOTP-also-configured 2025-03-31 17:08:35 -04:00
Philip Cappelli
932eced64e clean up 2025-03-31 17:07:15 -04:00
Patrick Honkonen
1eced037a4 [PM-19627] Move Json extension functions to core module
Move JsonExtensions and related tests to `core` module.

- Moved `decodeFromStringOrNull` and related testing from `app` and `authenticator` modules to `core` module.
- Updated all usages of `decodeFromStringOrNull` in `app` and `authenticator` to the new location in `core`.
- Deleted unused `JsonExtensionsTest` and `JsonExtensions.kt` in `app` and `authenticator`.
- Updated dependencies for core.
2025-03-31 17:06:06 -04:00
Philip Cappelli
a4fb50d3d8 revert previous changes and go back to hash solution 2025-03-31 17:05:19 -04:00
Patrick Honkonen
9a50399116 Migrate DataStateExtensions to core module
Move `DataStateExtensions` to the `core` module.

- Deleted `DataStateExtensions.kt` from `authenticator` and `app` modules.
- Updated all imports.
- Added `junit5` and `kotlinx.coroutines.test` test implementation to `core` module.
2025-03-31 16:55:09 -04:00
Patrick Honkonen
5d5bc25a45 [PM-19652] Consolidate check configurations (#4937) 2025-03-31 21:46:19 +01:00
Patrick Honkonen
af528fdd82 Add matching fallback for the beta build type to release (#4946) 2025-03-31 19:56:26 +00:00
David Perez
7d119fb552 Update to AGP 8.9.1 (#4947) 2025-03-31 19:56:18 +00:00
David Perez
81b43d13b0 PM-19404: Improve email validation and validation error parsing (#4945) 2025-03-31 19:36:01 +00:00
Patrick Honkonen
cd86413ff6 Fix detekt issues in authenticator tests (#4944) 2025-03-31 19:20:10 +00:00
Dave Severns
05094cf6e7 PM-19723 Group "no folder" items when there is a collection present. (#4941) 2025-03-31 19:19:25 +00:00
Patrick Honkonen
75af4868e2 [PM-19640] Migrate SpecialCharWithPrecedenceComparator to core module (#4942) 2025-03-31 19:19:03 +00:00
Patrick Honkonen
b7948948f0 [PM-19628] Migrate ResultExtensions to core module (#4934) 2025-03-31 17:38:45 +00:00
David Perez
efec5cb4ca PM-19653: Add tooltip and subtext tupport for the switch (#4936) 2025-03-31 15:15:58 +00:00
Patrick Honkonen
6369b20f18 Run detekt on authenticatorbridge module (#4940) 2025-03-31 14:22:18 +00:00
Patrick Honkonen
2e11c81f45 [PM-19626] Migrate SharedFlowExtensions to core module (#4931) 2025-03-31 12:52:18 +00:00
Philip Cappelli
3926fbca7f Revert "WIP"
This reverts commit f698d09b43.
2025-03-28 14:27:40 -04:00
Philip Cappelli
29838b19e0 Revert "WIP"
This reverts commit 66dae199c8.
2025-03-28 14:27:30 -04:00
Philip Cappelli
66dae199c8 WIP 2025-03-28 13:52:16 -04:00
Philip Cappelli
f698d09b43 WIP 2025-03-28 11:44:42 -04:00
bw-ghapp[bot]
9486f4c4e2 Autosync Crowdin Translations (#4935)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2025-03-28 13:50:14 +00:00
David Perez
6664ccc53f PM-19466: Fix snackbar ime padding (#4933) 2025-03-28 13:40:54 +00:00
Patrick Honkonen
d62e3164dc [PM-19624] Migrate DataState to core module (#4930) 2025-03-28 13:29:39 +00:00
Philip Cappelli
b0729e8cd2 WIP 2025-03-27 17:32:59 -04:00
Philip Cappelli
c51f61c585 WIP 2025-03-27 17:32:53 -04:00
Patrick Honkonen
6340c2dd04 [PM-19616] Move OmitFromCoverage annotation to core module (#4928) 2025-03-27 21:11:53 +00:00
David Perez
42df9733c8 PM-19543: Add flight recorder feature flag (#4929) 2025-03-27 20:51:29 +00:00
Patrick Honkonen
cfa753cb12 [PM-19013] Create core module (#4836) 2025-03-27 19:53:29 +00:00
David Perez
71250a28fa Update the README dependencies section and clean up toml file (#4926) 2025-03-27 19:51:24 +00:00
David Perez
5279e6d18c PM-19547: Delay the delete account success dialog to avoid flicker (#4927) 2025-03-27 18:52:38 +00:00
aj-rosado
8dd5a9df9f [PM-8331] Using default send url when on US cloud (#4925) 2025-03-27 18:30:49 +00:00
Patrick Honkonen
346961856f Update passkey privileged app community list (#4923) 2025-03-27 13:53:24 +00:00
Dave Severns
4cae0823f2 PM-19559 Remove "Give feedback" from Settings > About (#4924) 2025-03-26 20:08:55 +00:00
Dave Severns
98b6f68821 PM-19550: Accept app language settings "System default" (#4922) 2025-03-26 19:37:19 +00:00
github-actions[bot]
a6d1f210c8 Update Google privileged browsers list (#4910)
Co-authored-by: GitHub Actions Bot <actions@github.com>
Co-authored-by: Patrick Honkonen <1883101+SaintPatrck@users.noreply.github.com>
2025-03-26 19:05:33 +00:00
Philip Cappelli
c0707ae08c Revert "PM-19131 - moved isVisible logic for hidden custom fields to be managed on view side vs model side"
This reverts commit bc76e46185.
2025-03-26 14:10:15 -04:00
David Perez
3e15b60178 PM-19498: Update cipher migration logic (#4920) 2025-03-26 17:29:28 +00:00
David Perez
6081b7e932 Replace landscape and portrait logic with sceen width logic (#4915) 2025-03-26 16:09:41 +00:00
Philip Cappelli
bc76e46185 PM-19131 - moved isVisible logic for hidden custom fields to be managed on view side vs model side 2025-03-25 17:21:29 -04:00
David Perez
b4b4f753ca PM-8953: Require 4 digits for pin entry (#4914) 2025-03-25 21:20:15 +00:00
David Perez
22376bfe4b PM-19403: Add better error messages for username generation (#4911) 2025-03-24 18:32:24 +00:00
David Perez
ab270cd243 PM-19466: Handle the IME padding internal to the BitwardenScaffold (#4912) 2025-03-24 17:13:35 +00:00
David Perez
8ed9b97805 Update protobuf lib to 4.30.1 (#4909) 2025-03-21 21:18:01 +00:00
David Perez
27e4c6a2b4 Update Compose BOM to 2025.03.00 (#4908) 2025-03-21 21:17:41 +00:00
David Perez
a6ed702a95 BWA-154: Fix privacy policy padding (#4907) 2025-03-21 20:25:06 +00:00
David Perez
0792f44b6b Update to Firebase 33.11.0 (#4906) 2025-03-21 18:36:54 +00:00
David Perez
94a91702cc PM-19399: Do not show 'Share error details' button when user enter incorrect password (#4905) 2025-03-21 16:29:38 +00:00
David Perez
21af60f4de Update to Junit 5.12.1 (#4903) 2025-03-21 16:11:12 +00:00
Matt Andreko
1add57d56c Fix SARIF upload branch ref/sha (#4899) 2025-03-21 13:13:00 +00:00
bw-ghapp[bot]
b0421c774b Autosync Crowdin Translations (#4902)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2025-03-21 13:06:20 +00:00
David Perez
7d846ae383 PM-18862: Update IME handling for BitwardenScaffold and VaultUnlockedNavBarScreen (#4901) 2025-03-20 20:44:46 +00:00
David Perez
29371bdcb5 PM-19389: Handle encoding error when migrating biometric key (#4900) 2025-03-20 19:15:44 +00:00
Álison Fernandes
3eed1c1abe [PM-19049] Add workflow to regularly fetch updates to fido2_privileged_google.json (#4858)
Co-authored-by: Patrick Honkonen <1883101+SaintPatrck@users.noreply.github.com>
2025-03-19 21:13:40 +00:00
aj-rosado
ad6bc883b8 [PM-13257] Checking if user is navigating from vault before showing prompt for biometrics (#4846) 2025-03-19 10:23:50 +00:00
David Perez
f4f669683e PM-19334: Propagate errors to the UI (#4893) 2025-03-18 17:27:41 +00:00
Dave Severns
475a82e0fb PM-19335 add throwable val to generator error results (#4894) 2025-03-18 17:08:11 +00:00
Phil Cappelli
f22156389b BWA-119 - Unable to Access Manual Code Entry After Denying Camera Permissions on (#4891) 2025-03-18 15:50:51 +00:00
Phil Cappelli
4f09f5dae4 PM-18872 - When a Folder name is long, the View/Edit Item > Folder selection screen doesn't adjust well (#4892) 2025-03-18 15:50:39 +00:00
David Perez
3934bc9ae2 PM-19314: Propagate remaining auth errors to the UI (#4888) 2025-03-18 15:24:17 +00:00
David Perez
72c9149d27 PM-19295: Propagate password errors to the UI (#4884) 2025-03-18 14:05:36 +00:00
David Perez
a040a38ce8 PM-19296: Propagate login errors to the UI (#4885) 2025-03-18 14:05:07 +00:00
Dave Severns
ef3b7730d0 PM-19289 propagating remaining vault result errors. (#4881) 2025-03-18 13:51:30 +00:00
David Perez
ad8d8d271a PM-19294: Propagate the Register errors to the UI (#4883) 2025-03-17 19:54:43 +00:00
David Perez
4954e57007 Update gem dependencies (#4882) 2025-03-17 19:29:22 +00:00
Dave Severns
6f50fffd17 PM-19275 propagate the errors for the vault unlock error result types (#4878) 2025-03-17 19:24:13 +00:00
David Perez
44c5755301 PM-19284: Propagate SSO flow errors to the UI (#4880) 2025-03-17 19:14:17 +00:00
David Perez
b20eece3aa PM-19283: Propagate error from email token and known device flows (#4879) 2025-03-17 17:47:07 +00:00
renovate[bot]
869a3b00a5 [deps]: Lock file maintenance (#4875)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-17 15:47:03 +00:00
David Perez
7f8e848c46 PM-19245: Propagate error from password validation to UI (#4877) 2025-03-17 15:36:01 +00:00
Dave Severns
6c784d28eb PM-19272 propagate errors from cipher results (#4876) 2025-03-17 15:18:05 +00:00
Dave Severns
dfcdc72499 PM-19241 folder result errors propagated to UI (#4870) 2025-03-17 12:20:44 +00:00
Dave Severns
db287ddce5 PM-19243 send result errors propagated to UI (#4872) 2025-03-14 22:01:42 +00:00
David Perez
9ea85917b1 PM-19239: Propagate delete account errors to the UI (#4871) 2025-03-14 21:27:56 +00:00
Dave Severns
6db4165c4c PM-19234 propagates attachment result errors to UI (#4869) 2025-03-14 20:47:25 +00:00
David Perez
18ce45e7e5 PM-19233: Propagate auth request errors to the UI (#4868) 2025-03-14 18:33:39 +00:00
Dave Severns
6fe9eba620 PM-11356 Adjust autofocus delay to be greater than screen refresh delay. (#4866) 2025-03-14 16:48:34 +00:00
David Perez
b084987758 PM-19226: Propagate error from create auth request flow to UI (#4867) 2025-03-14 15:47:03 +00:00
bw-ghapp[bot]
5d0593026f Autosync Crowdin Translations (#4865)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2025-03-14 14:39:07 +00:00
David Perez
47abeb7843 PM-14435: Improve accessibility service detection (#4864) 2025-03-14 14:16:25 +00:00
Phil Cappelli
e2779e4edb PM-18681 - Update Showing Coach Mark Tour Logic To Only Consider User's Personal Vault (#4863) 2025-03-13 20:46:14 +00:00
Álison Fernandes
90cc9f77c5 [PM-19207] Add Passkey / FIDO2 Bug Report template (#4859) 2025-03-13 20:31:30 +00:00
David Perez
40760f270a Use immutable map in debug menu (#4861) 2025-03-13 19:28:27 +00:00
David Perez
8a773141a4 Simplify RootNavScreenTest (#4860) 2025-03-13 19:20:14 +00:00
David Perez
0c149abdd9 PM-18844: Update BitwardenBasicDialog to allow it to share error logs (#4855) 2025-03-13 18:16:22 +00:00
David Perez
f540f86b19 PM-19199: hoist debug menu up to top level of the app (#4857) 2025-03-13 17:51:22 +00:00
Dave Severns
ca64ce2176 PM-18877 Respect system app specific language selection on Android 13 and up. (#4849) 2025-03-13 13:14:41 +00:00
André Bispo
da63c9e36b [PM-17995] Adjust custom fields section (#4835) 2025-03-13 11:33:39 +00:00
André Bispo
e16ad44d5e [PM-17242] While on autofill search on all item types. (#4824) 2025-03-13 11:33:12 +00:00
Phil Cappelli
d26a2ee52a PM-18681 - Update Showing Coach Mark Tour Logic To Account for Org Only Policy (#4854) 2025-03-12 20:20:44 +00:00
Dave Severns
1eb741ab58 PM-11356 prevent extra soft-keyboard showing. (#4845) 2025-03-11 20:10:46 +00:00
David Perez
e10ca9a6ec PM-19099: Centralize app metadata (#4847) 2025-03-11 19:47:07 +00:00
David Perez
3fca61ad3e Remove the language change dialog (#4658) 2025-03-11 14:33:22 +00:00
David Perez
409529b9ca Update AndroidX Activity to 1.10.1 (#4844) 2025-03-11 13:51:39 +00:00
David Perez
4568dd53d4 Update Firebase BOM to 33.10.0 (#4843) 2025-03-10 21:20:56 +00:00
David Perez
b9b90165bf PM-10725: Always show share sheet after creating send regardless of how it was made (#4841) 2025-03-10 20:43:49 +00:00
David Perez
778a630012 Update to AGP 8.9.0 (#4840) 2025-03-10 15:46:30 +00:00
Dave Severns
4809066ad7 PM-17087 update notification payloads to support camelCase JSON keys. (#4823) 2025-03-10 14:54:58 +00:00
Patrick Honkonen
d03c6c243d [PM-18873] Refactor ItemHeader.kt to improve location display (#4814) 2025-03-07 17:02:15 +00:00
bw-ghapp[bot]
d19ab498ff Autosync Crowdin Translations (#4832)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2025-03-07 16:48:31 +00:00
Phil Cappelli
efc3d21fde PM-18681 - Update Showing Coach Mark Tour Logic To Only Consider User's Personal Vault (#4821) 2025-03-05 16:01:41 +00:00
Phil Cappelli
35e585a60e PM-18570 Update Owner Selection Field to Bottom Sheet Selector (#4810) 2025-03-04 22:24:31 +00:00
Patrick Honkonen
39787f9bf0 [deps] Update mockk to 1.13.17 (#4818) 2025-03-04 20:17:42 +00:00
Patrick Honkonen
3940997ef9 [deps] Update junit5 to 5.11.4 (#4819) 2025-03-04 20:17:23 +00:00
Patrick Honkonen
ce482e744d [deps] Update testng to 7.11.0 (#4820) 2025-03-04 19:36:18 +00:00
Patrick Honkonen
b0157d10e2 [deps] Update detekt to 1.23.8 (#4817) 2025-03-04 19:36:00 +00:00
renovate[bot]
cf3c2fb56d [deps]: migrate renovate config (#4815)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-04 17:56:09 +00:00
Dave Severns
a88a173e00 PM-18773 update the keyName for the ChromeAutofill flag (#4812) 2025-03-03 15:31:02 +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
Patrick Honkonen
9635bd9b43 [BWA-33]: Publish release bundles to Play Store when requested (#303) 2024-12-13 13:36:54 -05:00
bw-ghapp[bot]
8dd9ba65d0 Autosync Crowdin Translations (#302) 2024-12-13 12:48:37 -05:00
Phil Cappelli
ad90785c39 BWA-124 - 'Copy' Option Missing from Long-Press Menu (#300) 2024-12-12 00:28:59 -05: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
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
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
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
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
renovate[bot]
7d1e2fec90 [deps]: Update gh minor (#284) 2024-12-03 15:23:04 +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
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
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
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
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
7f25fa07a4 Use authenticatorbridge version 1.0.0 (#270) 2024-11-01 16:41:40 -05: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
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
Andrew Haisting
bcc7e6756e BITAU-84 Show Snackbar the first time a user syncs accounts (#259) 2024-10-30 11:12:47 -05: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
bb6255b6a4 Disable ExtraTranslation lint check (#262) 2024-10-29 18:12:21 -04: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
Andrew Haisting
1d2095b0b3 BITAU-181 Allow user to update default save options from settings (#252) 2024-10-24 09:49:07 -05:00
Andrew Haisting
5fdfb26950 BITAU-180 Show "Move to Bitwarden" long press action (#250) 2024-10-24 08:38:55 -05:00
Andrew Haisting
5d7656323b Add queries to AndroidManifest (#251) 2024-10-23 09:53:16 -05: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
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
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
Andrew Haisting
8abe62e53e Remove Firebase APK distribution (#244) 2024-10-17 11:51:57 -05: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
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
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
43fb630393 BITAU-76 Show download Bitwarden action card (#229) 2024-10-10 15:22:54 -05: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
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
Andrew Haisting
f3bce23942 Use correct feature for syncing with Bitwarden (#230) 2024-10-08 15:08:35 -05:00
Andrew Haisting
1015654d27 BITAU-70 Implement symmetric key storage (#226) 2024-10-08 13:01:55 -05: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
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
93423d4b13 BITAU-68 Specify build specific bridge permission in manifest (#218) 2024-10-03 13:45:27 -05: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
renovate[bot]
e2e49a4555 [deps]: Update kotlin (#193) 2024-10-02 10:22:58 -04: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
Andrew Haisting
9f4a85d373 remove unused getAuthCodeFlow() (#215) 2024-10-01 15:33:21 -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
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
Patrick Honkonen
ddeece0a5c [BWA-79] Sanitize manual entry code before validation (#200) 2024-09-26 10:22:10 -04:00
Andrew Haisting
3445191a05 BITAU-66 Use fixed keystore for signing debug build (#201) 2024-09-25 14:17:36 -05: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
renovate[bot]
26eeb39f88 [deps]: Update gradle minor (#192) 2024-09-19 16:35:00 -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
Patrick Honkonen
1f89314bbb [BWA-65] Sort items alphabetically with special char precedence (#190) 2024-09-18 13:10:16 -03:00
github-actions[bot]
afd7097b53 Autosync Crowdin Translations (#186) 2024-09-18 15:00:57 +00:00
Andrew Haisting
087cd5a093 BITAU-158 Add PasswordManagerSync local feature flag (#189) 2024-09-18 09:12:13 -05: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
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
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
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
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
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
Martini
524e0941e4 [BWA-53] Fix: Resolve issue with code copying in search results (#163) 2024-08-20 09:17:32 -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
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
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
renovate[bot]
48f30f022d [deps]: Update gradle minor (#149) 2024-07-23 13:08:54 +00:00
Matt Bishop
2f526a7725 Exclude tests from Sonar (#147) 2024-07-12 16:45:20 -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]
1e1beec6e4 [deps]: Update gh minor (#117) 2024-07-08 09:33:44 -04:00
Patrick Honkonen
9a72c0c8e5 [BWA-45] Update Androidx Lifecycle components to fix runtime crash (#140) 2024-07-01 17:09:33 -04:00
Matt Bishop
cff5c7b9a2 Adjust Sonar scan paths (#139) 2024-06-24 14:15:07 -04: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
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
2019 changed files with 175771 additions and 97521 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

2
.github/CODEOWNERS vendored
View File

@@ -5,7 +5,7 @@
# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
# Default file owners.
* @bitwarden/team-android @brian-livefront @david-livefront @dseverns-livefront @ahaisting-livefront @phil-livefront
* @bitwarden/team-android @brian-livefront @david-livefront
# Actions and workflow changes.
.github/ @bitwarden/dept-development-mobile

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.

64
.github/ISSUE_TEMPLATE/bug-passkey.yml vendored Normal file
View File

@@ -0,0 +1,64 @@
name: Passkey Bug Report
description: File a Passkey / FIDO2 related bug report
labels: [ "app:password-manager", "bug-passkey" ]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this Passkey-related bug report!
Please provide as much detail as possible to help us investigate the issue.
- type: dropdown
id: origin
attributes:
label: Origin
description: Are you using a web browser or a native application?
options:
- Web (Browser)
- Native Application (non-browser app)
validations:
required: true
- type: input
id: rp-id
attributes:
label: Web URL or App name
description: The website domain or app name you were trying to use the Passkey with
placeholder: "e.g. example.com or ExampleApp"
validations:
required: true
- type: checkboxes
id: operation-type
attributes:
label: Passkey Action
description: What passkey related action(s) were you trying to perform?
options:
- label: Creating new passkey (Registration)
- label: Signing in (Authentication)
validations:
required: true
- type: textarea
id: build-info
attributes:
label: Build Information
description: Please retrieve the build information from the About screen by tapping the Version number field
validations:
required: true
- type: textarea
id: additional-info
attributes:
label: Additional Information
description: Any additional context, steps to reproduce, error messages, or relevant information about the issue
- 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:

View File

@@ -1,8 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: Legacy Android Bug Reports
url: https://github.com/bitwarden/mobile/issues
about: Bugs found in the publicly available .NET MAUI app should be reported in [bitwarden/mobile](https://github.com/bitwarden/mobile)
- name: Feature Requests
url: https://community.bitwarden.com/c/feature-requests/
about: Request new features using the Community Forums. Please search existing feature requests before making a new one.

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

50
.github/renovate.json vendored
View File

@@ -1,32 +1,56 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["github>bitwarden/renovate-config"],
"enabledManagers": ["github-actions", "gradle", "bundler"],
"extends": [
"github>bitwarden/renovate-config"
],
"enabledManagers": [
"github-actions",
"gradle",
"bundler"
],
"packageRules": [
{
"groupName": "gh minor",
"matchManagers": ["github-actions"],
"matchUpdateTypes": ["minor", "patch"]
"matchManagers": [
"github-actions"
],
"matchUpdateTypes": [
"minor",
"patch"
]
},
{
"groupName": "gradle minor",
"matchUpdateTypes": ["minor", "patch"],
"matchManagers": ["gradle"]
"matchUpdateTypes": [
"minor",
"patch"
],
"matchManagers": [
"gradle"
]
},
{
"groupName": "kotlin",
"description": "Kotlin and Compose dependencies that must be updated together to maintain compatibility.",
"matchPackagePatterns": [
"androidx.compose:compose-bom",
"org.jetbrains.kotlin.*",
"com.google.devtools.ksp"
"matchManagers": [
"gradle"
],
"matchManagers": ["gradle"]
"matchPackageNames": [
"/androidx.compose:compose-bom/",
"/androidx.lifecycle:*/",
"/org.jetbrains.kotlin.*/",
"/com.google.devtools.ksp/"
]
},
{
"groupName": "bundler minor",
"matchUpdateTypes": ["minor", "patch"],
"matchManagers": ["bundler"]
"matchUpdateTypes": [
"minor",
"patch"
],
"matchManagers": [
"bundler"
]
}
]
}

View File

@@ -0,0 +1 @@
3.13

39
.github/scripts/validate-json/README.md vendored Normal file
View File

@@ -0,0 +1,39 @@
# JSON Validation Scripts
Utility scripts for validating JSON files and checking for duplicate package names between Google and Community privileged browser lists.
## Usage
### Validate a JSON file
```bash
python validate_json.py validate <json_file>
```
### Check for duplicates between two JSON files
```bash
python validate_json.py duplicates <json_file1> <json_file2> [output_file]
```
If `output_file` is not specified, duplicates will be saved to `duplicates.txt`.
## Running Tests
```bash
# Run all tests
python -m unittest test_validate_json.py
# Run the invalid JSON test individually
python -m unittest test_validate_json.TestValidateJson.test_validate_json_invalid
```
## Examples
```bash
# Validate Google privileged browsers list
python validate_json.py validate ../../app/src/main/assets/fido2_privileged_google.json
# Check for duplicates between Google and Community lists
python validate_json.py duplicates ../../app/src/main/assets/fido2_privileged_google.json ../../app/src/main/assets/fido2_privileged_community.json duplicates.txt
```

View File

@@ -0,0 +1,20 @@
{
"apps": [
"type": "android",
"info": {
"package_name": "com.android.chrome",
"signatures": [
{
"build": "release",
"cert_fingerprint_sha256": "F0:FD:6C:5B:41:0F:25:CB:25:C3:B5:33:46:C8:97:2F:AE:30:F8:EE:74:11:DF:91:04:80:AD:6B:2D:60:DB:83"
},
{
"build": "userdebug",
"cert_fingerprint_sha256": "19:75:B2:F1:71:77:BC:89:A5:DF:F3:1F:9E:64:A6:CA:E2:81:A5:3D:C1:D1:D5:9B:1D:14:7F:E1:C8:2A:FA:00"
}
]
}
}
]
}

View File

@@ -0,0 +1,48 @@
{
"apps": [
{
"type": "android",
"info": {
"package_name": "com.android.chrome",
"signatures": [
{
"build": "release",
"cert_fingerprint_sha256": "F0:FD:6C:5B:41:0F:25:CB:25:C3:B5:33:46:C8:97:2F:AE:30:F8:EE:74:11:DF:91:04:80:AD:6B:2D:60:DB:83"
},
{
"build": "userdebug",
"cert_fingerprint_sha256": "19:75:B2:F1:71:77:BC:89:A5:DF:F3:1F:9E:64:A6:CA:E2:81:A5:3D:C1:D1:D5:9B:1D:14:7F:E1:C8:2A:FA:00"
}
]
}
},
{
"type": "android",
"info": {
"package_name": "com.chrome.dev",
"signatures": [
{
"build": "release",
"cert_fingerprint_sha256": "90:44:EE:5F:EE:4B:BC:5E:21:DD:44:66:54:31:C4:EB:1F:1F:71:A3:27:16:A0:BC:92:7B:CB:B3:92:33:CA:BF"
},
{
"build": "release",
"cert_fingerprint_sha256": "3D:7A:12:23:01:9A:A3:9D:9E:A0:E3:43:6A:B7:C0:89:6B:FB:4F:B6:79:F4:DE:5F:E7:C2:3F:32:6C:8F:99:4A"
}
]
}
},
{
"type": "android",
"info": {
"package_name": "com.chrome.canary",
"signatures": [
{
"build": "release",
"cert_fingerprint_sha256": "DF:A1:FB:23:EF:BF:70:C5:BC:D1:44:3C:5B:EA:B0:4F:3F:2F:F4:36:6E:9A:C1:E3:45:76:39:A2:4C:FC"
}
]
}
}
]
}

View File

@@ -0,0 +1,20 @@
{
"apps": [
{
"type": "android",
"info": {
"package_name": "org.chromium.chrome",
"signatures": [
{
"build": "release",
"cert_fingerprint_sha256": "C6:AD:B8:B8:3C:6D:4C:17:D2:92:AF:DE:56:FD:48:8A:51:D3:16:FF:8F:2C:11:C5:41:02:23:BF:F8:A7:DB:B3"
},
{
"build": "userdebug",
"cert_fingerprint_sha256": "19:75:B2:F1:71:77:BC:89:A5:DF:F3:1F:9E:64:A6:CA:E2:81:A5:3D:C1:D1:D5:9B:1D:14:7F:E1:C8:2A:FA:00"
}
]
}
}
]
}

View File

@@ -0,0 +1,48 @@
#!/usr/bin/env python3
import unittest
import os
import json
from validate_json import validate_json, find_duplicates, get_package_names
from unittest.mock import patch
import io
class TestValidateJson(unittest.TestCase):
def setUp(self):
self.valid_file = os.path.join(os.path.dirname(__file__), "fixtures/sample-valid1.json")
self.valid_file2 = os.path.join(os.path.dirname(__file__), "fixtures/sample-valid2.json")
self.invalid_file = os.path.join(os.path.dirname(__file__), "fixtures/sample-invalid.json")
# Suppress stdout
self.stdout_patcher = patch('sys.stdout', new=io.StringIO())
self.stdout_patcher.start()
def tearDown(self):
self.stdout_patcher.stop()
def test_validate_json_valid(self):
"""Test validation of valid JSON file"""
self.assertTrue(validate_json(self.valid_file))
def test_validate_json_invalid(self):
"""Test validation of invalid JSON file"""
self.assertFalse(validate_json(self.invalid_file))
def test_find_duplicates(self):
"""Test when using the same file (should find duplicates)"""
expected_package_names = get_package_names(self.valid_file)
duplicates = find_duplicates(self.valid_file, self.valid_file)
self.assertEqual(len(duplicates), len(expected_package_names))
for package_name in expected_package_names:
self.assertIn(package_name, duplicates)
def test_find_duplicates_returns_empty_list_when_no_duplicates(self):
"""Test when using different files (should not find duplicates)"""
duplicates = find_duplicates(self.valid_file, self.valid_file2)
self.assertEqual(len(duplicates), 0)
if __name__ == "__main__":
unittest.main()

View File

@@ -0,0 +1,145 @@
#!/usr/bin/env python3
import json
import sys
import os
from typing import List, Dict, Any, Set
def get_package_names(file_path: str) -> Set[str]:
"""
Extracts package names from a JSON file.
Args:
file_path: Path to the JSON file
Returns:
Set of package names
"""
with open(file_path, 'r') as f:
data = json.load(f)
package_names = set()
for app in data["apps"]:
package_names.add(app["info"]["package_name"])
return package_names
def validate_json(file_path: str) -> bool:
"""
Validates if a JSON file is correctly formatted by attempting to deserialize it.
Args:
file_path: Path to the JSON file to validate
Returns:
True if valid, False otherwise
"""
try:
if not os.path.exists(file_path):
print(f"Error: File {file_path} does not exist")
return False
with open(file_path, 'r') as f:
json.load(f)
print(f"✅ JSON file {file_path} is valid")
return True
except json.JSONDecodeError as e:
print(f"❌ Invalid JSON in {file_path}: {str(e)}")
return False
except Exception as e:
print(f"❌ Error validating {file_path}: {str(e)}")
return False
def find_duplicates(file1_path: str, file2_path: str) -> List[str]:
"""
Checks for duplicate package_name entries between two JSON files.
Args:
file1_path: Path to the first JSON file
file2_path: Path to the second JSON file
Returns:
List of duplicate package names, empty list if none found
"""
try:
# Get package names from both files
packages1 = get_package_names(file1_path)
packages2 = get_package_names(file2_path)
# Find duplicates
duplicates = list(packages1.intersection(packages2))
if duplicates:
print(f"❌ Found {len(duplicates)} duplicate package names between {file1_path} and {file2_path}:")
for dup in duplicates:
print(f" - {dup}")
return duplicates
else:
print(f"✅ No duplicate package names found between {file1_path} and {file2_path}")
return []
except Exception as e:
print(f"❌ Error checking duplicates: {str(e)}")
return []
def save_duplicates_to_file(duplicates: List[str], output_file: str) -> None:
"""
Saves the list of duplicates to a file.
Args:
duplicates: List of duplicate package names
output_file: Path to save the list of duplicates
"""
try:
with open(output_file, 'w') as f:
for dup in duplicates:
f.write(f"{dup}\n")
print(f"Duplicates saved to {output_file}")
except Exception as e:
print(f"❌ Error saving duplicates to file: {str(e)}")
def main():
if len(sys.argv) < 2:
print("Usage:")
print(" Validate JSON: python validate_json.py validate <json_file>")
print(" Check duplicates: python validate_json.py duplicates <json_file1> <json_file2> [output_file]")
sys.exit(1)
command = sys.argv[1]
match command:
case "validate":
if len(sys.argv) < 3:
print("Error: Missing JSON file path")
sys.exit(1)
file_path = sys.argv[2]
success = validate_json(file_path)
sys.exit(0 if success else 1)
case "duplicates":
if len(sys.argv) < 4:
print("Error: Missing JSON file paths")
sys.exit(1)
file1_path = sys.argv[2]
file2_path = sys.argv[3]
output_file = sys.argv[4] if len(sys.argv) > 4 else "duplicates.txt"
duplicates = find_duplicates(file1_path, file2_path)
if duplicates:
save_duplicates_to_file(duplicates, output_file)
sys.exit(0)
case _:
print(f"Unknown command: {command}")
sys.exit(1)
if __name__ == "__main__":
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@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
- name: Cache Gradle files
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
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@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
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@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
with:
distribution: "temurin"
java-version: ${{ env.JAVA_VERSION }}
- name: Configure Ruby
uses: ruby/setup-ruby@ca041f971d66735f3e5ff1e21cc13e2d51e7e535 # v1.233.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 check
- 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@ca041f971d66735f3e5ff1e21cc13e2d51e7e535 # v1.233.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@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
- name: Cache Gradle files
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
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@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
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@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
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@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
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@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
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@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
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@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
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

@@ -40,10 +40,10 @@ jobs:
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Validate Gradle wrapper
uses: gradle/actions/wrapper-validation@cc4fc85e6b35bafd578d5ffbc76a5518407e1af0 # v4.2.1
uses: gradle/actions/wrapper-validation@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
- name: Cache Gradle files
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: |
~/.gradle/caches
@@ -53,7 +53,7 @@ jobs:
${{ runner.os }}-gradle-v2-
- name: Cache build output
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: |
${{ github.workspace }}/build-cache
@@ -62,13 +62,13 @@ jobs:
${{ runner.os }}-build-
- name: Configure JDK
uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b # v4.5.0
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
with:
distribution: "temurin"
java-version: ${{ env.JAVA_VERSION }}
- name: Configure Ruby
uses: ruby/setup-ruby@2a18b06812b0e15bb916e1df298d3e740422c47e # v1.203.0
uses: ruby/setup-ruby@ca041f971d66735f3e5ff1e21cc13e2d51e7e535 # v1.233.0
with:
bundler-cache: true
@@ -85,7 +85,7 @@ jobs:
run: bundle exec fastlane assembleDebugApks
- name: Upload test reports on failure
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
if: failure()
with:
name: test-reports
@@ -106,7 +106,7 @@ jobs:
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Configure Ruby
uses: ruby/setup-ruby@2a18b06812b0e15bb916e1df298d3e740422c47e # v1.203.0
uses: ruby/setup-ruby@ca041f971d66735f3e5ff1e21cc13e2d51e7e535 # v1.233.0
with:
bundler-cache: true
@@ -157,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@cc4fc85e6b35bafd578d5ffbc76a5518407e1af0 # v4.2.1
uses: gradle/actions/wrapper-validation@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
- name: Cache Gradle files
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: |
~/.gradle/caches
@@ -170,7 +170,7 @@ jobs:
${{ runner.os }}-gradle-v2-
- name: Cache build output
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: |
${{ github.workspace }}/build-cache
@@ -179,7 +179,7 @@ jobs:
${{ runner.os }}-build-
- name: Configure JDK
uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b # v4.5.0
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
with:
distribution: "temurin"
java-version: ${{ env.JAVA_VERSION }}
@@ -253,7 +253,7 @@ jobs:
- name: Upload release Play Store .aab artifact
if: ${{ (matrix.variant == 'prod') && (matrix.artifact == 'aab') }}
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: com.x8bit.bitwarden.aab
path: app/build/outputs/bundle/standardRelease/com.x8bit.bitwarden.aab
@@ -261,7 +261,7 @@ jobs:
- name: Upload beta Play Store .aab artifact
if: ${{ (matrix.variant == 'prod') && (matrix.artifact == 'aab') }}
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: com.x8bit.bitwarden.beta.aab
path: app/build/outputs/bundle/standardBeta/com.x8bit.bitwarden.beta.aab
@@ -269,7 +269,7 @@ jobs:
- name: Upload release .apk artifact
if: ${{ (matrix.variant == 'prod') && (matrix.artifact == 'apk') }}
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: com.x8bit.bitwarden.apk
path: app/build/outputs/apk/standard/release/com.x8bit.bitwarden.apk
@@ -277,7 +277,7 @@ jobs:
- name: Upload beta .apk artifact
if: ${{ (matrix.variant == 'prod') && (matrix.artifact == 'apk') }}
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: com.x8bit.bitwarden.beta.apk
path: app/build/outputs/apk/standard/beta/com.x8bit.bitwarden.beta.apk
@@ -286,7 +286,7 @@ jobs:
# When building variants other than 'prod'
- name: Upload debug .apk artifact
if: ${{ (matrix.variant != 'prod') && (matrix.artifact == 'apk') }}
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: com.x8bit.bitwarden.${{ matrix.variant }}.apk
path: app/build/outputs/apk/standard/debug/com.x8bit.bitwarden.dev.apk
@@ -324,7 +324,7 @@ jobs:
- name: Upload .apk SHA file for release
if: ${{ (matrix.variant == 'prod') && (matrix.artifact == 'apk') }}
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: com.x8bit.bitwarden.apk-sha256.txt
path: ./com.x8bit.bitwarden.apk-sha256.txt
@@ -332,7 +332,7 @@ jobs:
- name: Upload .apk SHA file for beta
if: ${{ (matrix.variant == 'prod') && (matrix.artifact == 'apk') }}
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: com.x8bit.bitwarden.beta.apk-sha256.txt
path: ./com.x8bit.bitwarden.beta.apk-sha256.txt
@@ -340,7 +340,7 @@ jobs:
- name: Upload .aab SHA file for release
if: ${{ (matrix.variant == 'prod') && (matrix.artifact == 'aab') }}
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: com.x8bit.bitwarden.aab-sha256.txt
path: ./com.x8bit.bitwarden.aab-sha256.txt
@@ -348,7 +348,7 @@ jobs:
- name: Upload .aab SHA file for beta
if: ${{ (matrix.variant == 'prod') && (matrix.artifact == 'aab') }}
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: com.x8bit.bitwarden.beta.aab-sha256.txt
path: ./com.x8bit.bitwarden.beta.aab-sha256.txt
@@ -356,7 +356,7 @@ jobs:
- name: Upload .apk SHA file for debug
if: ${{ (matrix.variant != 'prod') && (matrix.artifact == 'apk') }}
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: com.x8bit.bitwarden.${{ matrix.variant }}.apk-sha256.txt
path: ./com.x8bit.bitwarden.${{ matrix.variant }}.apk-sha256.txt
@@ -405,7 +405,7 @@ jobs:
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Configure Ruby
uses: ruby/setup-ruby@2a18b06812b0e15bb916e1df298d3e740422c47e # v1.203.0
uses: ruby/setup-ruby@ca041f971d66735f3e5ff1e21cc13e2d51e7e535 # v1.233.0
with:
bundler-cache: true
@@ -442,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@cc4fc85e6b35bafd578d5ffbc76a5518407e1af0 # v4.2.1
uses: gradle/actions/wrapper-validation@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
- name: Cache Gradle files
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: |
~/.gradle/caches
@@ -455,7 +455,7 @@ jobs:
${{ runner.os }}-gradle-v2-
- name: Cache build output
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: |
${{ github.workspace }}/build-cache
@@ -464,7 +464,7 @@ jobs:
${{ runner.os }}-build-
- name: Configure JDK
uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b # v4.5.0
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
with:
distribution: "temurin"
java-version: ${{ env.JAVA_VERSION }}
@@ -515,7 +515,7 @@ jobs:
keyPassword:"${{ env.FDROID_BETA_KEY_PASSWORD }}"
- name: Upload F-Droid .apk artifact
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: com.x8bit.bitwarden-fdroid.apk
path: app/build/outputs/apk/fdroid/release/com.x8bit.bitwarden-fdroid.apk
@@ -527,14 +527,14 @@ jobs:
> ./com.x8bit.bitwarden-fdroid.apk-sha256.txt
- name: Upload F-Droid SHA file
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
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@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: com.x8bit.bitwarden.beta-fdroid.apk
path: app/build/outputs/apk/fdroid/beta/com.x8bit.bitwarden.beta-fdroid.apk
@@ -546,7 +546,7 @@ jobs:
> ./com.x8bit.bitwarden.beta-fdroid.apk-sha256.txt
- name: Upload F-Droid Beta SHA file
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: com.x8bit.bitwarden.beta-fdroid.apk-sha256.txt
path: ./com.x8bit.bitwarden.beta-fdroid.apk-sha256.txt

View File

@@ -0,0 +1,98 @@
name: Cron / Sync Google Privileged Browsers List
on:
schedule:
# Run weekly on Monday at 00:00 UTC
- cron: '0 0 * * 1'
workflow_dispatch:
env:
SOURCE_URL: https://www.gstatic.com/gpm-passkeys-privileged-apps/apps.json
GOOGLE_FILE: app/src/main/assets/fido2_privileged_google.json
COMMUNITY_FILE: app/src/main/assets/fido2_privileged_community.json
jobs:
sync-privileged-browsers:
name: Sync Google Privileged Browsers List
runs-on: ubuntu-24.04
permissions:
contents: write
pull-requests: write
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # 4.2.2
- name: Download Google Privileged Browsers List
run: curl -s $SOURCE_URL -o $GOOGLE_FILE
- name: Check for changes
id: check-changes
run: |
if git diff --quiet -- $GOOGLE_FILE; then
echo "👀 No changes detected, skipping..."
echo "has_changes=false" >> $GITHUB_OUTPUT
exit 0
fi
echo "has_changes=true" >> $GITHUB_OUTPUT
echo "👀 Changes detected, validating fido2_privileged_google.json..."
python .github/scripts/validate-json/validate_json.py validate $GOOGLE_FILE
if [ $? -ne 0 ]; then
echo "::error::JSON validation failed for $GOOGLE_FILE"
exit 1
fi
echo "👀 fido2_privileged_google.json is valid, checking for duplicates..."
# Check for duplicates between Google and Community files
python .github/scripts/validate-json/validate_json.py duplicates $GOOGLE_FILE $COMMUNITY_FILE duplicates.txt
if [ -f duplicates.txt ]; then
echo "::warning::Duplicate package names found between Google and Community files."
echo "duplicates_found=true" >> $GITHUB_OUTPUT
else
echo "✅ No duplicate package names found between Google and Community files"
echo "duplicates_found=false" >> $GITHUB_OUTPUT
fi
- name: Create branch and commit
if: steps.check-changes.outputs.has_changes == 'true'
run: |
echo "👀 Committing fido2_privileged_google.json..."
BRANCH_NAME="cron-sync-privileged-browsers/$GITHUB_RUN_NUMBER-sync"
git config user.name "GitHub Actions Bot"
git config user.email "actions@github.com"
git checkout -b $BRANCH_NAME
git add $GOOGLE_FILE
git commit -m "Update Google privileged browsers list"
git push origin $BRANCH_NAME
echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_ENV
echo "🌱 Branch created: $BRANCH_NAME"
- name: Create Pull Request
if: steps.check-changes.outputs.has_changes == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DUPLICATES_FOUND: ${{ steps.check-changes.outputs.duplicates_found }}
BASE_PR_URL: ${{ github.server_url }}/${{ github.repository }}/pull/
run: |
PR_BODY="Updates the Google privileged browsers list with the latest data from $SOURCE_URL"
if [ "$DUPLICATES_FOUND" = "true" ]; then
PR_BODY="$PR_BODY\n\n> [!WARNING]\n> :suspect: The following package(s) appear in both Google and Community files:"
while IFS= read -r line; do
PR_BODY="$PR_BODY\n> - $line"
done < duplicates.txt
fi
# Use echo -e to interpret escape sequences and pipe to gh pr create
PR_URL=$(echo -e "$PR_BODY" | gh pr create \
--title "Update Google privileged browsers list" \
--body-file - \
--base main \
--head $BRANCH_NAME \
--label "automated-pr" \
--label "t:ci")

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@3ff1caaa28b64c9cc276ce0a02e2ff584f3900c5 # v2.0.2
id: app-token
with:
app-id: ${{ secrets.BW_GHAPP_ID }}
private-key: ${{ secrets.BW_GHAPP_KEY }}
- name: Download translations
uses: crowdin/github-action@b8012bd5491b8aa8578b73ab5b5f5e7c94aaa6e2 # v2.7.0
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 }}

View File

@@ -29,14 +29,14 @@ jobs:
secrets: "crowdin-api-token, github-gpg-private-key, github-gpg-private-key-passphrase"
- name: Generate GH App token
uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # v1.11.0
uses: actions/create-github-app-token@3ff1caaa28b64c9cc276ce0a02e2ff584f3900c5 # v2.0.2
id: app-token
with:
app-id: ${{ secrets.BW_GHAPP_ID }}
private-key: ${{ secrets.BW_GHAPP_KEY }}
- name: Download translations
uses: crowdin/github-action@a9ffb7d5ac46eca1bb1f06656bf888b39462f161 # v2.4.0
uses: crowdin/github-action@b8012bd5491b8aa8578b73ab5b5f5e7c94aaa6e2 # v2.7.0
env:
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }}

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@b8012bd5491b8aa8578b73ab5b5f5e7c94aaa6e2 # v2.7.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CROWDIN_API_TOKEN: ${{ secrets.CROWDIN_API_TOKEN }}
with:
config: crowdin-bwa.yml
upload_sources: true
upload_translations: false

View File

@@ -29,7 +29,7 @@ jobs:
secrets: "crowdin-api-token"
- name: Upload sources
uses: crowdin/github-action@a9ffb7d5ac46eca1bb1f06656bf888b39462f161 # v2.4.0
uses: crowdin/github-action@b8012bd5491b8aa8578b73ab5b5f5e7c94aaa6e2 # v2.7.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }}

View File

@@ -95,7 +95,7 @@ jobs:
- name: Create Release
id: create_release
uses: softprops/action-gh-release@01570a1f39cb168c169c802c3bceb9e93fb10974 # v2.1.0
uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 # v2.2.2
with:
tag_name: "v${{ inputs.version-name }}"
name: "${{ inputs.version-name }} (${{ inputs.version-number }})"

View File

@@ -21,7 +21,7 @@ jobs:
fetch-depth: 0
- name: Scan with Checkmarx
uses: checkmarx/ast-github-action@b74e8d514feae4ad5ad2b43e72590935bd2daf5f # 2.0.39
uses: checkmarx/ast-github-action@ef93013c95adc60160bc22060875e90800d3ecfc # 2.3.19
with:
project_name: ${{ github.repository }}
cx_tenant: ${{ secrets.CHECKMARX_TENANT }}
@@ -34,7 +34,7 @@ jobs:
--output-path .
- name: Upload Checkmarx results to GitHub
uses: github/codeql-action/upload-sarif@aa578102511db1f4524ed59b8cc2bae4f6e88195 # v3.27.6
uses: github/codeql-action/upload-sarif@45775bd8235c68ba998cffa5171334d58593da47 # v3.28.15
with:
sarif_file: cx_result.sarif
@@ -51,7 +51,7 @@ jobs:
fetch-depth: 0
- name: Scan with SonarCloud
uses: sonarsource/sonarqube-scan-action@bfd4e558cda28cda6b5defafb9232d191be8c203 # v4.2.1
uses: sonarsource/sonarqube-scan-action@aa494459d7c39c106cc77b166de8b4250a32bb97 # v5.1.0
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
with:

View File

@@ -2,10 +2,14 @@ name: Scan Pull Requests
on:
workflow_dispatch:
pull_request:
types: [opened, synchronize, reopened]
branches-ignore:
- main
pull_request_target:
types: [opened, synchronize]
merge_group:
types: [checks_requested]
types: [opened, synchronize, reopened]
branches:
- main
jobs:
check-run:
@@ -28,7 +32,7 @@ jobs:
ref: ${{ github.event.pull_request.head.sha }}
- name: Scan with Checkmarx
uses: checkmarx/ast-github-action@b74e8d514feae4ad5ad2b43e72590935bd2daf5f # 2.0.39
uses: checkmarx/ast-github-action@ef93013c95adc60160bc22060875e90800d3ecfc # 2.3.19
env:
INCREMENTAL: "${{ contains(github.event_name, 'pull_request') && '--sast-incremental' || '' }}"
with:
@@ -43,9 +47,11 @@ jobs:
--output-path . ${{ env.INCREMENTAL }}
- name: Upload Checkmarx results to GitHub
uses: github/codeql-action/upload-sarif@aa578102511db1f4524ed59b8cc2bae4f6e88195 # v3.27.6
uses: github/codeql-action/upload-sarif@45775bd8235c68ba998cffa5171334d58593da47 # v3.28.15
with:
sarif_file: cx_result.sarif
sha: ${{ contains(github.event_name, 'pull_request') && github.event.pull_request.head.sha || github.sha }}
ref: ${{ contains(github.event_name, 'pull_request') && format('refs/pull/{0}/head', github.event.pull_request.number) || github.ref }}
quality:
name: Quality scan
@@ -63,10 +69,11 @@ jobs:
ref: ${{ github.event.pull_request.head.sha }}
- name: Scan with SonarCloud
uses: sonarsource/sonarqube-scan-action@bfd4e558cda28cda6b5defafb9232d191be8c203 # v4.2.1
uses: sonarsource/sonarqube-scan-action@aa494459d7c39c106cc77b166de8b4250a32bb97 # v5.1.0
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

@@ -13,15 +13,15 @@ on:
workflow_dispatch:
env:
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:
test:
name: Test
runs-on: ubuntu-24.04
permissions:
contents: read
issues: write
packages: read
pull-requests: write
@@ -30,10 +30,10 @@ jobs:
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Validate Gradle wrapper
uses: gradle/actions/wrapper-validation@cc4fc85e6b35bafd578d5ffbc76a5518407e1af0 # v4.2.1
uses: gradle/actions/wrapper-validation@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
- name: Cache Gradle files
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: |
~/.gradle/caches
@@ -43,7 +43,7 @@ jobs:
${{ runner.os }}-gradle-v2-
- name: Cache build output
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: |
${{ github.workspace }}/build-cache
@@ -52,15 +52,15 @@ jobs:
${{ runner.os }}-build-
- name: Configure Ruby
uses: ruby/setup-ruby@2a18b06812b0e15bb916e1df298d3e740422c47e # v1.203.0
uses: ruby/setup-ruby@ca041f971d66735f3e5ff1e21cc13e2d51e7e535 # v1.233.0
with:
bundler-cache: true
- name: Configure JDK
uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b # v4.5.0
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
with:
distribution: "temurin"
java-version: ${{ env.JAVA_VERSION }}
java-version: ${{ env._JAVA_VERSION }}
- name: Install Fastlane
run: |
@@ -69,17 +69,48 @@ jobs:
bundle install --jobs 4 --retry 3
- name: Build and test
env:
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 on failure
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
if: failure()
- name: Upload test reports
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
if: always()
with:
name: test-reports
path: app/build/reports/tests/
path: |
build/reports/kover/reportMergedCoverage.xml
app/build/reports/tests/
authenticator/build/reports/tests/
authenticatorbridge/build/reports/tests/
core/build/reports/tests/
data/build/reports/tests/
network/build/reports/tests/
ui/build/reports/tests/
- name: Upload to codecov.io
uses: codecov/codecov-action@7f8b4b4bde536c465e797be725718b88c5d95e0e # v5.1.1
id: upload-to-codecov
uses: codecov/codecov-action@ad3126e916f78f00edff4ed0317cf185271ccc2d # v5.4.2
if: github.event_name == 'push' || github.event_name == 'pull_request'
continue-on-error: true
with:
files: app/build/reports/kover/reportStandardDebug.xml
os: linux
files: build/reports/kover/reportMergedCoverage.xml
fail_ci_if_error: true
disable_search: 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

10
.gitignore vendored
View File

@@ -25,5 +25,13 @@ 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
.python-version
__pycache__/
# Generated by .github/scripts/validate-json/validate-json.py
duplicates.txt

1
.husky/pre-commit Executable file
View File

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

View File

@@ -9,21 +9,23 @@ GEM
public_suffix (>= 2.0.2, < 7.0)
artifactory (3.0.17)
atomos (0.1.3)
aws-eventstream (1.3.0)
aws-partitions (1.1026.0)
aws-sdk-core (3.214.0)
aws-eventstream (1.3.2)
aws-partitions (1.1102.0)
aws-sdk-core (3.223.0)
aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.992.0)
aws-sigv4 (~> 1.9)
base64
jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.96.0)
aws-sdk-core (~> 3, >= 3.210.0)
logger
aws-sdk-kms (1.100.0)
aws-sdk-core (~> 3, >= 3.216.0)
aws-sigv4 (~> 1.5)
aws-sdk-s3 (1.176.1)
aws-sdk-core (~> 3, >= 3.210.0)
aws-sdk-s3 (1.185.0)
aws-sdk-core (~> 3, >= 3.216.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.5)
aws-sigv4 (1.10.1)
aws-sigv4 (1.11.0)
aws-eventstream (~> 1, >= 1.0.2)
babosa (1.0.4)
base64 (0.2.0)
@@ -34,7 +36,7 @@ GEM
highline (~> 2.0.0)
date (3.4.1)
declarative (0.0.20)
digest-crc (0.6.5)
digest-crc (0.7.0)
rake (>= 12.0.0, < 14.0.0)
domain_name (0.6.20240107)
dotenv (2.8.1)
@@ -68,8 +70,8 @@ GEM
faraday-retry (1.0.3)
faraday_middleware (1.2.1)
faraday (~> 1.0)
fastimage (2.3.1)
fastlane (2.226.0)
fastimage (2.4.0)
fastlane (2.227.2)
CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.8, < 3.0.0)
artifactory (~> 3.0)
@@ -109,9 +111,9 @@ GEM
tty-spinner (>= 0.8.0, < 1.0.0)
word_wrap (~> 1.0.0)
xcodeproj (>= 1.13.0, < 2.0.0)
xcpretty (~> 0.4.0)
xcpretty (~> 0.4.1)
xcpretty-travis-formatter (>= 0.0.3, < 2.0.0)
fastlane-plugin-firebase_app_distribution (0.9.1)
fastlane-plugin-firebase_app_distribution (0.10.1)
google-apis-firebaseappdistribution_v1 (~> 0.3.0)
google-apis-firebaseappdistribution_v1alpha (~> 0.2.0)
fastlane-sirp (1.0.0)
@@ -137,12 +139,12 @@ 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.1)
google-cloud-core (1.8.0)
google-cloud-env (>= 1.0, < 3.a)
google-cloud-errors (~> 1.0)
google-cloud-env (1.6.0)
faraday (>= 0.17.3, < 3.0)
google-cloud-errors (1.4.0)
google-cloud-errors (1.5.0)
google-cloud-storage (1.47.0)
addressable (~> 2.8)
digest-crc (~> 0.4)
@@ -160,34 +162,37 @@ GEM
highline (2.0.3)
http-cookie (1.0.8)
domain_name (~> 0.5)
httpclient (2.8.3)
httpclient (2.9.0)
mutex_m
jmespath (1.6.2)
json (2.9.1)
jwt (2.9.3)
json (2.11.3)
jwt (2.10.1)
base64
logger (1.7.0)
mini_magick (4.13.2)
mini_mime (1.1.5)
multi_json (1.15.0)
multipart-post (2.4.1)
mutex_m (0.3.0)
nanaimo (0.4.0)
naturally (2.2.1)
nkf (0.2.0)
optparse (0.6.0)
os (1.1.4)
plist (3.7.1)
public_suffix (6.0.1)
plist (3.7.2)
public_suffix (6.0.2)
rake (13.2.1)
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.4.0)
rexml (3.4.1)
rouge (3.28.0)
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
rubyzip (2.4.1)
security (0.1.5)
signet (0.19.0)
signet (0.20.0)
addressable (~> 2.8)
faraday (>= 0.17.5, < 3.a)
jwt (>= 1.5, < 3.0)
@@ -216,7 +221,7 @@ GEM
colored2 (~> 3.1)
nanaimo (~> 0.4.0)
rexml (>= 3.3.6, < 4.0)
xcpretty (0.4.0)
xcpretty (0.4.1)
rouge (~> 3.28.0)
xcpretty-travis-formatter (1.0.1)
xcpretty (~> 0.2, >= 0.0.7)
@@ -233,4 +238,4 @@ RUBY VERSION
ruby 3.3.1p55
BUNDLED WITH
2.5.9
2.6.6

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

@@ -4,6 +4,7 @@
- [Compatibility](#compatibility)
- [Setup](#setup)
- [Theme](#theme)
- [Dependencies](#dependencies)
## Compatibility
@@ -15,7 +16,6 @@
## Setup
1. Clone the repository:
```sh
@@ -52,12 +52,36 @@
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.
## Theme
### Icons & Illustrations
The app supports light mode, dark mode and dynamic colors. Most icons in the app will display correctly using tinting but multi-tonal icons and illustrations require extra processing in order to be displayed properly with dynamic colors.
All illustrations and multi-tonal icons require the svg paths to be tagged with the `name` attribute in order for each individual path to be tinted the appropriate color. Any untagged path will not be tinted and the resulting image will be incorrect.
The supported tags are as follows:
* outline
* primary
* secondary
* tertiary
* accent
* logo
* navigation
* navigationActiveAccent
## Dependencies
### Application Dependencies
The following is a list of all third-party dependencies included as part of the application beyond the standard Android SDK.
- **AndroidX Activity**
- https://developer.android.com/jetpack/androidx/releases/activity
- Purpose: Allows access composable APIs built on top of Activity.
- License: Apache 2.0
- **AndroidX Appcompat**
- https://developer.android.com/jetpack/androidx/releases/appcompat
- Purpose: Allows access to new APIs on older API versions.
@@ -78,7 +102,7 @@ The following is a list of all third-party dependencies included as part of the
- Purpose: Displays webpages with the user's default browser.
- License: Apache 2.0
- **AndroidX CameraX Camera2**
- **AndroidX Camera**
- https://developer.android.com/jetpack/androidx/releases/camera
- Purpose: Display and capture images for barcode scanning.
- License: Apache 2.0
@@ -88,9 +112,9 @@ The following is a list of all third-party dependencies included as part of the
- Purpose: A Kotlin-based declarative UI framework.
- License: Apache 2.0
- **AndroidX Core SplashScreen**
- **AndroidX Core**
- https://developer.android.com/jetpack/androidx/releases/core
- Purpose: Backwards compatible SplashScreen API implementation.
- Purpose: Backwards compatible platform features and APIs.
- License: Apache 2.0
- **AndroidX Credentials**
@@ -103,6 +127,11 @@ The following is a list of all third-party dependencies included as part of the
- Purpose: Lifecycle aware components and tooling.
- License: Apache 2.0
- **AndroidX Navigation**
- https://developer.android.com/jetpack/androidx/releases/navigation
- Purpose: Provides a consistent API for navigating between Android components.
- License: Apache 2.0
- **AndroidX Room**
- https://developer.android.com/jetpack/androidx/releases/room
- Purpose: A convenient SQLite-based persistence layer for Android.
@@ -123,21 +152,6 @@ The following is a list of all third-party dependencies included as part of the
- Purpose: Dependency injection framework.
- License: Apache 2.0
- **Firebase Cloud Messaging**
- https://github.com/firebase/firebase-android-sdk
- Purpose: Allows for push notification support. (**NOTE:** This dependency is not included in builds distributed via F-Droid.)
- License: Apache 2.0
- **Firebase Crashlytics**
- 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
- Purpose: Image loading and caching.
@@ -158,11 +172,6 @@ The following is a list of all third-party dependencies included as part of the
- Purpose: JSON serialization library for Kotlin.
- License: Apache 2.0
- **kotlinx.serialization converter**
- https://github.com/square/retrofit/tree/trunk/retrofit-converters/kotlinx-serialization
- Purpose: Converter for Retrofit 2 and kotlinx.serialization.
- License: Apache 2.0
- **OkHttp 3**
- https://github.com/square/okhttp
- Purpose: An HTTP client used by the library to intercept and log traffic.
@@ -178,16 +187,28 @@ The following is a list of all third-party dependencies included as part of the
- Purpose: Extensible logging library for Android.
- License: Apache 2.0
- **zxcvbn4j**
- https://github.com/nulab/zxcvbn4j
- Purpose: Password strength estimation.
- License: MIT
- **ZXing**
- https://github.com/zxing/zxing
- Purpose: Barcode scanning and generation.
- License: Apache 2.0
The following is an additional list of third-party dependencies that are only included in the non-F-Droid build variants of the application.
- **Firebase Cloud Messaging**
- https://github.com/firebase/firebase-android-sdk
- Purpose: Allows for push notification support.
- License: Apache 2.0
- **Firebase Crashlytics**
- https://github.com/firebase/firebase-android-sdk
- Purpose: SDK for crash and non-fatal error reporting.
- 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
### Development Environment Dependencies
The following is a list of additional third-party dependencies used as part of the local development environment. This includes test-related artifacts as well as tools related to code quality and linting. These are not present in the final packaged application.

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!

1
annotation/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/build

View File

@@ -0,0 +1,42 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
plugins {
alias(libs.plugins.android.library)
alias(libs.plugins.kotlin.android)
}
android {
namespace = "com.bitwarden.annotation"
compileSdk = libs.versions.compileSdk.get().toInt()
defaultConfig {
minSdk = libs.versions.minSdkBwa.get().toInt()
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("consumer-rules.pro")
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro",
)
}
}
compileOptions {
sourceCompatibility(libs.versions.jvmTarget.get())
targetCompatibility(libs.versions.jvmTarget.get())
}
@Suppress("UnstableApiUsage")
testFixtures {
enable = true
}
}
kotlin {
compilerOptions {
jvmTarget.set(JvmTarget.fromTarget(libs.versions.jvmTarget.get()))
}
}

View File

@@ -1,4 +1,4 @@
package com.x8bit.bitwarden.data.platform.annotation
package com.bitwarden.annotation
/**
* Used to omit the annotated class from test coverage reporting. This should be used sparingly and

View File

@@ -13,16 +13,13 @@ plugins {
// Crashlytics is enabled for all builds initially but removed for FDroid builds in gradle and
// standardDebug builds in the merged manifest.
alias(libs.plugins.crashlytics)
alias(libs.plugins.detekt)
alias(libs.plugins.hilt)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.compose.compiler)
alias(libs.plugins.kotlin.parcelize)
alias(libs.plugins.kotlin.serialization)
alias(libs.plugins.kotlinx.kover)
alias(libs.plugins.ksp)
alias(libs.plugins.google.services)
alias(libs.plugins.sonarqube)
}
/**
@@ -54,7 +51,7 @@ android {
minSdk = libs.versions.minSdk.get().toInt()
targetSdk = libs.versions.targetSdk.get().toInt()
versionCode = 1
versionName = "2024.9.0"
versionName = "2025.4.0"
setProperty("archivesBaseName", "com.x8bit.bitwarden")
@@ -68,7 +65,7 @@ android {
buildConfigField(
type = "String",
name = "CI_INFO",
value = "${ciProperties.getOrDefault("ci.info", "\"local\"")}"
value = "${ciProperties.getOrDefault("ci.info", "\"local\"")}",
)
}
@@ -102,9 +99,10 @@ android {
applicationIdSuffix = ".beta"
isDebuggable = false
isMinifyEnabled = true
matchingFallbacks += listOf("release")
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
"proguard-rules.pro",
)
buildConfigField(type = "boolean", name = "HAS_DEBUG_MENU", value = "false")
@@ -115,7 +113,7 @@ android {
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
"proguard-rules.pro",
)
buildConfigField(type = "boolean", name = "HAS_DEBUG_MENU", value = "false")
@@ -180,7 +178,6 @@ android {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
}
}
@Suppress("UnstableApiUsage")
testOptions {
// Required for Robolectric
unitTests.isIncludeAndroidResources = true
@@ -216,6 +213,12 @@ dependencies {
implementation(files("libs/authenticatorbridge-1.0.0-release.aar"))
implementation(project(":annotation"))
implementation(project(":core"))
implementation(project(":data"))
implementation(project(":network"))
implementation(project(":ui"))
implementation(libs.androidx.activity.compose)
implementation(libs.androidx.appcompat)
implementation(libs.androidx.autofill)
@@ -227,6 +230,7 @@ dependencies {
implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.compose.animation)
implementation(libs.androidx.compose.material3)
implementation(libs.androidx.compose.material3.adaptive)
implementation(libs.androidx.compose.runtime)
implementation(libs.androidx.compose.ui)
implementation(libs.androidx.compose.ui.graphics)
@@ -251,7 +255,6 @@ dependencies {
implementation(libs.kotlinx.collections.immutable)
implementation(libs.kotlinx.coroutines.android)
implementation(libs.kotlinx.serialization)
implementation(libs.nulab.zxcvbn4j)
implementation(libs.square.okhttp)
implementation(libs.square.okhttp.logging)
implementation(platform(libs.square.retrofit.bom))
@@ -270,8 +273,15 @@ dependencies {
standardImplementation(libs.google.firebase.crashlytics)
standardImplementation(libs.google.play.review)
// Pull in test fixtures from other modules
testImplementation(testFixtures(project(":data")))
testImplementation(testFixtures(project(":network")))
testImplementation(testFixtures(project(":ui")))
testImplementation(libs.androidx.compose.ui.test)
testImplementation(libs.google.hilt.android.testing)
testImplementation(platform(libs.junit.bom))
testRuntimeOnly(libs.junit.platform.launcher)
testImplementation(libs.junit.junit5)
testImplementation(libs.junit.vintage)
testImplementation(libs.kotlinx.coroutines.test)
@@ -279,89 +289,9 @@ dependencies {
testImplementation(libs.robolectric.robolectric)
testImplementation(libs.square.okhttp.mockwebserver)
testImplementation(libs.square.turbine)
detektPlugins(libs.detekt.detekt.formatting)
detektPlugins(libs.detekt.detekt.rules)
}
detekt {
autoCorrect = true
config.from(files("$rootDir/detekt-config.yml"))
}
kover {
currentProject {
sources {
excludeJava = true
}
}
reports {
filters {
excludes {
androidGeneratedClasses()
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",
)
classes(
// Navigation helpers
"*.*NavigationKt*",
// Composable singletons
"*.*ComposableSingletons*",
// Generated classes related to interfaces with default values
"*.*DefaultImpls*",
// Databases
"*.database.*Database*",
"*.dao.*Dao*",
// Dagger Hilt
"dagger.hilt.*",
"hilt_aggregated_deps.*",
"*_Factory",
"*_Factory\$*",
"*_*Factory",
"*_*Factory\$*",
"*.Hilt_*",
"*_HiltModules",
"*_HiltModules\$*",
"*_Impl",
"*_Impl\$*",
"*_MembersInjector",
)
packages(
// Dependency injection
"*.di",
// Models
"*.model",
// Custom UI components
"com.x8bit.bitwarden.ui.platform.components",
// Theme-related code
"com.x8bit.bitwarden.ui.platform.theme",
)
}
}
}
}
tasks {
getByName("check") {
// Add detekt with type resolution to check
dependsOn("detekt")
}
getByName("sonar") {
dependsOn("check")
}
withType<io.gitlab.arturbosch.detekt.Detekt>().configureEach {
jvmTarget = libs.versions.jvmTarget.get()
}
withType<io.gitlab.arturbosch.detekt.DetektCreateBaselineTask>().configureEach {
jvmTarget = libs.versions.jvmTarget.get()
}
withType<Test> {
useJUnitPlatform()
maxHeapSize = "2g"
@@ -381,18 +311,6 @@ afterEvaluate {
.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()) {

View File

@@ -1,9 +1,9 @@
package com.x8bit.bitwarden.data.platform.manager
import com.bitwarden.data.repository.model.Environment
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
/**

View File

@@ -15,7 +15,7 @@
<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.
@@ -76,16 +76,15 @@
<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.com" />
<data android:host="*.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" />
<action android:name="com.x8bit.bitwarden.credentials.ACTION_CREATE_PASSKEY" />
<action android:name="com.x8bit.bitwarden.credentials.ACTION_GET_PASSKEY" />
<action android:name="com.x8bit.bitwarden.credentials.ACTION_UNLOCK_ACCOUNT" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
@@ -310,6 +309,14 @@
android:exported="true"
android:permission="${applicationId}.permission.AUTHENTICATOR_BRIDGE_SERVICE" />
<!-- Firebase SDK initOrder is 100. We use a higher order to initialize first -->
<provider
android:name=".data.platform.contentprovider.UncaughtErrorLoggingContentProvider"
android:authorities="${applicationId}"
android:exported="false"
android:grantUriPermissions="false"
android:initOrder="101" />
</application>
<queries>
@@ -320,6 +327,11 @@
<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

@@ -39,11 +39,11 @@
{
"type": "android",
"info": {
"package_name": "org.mozilla.fenix",
"package_name": "org.ironfoxoss.ironfox",
"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"
"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"
}
]
}
@@ -59,34 +59,6 @@
}
]
}
},
{
"type": "android",
"info": {
"package_name": "us.spotco.fennec_dos",
"signatures": [
{
"build": "release",
"cert_fingerprint_sha256": "26:0E:0A:49:67:8C:78:B7:0C:02:D6:53:7A:DD:3B:6D:C0:A1:71:71:BB:DE:8C:E7:5F:D4:02:6A:8A:3E:18:D2"
},
{
"build": "release",
"cert_fingerprint_sha256": "FF:81:F5:BE:56:39:65:94:EE:E7:0F:EF:28:32:25:6E:15:21:41:22:E2:BA:9C:ED:D2:60:05:FF:D4:BC:AA:A8"
}
]
}
},
{
"type": "android",
"info": {
"package_name": "us.spotco.mulch",
"signatures": [
{
"build": "release",
"cert_fingerprint_sha256": "26:0E:0A:49:67:8C:78:B7:0C:02:D6:53:7A:DD:3B:6D:C0:A1:71:71:BB:DE:8C:E7:5F:D4:02:6A:8A:3E:18:D2"
}
]
}
}
]
}

View File

@@ -160,6 +160,78 @@
]
}
},
{
"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.fenix.debug",
"signatures": [
{
"build": "userdebug",
"cert_fingerprint_sha256": "BD:AE:82:02:80:D2:AF:B7:74:94:EF:22:58:AA:78:A9:AE:A1:36:41:7E:8B:C2:3D:C9:87:75:2E:6F:48:E8:48"
}
]
}
},
{
"type": "android",
"info": {
"package_name": "org.mozilla.focus.beta",
"signatures": [
{
"build": "release",
"cert_fingerprint_sha256": "62:03:A4:73:BE:36:D6:4E:E3:7F:87:FA:50:0E:DB:C7:9E:AB:93:06:10:AB:9B:9F:A4:CA:7D:5C:1F:1B:4F:FC"
}
]
}
},
{
"type": "android",
"info": {
"package_name": "org.mozilla.focus.nightly",
"signatures": [
{
"build": "release",
"cert_fingerprint_sha256": "62:03:A4:73:BE:36:D6:4E:E3:7F:87:FA:50:0E:DB:C7:9E:AB:93:06:10:AB:9B:9F:A4:CA:7D:5C:1F:1B:4F:FC"
}
]
}
},
{
"type": "android",
"info": {
"package_name": "org.mozilla.klar",
"signatures": [
{
"build": "release",
"cert_fingerprint_sha256": "62:03:A4:73:BE:36:D6:4E:E3:7F:87:FA:50:0E:DB:C7:9E:AB:93:06:10:AB:9B:9F:A4:CA:7D:5C:1F:1B:4F:FC"
}
]
}
},
{
"type": "android",
"info": {
"package_name": "org.mozilla.reference.browser",
"signatures": [
{
"build": "release",
"cert_fingerprint_sha256": "B0:09:90:E3:0F:9D:81:5D:2E:BC:7B:9B:B2:21:CE:47:E5:C9:D5:17:AA:C7:0E:7F:D5:95:B1:E5:3E:9A:4B:14"
}
]
}
},
{
"type": "android",
"info": {
@@ -571,6 +643,142 @@
}
]
}
},
{
"type": "android",
"info": {
"package_name": "io.island.Island",
"signatures": [
{
"build": "release",
"cert_fingerprint_sha256": "D9:C3:39:AC:9C:3A:EE:E1:75:1D:85:8C:35:D9:BA:C5:CC:87:B3:CE:76:30:93:F0:F5:10:64:F5:A2:F6:9B:04"
},
{
"build": "userdebug",
"cert_fingerprint_sha256": "6C:65:BD:B0:33:F5:CE:B1:74:09:EF:F9:99:48:D5:58:9F:55:63:9A:63:78:D5:A5:00:EB:95:FC:01:BC:6D:44"
}
]
}
},
{
"type": "android",
"info": {
"package_name": "io.island.IslandCanary",
"signatures": [
{
"build": "release",
"cert_fingerprint_sha256": "90:17:13:23:45:6E:6F:39:CB:FD:CF:B2:56:BE:1D:CF:F3:BC:1C:59:8A:15:93:30:E4:97:73:D0:4C:B9:C9:05"
},
{
"build": "userdebug",
"cert_fingerprint_sha256": "6C:65:BD:B0:33:F5:CE:B1:74:09:EF:F9:99:48:D5:58:9F:55:63:9A:63:78:D5:A5:00:EB:95:FC:01:BC:6D:44"
}
]
}
},
{
"type": "android",
"info": {
"package_name": "io.island.IslandBeta",
"signatures": [
{
"build": "release",
"cert_fingerprint_sha256": "35:31:83:1A:9E:2B:21:1D:E6:AA:C3:69:4B:45:83:6E:56:09:B9:D7:D0:04:C3:1B:21:87:40:FB:77:17:38:D1"
},
{
"build": "userdebug",
"cert_fingerprint_sha256": "6C:65:BD:B0:33:F5:CE:B1:74:09:EF:F9:99:48:D5:58:9F:55:63:9A:63:78:D5:A5:00:EB:95:FC:01:BC:6D:44"
}
]
}
},
{
"type": "android",
"info": {
"package_name": "io.island.IslandDev",
"signatures": [
{
"build": "userdebug",
"cert_fingerprint_sha256": "6C:65:BD:B0:33:F5:CE:B1:74:09:EF:F9:99:48:D5:58:9F:55:63:9A:63:78:D5:A5:00:EB:95:FC:01:BC:6D:44"
}
]
}
},
{
"type": "android",
"info": {
"package_name": "io.island.island.intune",
"signatures": [
{
"build": "release",
"cert_fingerprint_sha256": "C2:38:24:15:41:20:A0:8F:C3:95:42:AC:D8:2A:E9:24:94:78:80:1E:47:FD:6C:66:2B:18:1C:28:CA:7E:59:4E"
},
{
"build": "userdebug",
"cert_fingerprint_sha256": "6C:65:BD:B0:33:F5:CE:B1:74:09:EF:F9:99:48:D5:58:9F:55:63:9A:63:78:D5:A5:00:EB:95:FC:01:BC:6D:44"
}
]
}
},
{
"type": "android",
"info": {
"package_name": "io.island.island.canary.intune",
"signatures": [
{
"build": "release",
"cert_fingerprint_sha256": "1E:16:74:BB:79:EA:09:FB:37:CF:9F:1B:07:1B:1D:51:8D:46:03:0E:D3:EE:F2:C1:4E:AD:93:9E:C6:EE:3A:4C"
},
{
"build": "userdebug",
"cert_fingerprint_sha256": "6C:65:BD:B0:33:F5:CE:B1:74:09:EF:F9:99:48:D5:58:9F:55:63:9A:63:78:D5:A5:00:EB:95:FC:01:BC:6D:44"
}
]
}
},
{
"type": "android",
"info": {
"package_name": "io.island.island.beta.intune",
"signatures": [
{
"build": "release",
"cert_fingerprint_sha256": "D2:5E:AD:F6:1C:E6:36:6C:A4:23:A4:7F:C4:DB:9B:8C:9C:8A:35:B4:B0:19:E8:D9:82:FB:D0:8A:D9:DB:49:5A"
},
{
"build": "userdebug",
"cert_fingerprint_sha256": "6C:65:BD:B0:33:F5:CE:B1:74:09:EF:F9:99:48:D5:58:9F:55:63:9A:63:78:D5:A5:00:EB:95:FC:01:BC:6D:44"
}
]
}
},
{
"type": "android",
"info": {
"package_name": "io.island.island.dev.intune",
"signatures": [
{
"build": "userdebug",
"cert_fingerprint_sha256": "6C:65:BD:B0:33:F5:CE:B1:74:09:EF:F9:99:48:D5:58:9F:55:63:9A:63:78:D5:A5:00:EB:95:FC:01:BC:6D:44"
}
]
}
},
{
"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"
},
{
"build": "userdebug",
"cert_fingerprint_sha256": "F1:38:00:4F:38:04:51:D4:8A:05:2B:B3:A3:EF:17:24:23:D4:B0:D0:C8:A3:AA:DD:FB:DB:66:30:31:48:EC:A4"
}
]
}
}
]
}
}

View File

@@ -2,7 +2,7 @@ package com.x8bit.bitwarden
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.x8bit.bitwarden.data.platform.annotation.OmitFromCoverage
import com.bitwarden.annotation.OmitFromCoverage
/**
* An activity to be launched and then immediately closed so that the OS Shade can be collapsed

View File

@@ -4,7 +4,7 @@ import android.content.Intent
import android.os.Bundle
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import com.x8bit.bitwarden.data.platform.annotation.OmitFromCoverage
import com.bitwarden.annotation.OmitFromCoverage
import dagger.hilt.android.AndroidEntryPoint
/**

View File

@@ -1,13 +1,13 @@
package com.x8bit.bitwarden
import android.content.Intent
import com.bitwarden.ui.platform.base.BaseViewModel
import com.x8bit.bitwarden.data.auth.repository.AuthRepository
import com.x8bit.bitwarden.data.auth.repository.util.getCaptchaCallbackTokenResult
import com.x8bit.bitwarden.data.auth.repository.util.getDuoCallbackTokenResult
import com.x8bit.bitwarden.data.auth.repository.util.getSsoCallbackResult
import com.x8bit.bitwarden.data.auth.repository.util.getWebAuthResultOrNull
import com.x8bit.bitwarden.data.auth.util.getYubiKeyResultOrNull
import com.x8bit.bitwarden.ui.platform.base.BaseViewModel
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject

View File

@@ -4,8 +4,8 @@ import android.os.Bundle
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import com.bitwarden.annotation.OmitFromCoverage
import com.x8bit.bitwarden.data.autofill.manager.AutofillCompletionManager
import com.x8bit.bitwarden.data.platform.annotation.OmitFromCoverage
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach

View File

@@ -2,6 +2,7 @@ package com.x8bit.bitwarden
import android.content.Intent
import androidx.lifecycle.viewModelScope
import com.bitwarden.ui.platform.base.BaseViewModel
import com.bitwarden.vault.CipherView
import com.x8bit.bitwarden.data.auth.repository.AuthRepository
import com.x8bit.bitwarden.data.autofill.util.getTotpCopyIntentOrNull
@@ -9,7 +10,6 @@ import com.x8bit.bitwarden.data.platform.util.launchWithTimeout
import com.x8bit.bitwarden.data.vault.repository.VaultRepository
import com.x8bit.bitwarden.data.vault.repository.model.VaultUnlockData
import com.x8bit.bitwarden.data.vault.repository.util.statusFor
import com.x8bit.bitwarden.ui.platform.base.BaseViewModel
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.mapNotNull

View File

@@ -5,10 +5,10 @@ import android.content.Intent
import android.os.Build
import androidx.annotation.Keep
import androidx.core.app.AppComponentFactory
import com.bitwarden.annotation.OmitFromCoverage
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
import com.x8bit.bitwarden.data.credentials.BitwardenCredentialProviderService
import com.x8bit.bitwarden.data.tiles.BitwardenAutofillTileService
import com.x8bit.bitwarden.data.tiles.BitwardenGeneratorTileService
import com.x8bit.bitwarden.data.tiles.BitwardenVaultTileService
@@ -30,7 +30,7 @@ class BitwardenAppComponentFactory : AppComponentFactory() {
* * [BitwardenAccessibilityService]
* * [BitwardenAutofillService]
* * [BitwardenAutofillTileService]
* * [BitwardenFido2ProviderService]
* * [BitwardenCredentialProviderService]
* * [BitwardenVaultTileService]
* * [BitwardenGeneratorTileService]
*/
@@ -63,7 +63,7 @@ class BitwardenAppComponentFactory : AppComponentFactory() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
super.instantiateServiceCompat(
cl,
BitwardenFido2ProviderService::class.java.name,
BitwardenCredentialProviderService::class.java.name,
intent,
)
} else {

View File

@@ -1,13 +1,15 @@
package com.x8bit.bitwarden
import android.app.Application
import com.bitwarden.annotation.OmitFromCoverage
import com.x8bit.bitwarden.data.auth.manager.AuthRequestNotificationManager
import com.x8bit.bitwarden.data.platform.annotation.OmitFromCoverage
import com.x8bit.bitwarden.data.platform.manager.LogsManager
import com.x8bit.bitwarden.data.platform.manager.NetworkConfigManager
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.network.NetworkConnectionManager
import com.x8bit.bitwarden.data.platform.manager.restriction.RestrictionManager
import dagger.hilt.android.HiltAndroidApp
import timber.log.Timber
import javax.inject.Inject
/**
@@ -21,6 +23,9 @@ class BitwardenApplication : Application() {
@Inject
lateinit var logsManager: LogsManager
@Inject
lateinit var networkConnectionManager: NetworkConnectionManager
@Inject
lateinit var networkConfigManager: NetworkConfigManager
@@ -32,4 +37,9 @@ class BitwardenApplication : Application() {
@Inject
lateinit var restrictionManager: RestrictionManager
override fun onLowMemory() {
super.onLowMemory()
Timber.w("onLowMemory")
}
}

View File

@@ -6,6 +6,11 @@ package com.x8bit.bitwarden
const val LEGACY_ACCESSIBILITY_SERVICE_NAME: String =
"com.x8bit.bitwarden.Accessibility.AccessibilityService"
/**
* The short form legacy name for the accessibility service.
*/
const val LEGACY_SHORT_ACCESSIBILITY_SERVICE_NAME: String = ".Accessibility.AccessibilityService"
/**
* The legacy name for the autofill service.
*/

View File

@@ -1,6 +1,7 @@
package com.x8bit.bitwarden
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.view.KeyEvent
import android.view.MotionEvent
@@ -11,27 +12,35 @@ 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.navigation.compose.rememberNavController
import androidx.navigation.compose.NavHost
import com.bitwarden.annotation.OmitFromCoverage
import com.bitwarden.ui.platform.base.util.EventsEffect
import com.bitwarden.ui.platform.theme.BitwardenTheme
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.components.util.rememberBitwardenNavController
import com.x8bit.bitwarden.ui.platform.composition.LocalManagerProvider
import com.x8bit.bitwarden.ui.platform.feature.debugmenu.debugMenuDestination
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 com.x8bit.bitwarden.ui.platform.feature.rootnav.ROOT_ROUTE
import com.x8bit.bitwarden.ui.platform.feature.rootnav.rootNavDestination
import com.x8bit.bitwarden.ui.platform.feature.settings.appearance.model.AppLanguage
import com.x8bit.bitwarden.ui.platform.util.appLanguage
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
/**
* Primary entry point for the application.
*/
@Suppress("TooManyFunctions")
@OmitFromCoverage
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
@@ -53,6 +62,7 @@ class MainActivity : AppCompatActivity() {
@Inject
lateinit var debugLaunchManager: DebugMenuLaunchManager
@Suppress("LongMethod")
override fun onCreate(savedInstanceState: Bundle?) {
var shouldShowSplashScreen = true
installSplashScreen().setKeepOnScreenCondition { shouldShowSplashScreen }
@@ -66,16 +76,13 @@ 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.
settingsRepository.appLanguage.localeName?.let { localeName ->
val localeList = LocaleListCompat.forLanguageTags(localeName)
AppCompatDelegate.setApplicationLocales(localeList)
}
// Within the app the 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.
AppCompatDelegate.setDefaultNightMode(settingsRepository.appTheme.osValue)
setContent {
val state by mainViewModel.stateFlow.collectAsStateWithLifecycle()
val navController = rememberNavController()
val navController = rememberBitwardenNavController(name = "MainActivity")
EventsEffect(viewModel = mainViewModel) { event ->
when (event) {
is MainEvent.CompleteAccessibilityAutofill -> {
@@ -94,15 +101,46 @@ class MainActivity : AppCompatActivity() {
)
.show()
}
is MainEvent.UpdateAppLocale -> {
AppCompatDelegate.setApplicationLocales(
LocaleListCompat.forLanguageTags(event.localeName),
)
}
is MainEvent.UpdateAppTheme -> {
AppCompatDelegate.setDefaultNightMode(event.osTheme)
}
}
}
updateScreenCapture(isScreenCaptureAllowed = state.isScreenCaptureAllowed)
LocalManagerProvider {
BitwardenTheme(theme = state.theme) {
RootNavScreen(
onSplashScreenRemoved = { shouldShowSplashScreen = false },
LocalManagerProvider(featureFlagsState = state.featureFlagsState) {
ObserveScreenDataEffect(
onDataUpdate = remember(mainViewModel) {
{
mainViewModel.trySendAction(
MainAction.ResumeScreenDataReceived(it),
)
}
},
)
BitwardenTheme(
theme = state.theme,
dynamicColor = state.isDynamicColorsEnabled,
) {
NavHost(
navController = navController,
)
startDestination = ROOT_ROUTE,
) {
// Nothing else should end up at this top level, we just want the ability
// to have the debug menu appear on top of the rest of the app without
// interacting with the state-based navigation used by the RootNavScreen.
rootNavDestination { shouldShowSplashScreen = false }
debugMenuDestination(
onNavigateBack = { navController.popBackStack() },
onSplashScreenRemoved = { shouldShowSplashScreen = false },
)
}
}
}
}
@@ -117,6 +155,33 @@ class MainActivity : AppCompatActivity() {
)
}
override fun onResume() {
super.onResume()
// When the app resumes check for any app specific language which may have been
// set via the device settings. Similar to the theme setting in onCreate this
// ensures we properly set the values when upgrading from older versions
// that handle this differently or when the activity restarts.
val appSpecificLanguage = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
val locales: LocaleListCompat = AppCompatDelegate.getApplicationLocales()
if (locales.isEmpty) {
// App is using the system language
null
} else {
// App has specific language settings
locales.get(0)?.appLanguage
}
} else {
// For older versions, use what ever language is available from the repository.
settingsRepository.appLanguage
}
mainViewModel.trySendAction(
action = MainAction.AppSpecificLanguageUpdate(
appLanguage = appSpecificLanguage ?: AppLanguage.DEFAULT,
),
)
}
override fun onStop() {
super.onStop()
// In some scenarios on an emulator the Activity can leak when recreated

View File

@@ -4,6 +4,10 @@ import android.content.Intent
import android.os.Parcelable
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.viewModelScope
import com.bitwarden.ui.platform.base.BaseViewModel
import com.bitwarden.ui.platform.feature.settings.appearance.model.AppTheme
import com.bitwarden.ui.util.Text
import com.bitwarden.ui.util.asText
import com.bitwarden.vault.CipherView
import com.x8bit.bitwarden.data.auth.manager.AddTotpItemFromAuthenticatorManager
import com.x8bit.bitwarden.data.auth.repository.AuthRepository
@@ -11,27 +15,29 @@ 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.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.getFido2CredentialRequestOrNull
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.credentials.manager.BitwardenCredentialManager
import com.x8bit.bitwarden.data.credentials.util.getCreateCredentialRequestOrNull
import com.x8bit.bitwarden.data.credentials.util.getFido2AssertionRequestOrNull
import com.x8bit.bitwarden.data.credentials.util.getGetCredentialsRequestOrNull
import com.x8bit.bitwarden.data.platform.manager.AppResumeManager
import com.x8bit.bitwarden.data.platform.manager.FeatureFlagManager
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.FlagKey
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.feature.settings.appearance.model.AppLanguage
import com.x8bit.bitwarden.ui.platform.manager.intent.IntentManager
import com.x8bit.bitwarden.ui.platform.model.FeatureFlagsState
import com.x8bit.bitwarden.ui.platform.util.isAccountSecurityShortcut
import com.x8bit.bitwarden.ui.platform.util.isMyVaultShortcut
import com.x8bit.bitwarden.ui.platform.util.isPasswordGeneratorShortcut
@@ -52,6 +58,7 @@ import java.time.Clock
import javax.inject.Inject
private const val SPECIAL_CIRCUMSTANCE_KEY = "special-circumstance"
private const val ANIMATION_REFRESH_DELAY = 500L
/**
* A view model that helps launch actions for the [MainActivity].
@@ -61,21 +68,27 @@ private const val SPECIAL_CIRCUMSTANCE_KEY = "special-circumstance"
class MainViewModel @Inject constructor(
accessibilitySelectionManager: AccessibilitySelectionManager,
autofillSelectionManager: AutofillSelectionManager,
featureFlagManager: FeatureFlagManager,
private val addTotpItemFromAuthenticatorManager: AddTotpItemFromAuthenticatorManager,
private val specialCircumstanceManager: SpecialCircumstanceManager,
private val garbageCollectionManager: GarbageCollectionManager,
private val fido2CredentialManager: Fido2CredentialManager,
private val bitwardenCredentialManager: BitwardenCredentialManager,
private val intentManager: IntentManager,
settingsRepository: SettingsRepository,
private val settingsRepository: SettingsRepository,
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>(
initialState = MainState(
theme = settingsRepository.appTheme,
isScreenCaptureAllowed = settingsRepository.isScreenCaptureAllowed,
isErrorReportingDialogEnabled = featureFlagManager.getFeatureFlag(
key = FlagKey.MobileErrorReporting,
),
isDynamicColorsEnabled = settingsRepository.isDynamicColorsEnabled,
),
) {
private var specialCircumstance: SpecialCircumstance?
@@ -93,6 +106,12 @@ class MainViewModel @Inject constructor(
.onEach { specialCircumstance = it }
.launchIn(viewModelScope)
featureFlagManager
.getFeatureFlagFlow(key = FlagKey.MobileErrorReporting)
.map { MainAction.Internal.OnMobileErrorReportingReceive(it) }
.onEach(::sendAction)
.launchIn(viewModelScope)
accessibilitySelectionManager
.accessibilitySelectionFlow
.map { MainAction.Internal.AccessibilitySelectionReceive(it) }
@@ -108,6 +127,11 @@ 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
@@ -115,6 +139,12 @@ class MainViewModel @Inject constructor(
.onEach(::trySendAction)
.launchIn(viewModelScope)
settingsRepository
.isDynamicColorsEnabledFlow
.map { MainAction.Internal.DynamicColorsUpdate(it) }
.onEach(::trySendAction)
.launchIn(viewModelScope)
authRepository
.userStateFlow
.drop(count = 1)
@@ -126,8 +156,7 @@ class MainViewModel @Inject constructor(
// Switching between account states often involves some kind of animation (ex:
// account switcher) that we might want to give time to finish before triggering
// a refresh.
@Suppress("MagicNumber")
delay(500)
delay(ANIMATION_REFRESH_DELAY)
trySendAction(MainAction.Internal.CurrentUserStateChange)
}
.launchIn(viewModelScope)
@@ -139,8 +168,7 @@ class MainViewModel @Inject constructor(
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)
delay(ANIMATION_REFRESH_DELAY)
trySendAction(MainAction.Internal.VaultUnlockStateChange)
}
@@ -164,6 +192,17 @@ class MainViewModel @Inject constructor(
}
override fun handleAction(action: MainAction) {
when (action) {
is MainAction.ReceiveFirstIntent -> handleFirstIntentReceived(action)
is MainAction.ReceiveNewIntent -> handleNewIntentReceived(action)
MainAction.OpenDebugMenu -> handleOpenDebugMenu()
is MainAction.ResumeScreenDataReceived -> handleAppResumeDataUpdated(action)
is MainAction.AppSpecificLanguageUpdate -> handleAppSpecificLanguageUpdate(action)
is MainAction.Internal -> handleInternalAction(action)
}
}
private fun handleInternalAction(action: MainAction.Internal) {
when (action) {
is MainAction.Internal.AccessibilitySelectionReceive -> {
handleAccessibilitySelectionReceive(action)
@@ -177,9 +216,29 @@ class MainViewModel @Inject constructor(
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.Internal.DynamicColorsUpdate -> handleDynamicColorsUpdate(action)
is MainAction.Internal.OnMobileErrorReportingReceive -> {
handleOnMobileErrorReportingReceive(action)
}
}
}
private fun handleOnMobileErrorReportingReceive(
action: MainAction.Internal.OnMobileErrorReportingReceive,
) {
mutableStateFlow.update {
it.copy(isErrorReportingDialogEnabled = action.isErrorReportingEnabled)
}
}
private fun handleAppSpecificLanguageUpdate(action: MainAction.AppSpecificLanguageUpdate) {
settingsRepository.appLanguage = action.appLanguage
}
private fun handleAppResumeDataUpdated(action: MainAction.ResumeScreenDataReceived) {
when (val data = action.screenResumeData) {
null -> appResumeManager.clearResumeScreen()
else -> appResumeManager.setResumeScreen(data)
}
}
@@ -211,12 +270,17 @@ class MainViewModel @Inject constructor(
private fun handleAppThemeUpdated(action: MainAction.Internal.ThemeUpdate) {
mutableStateFlow.update { it.copy(theme = action.theme) }
sendEvent(MainEvent.UpdateAppTheme(osTheme = action.theme.osValue))
}
private fun handleVaultUnlockStateChange() {
recreateUiAndGarbageCollect()
}
private fun handleDynamicColorsUpdate(action: MainAction.Internal.DynamicColorsUpdate) {
mutableStateFlow.update { it.copy(isDynamicColorsEnabled = action.isDynamicColorsEnabled) }
}
private fun handleFirstIntentReceived(action: MainAction.ReceiveFirstIntent) {
handleIntent(
intent = action.intent,
@@ -257,10 +321,10 @@ class MainViewModel @Inject constructor(
val hasGeneratorShortcut = intent.isPasswordGeneratorShortcut
val hasVaultShortcut = intent.isMyVaultShortcut
val hasAccountSecurityShortcut = intent.isAccountSecurityShortcut
val fido2CredentialRequestData = intent.getFido2CredentialRequestOrNull()
val completeRegistrationData = intent.getCompleteRegistrationDataIntentOrNull()
val fido2CredentialAssertionRequest = intent.getFido2AssertionRequestOrNull()
val fido2GetCredentialsRequest = intent.getFido2GetCredentialsRequestOrNull()
val createCredentialRequest = intent.getCreateCredentialRequestOrNull()
val getCredentialsRequest = intent.getGetCredentialsRequestOrNull()
val fido2AssertCredentialRequest = intent.getFido2AssertionRequestOrNull()
when {
passwordlessRequestData != null -> {
authRepository.activeUserId?.let {
@@ -318,35 +382,43 @@ class MainViewModel @Inject constructor(
)
}
fido2CredentialRequestData != null -> {
createCredentialRequest != 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.
fido2CredentialManager.isUserVerified = false
bitwardenCredentialManager.isUserVerified =
createCredentialRequest.isUserPreVerified
specialCircumstanceManager.specialCircumstance =
SpecialCircumstance.Fido2Save(
fido2CreateCredentialRequest = fido2CredentialRequestData,
SpecialCircumstance.ProviderCreateCredential(
createCredentialRequest = createCredentialRequest,
)
// Switch accounts if the selected user is not the active user.
if (authRepository.activeUserId != null &&
authRepository.activeUserId != fido2CredentialRequestData.userId
authRepository.activeUserId != createCredentialRequest.userId
) {
authRepository.switchAccount(fido2CredentialRequestData.userId)
authRepository.switchAccount(createCredentialRequest.userId)
}
}
fido2CredentialAssertionRequest != null -> {
fido2AssertCredentialRequest != 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.
bitwardenCredentialManager.isUserVerified =
fido2AssertCredentialRequest.isUserPreVerified
specialCircumstanceManager.specialCircumstance =
SpecialCircumstance.Fido2Assertion(
fido2AssertionRequest = fido2CredentialAssertionRequest,
fido2AssertionRequest = fido2AssertCredentialRequest,
)
}
fido2GetCredentialsRequest != null -> {
getCredentialsRequest != null -> {
specialCircumstanceManager.specialCircumstance =
SpecialCircumstance.Fido2GetCredentials(
fido2GetCredentialsRequest = fido2GetCredentialsRequest,
SpecialCircumstance.ProviderGetCredentials(
getCredentialsRequest = getCredentialsRequest,
)
}
@@ -422,7 +494,17 @@ class MainViewModel @Inject constructor(
data class MainState(
val theme: AppTheme,
val isScreenCaptureAllowed: Boolean,
) : Parcelable
val isDynamicColorsEnabled: Boolean,
private val isErrorReportingDialogEnabled: Boolean,
) : Parcelable {
/**
* Contains all feature flags that are available to the UI.
*/
val featureFlagsState: FeatureFlagsState
get() = FeatureFlagsState(
isErrorReportingDialogEnabled = isErrorReportingDialogEnabled,
)
}
/**
* Models actions for the [MainActivity].
@@ -443,6 +525,17 @@ sealed class MainAction {
*/
data object OpenDebugMenu : MainAction()
/**
* Receive event to save the app resume screen
*/
data class ResumeScreenDataReceived(val screenResumeData: AppResumeScreenData?) : MainAction()
/**
* Receive if there is an app specific locale selection made by user
* in the device's settings.
*/
data class AppSpecificLanguageUpdate(val appLanguage: AppLanguage) : MainAction()
/**
* Actions for internal use by the ViewModel.
*/
@@ -455,6 +548,13 @@ sealed class MainAction {
val cipherView: CipherView,
) : Internal()
/**
* Indicates the Mobile Error Reporting feature flag has been updated.
*/
data class OnMobileErrorReportingReceive(
val isErrorReportingEnabled: Boolean,
) : Internal()
/**
* Indicates the user has manually selected the given [cipherView] for autofill.
*/
@@ -485,6 +585,13 @@ sealed class MainAction {
* Indicates a relevant change in the current vault lock state.
*/
data object VaultUnlockStateChange : Internal()
/**
* Indicates that the dynamic colors state has changed.
*/
data class DynamicColorsUpdate(
val isDynamicColorsEnabled: Boolean,
) : Internal()
}
}
@@ -518,4 +625,18 @@ sealed class 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,18 +1,19 @@
package com.x8bit.bitwarden.data.auth.datasource.disk
import com.bitwarden.network.model.SyncResponseJson
import com.bitwarden.network.provider.AppIdProvider
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 {
interface AuthDiskSource : AppIdProvider {
/**
* The currently persisted authenticator sync symmetric key. This key is used for
@@ -20,13 +21,6 @@ interface AuthDiskSource {
*/
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
* application data.
*/
val uniqueAppId: String
/**
* The currently persisted saved email address (or `null` if not set).
*/
@@ -172,6 +166,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].
*/
@@ -334,12 +338,12 @@ interface AuthDiskSource {
fun getShowImportLoginsFlow(userId: String): Flow<Boolean?>
/**
* Gets the new device notice state for the given [userId].
* Gets the last lock timestamp for the given [userId].
*/
fun getNewDeviceNoticeState(userId: String): NewDeviceNoticeState
fun getLastLockTimestamp(userId: String): Instant?
/**
* Stores the new device notice state for the given [userId].
* Stores the last lock timestamp for the given [userId].
*/
fun storeNewDeviceNoticeState(userId: String, newState: NewDeviceNoticeState?)
fun storeLastLockTimestamp(userId: String, lastLockTimestamp: Instant?)
}

View File

@@ -1,28 +1,27 @@
package com.x8bit.bitwarden.data.auth.datasource.disk
import android.content.SharedPreferences
import com.bitwarden.core.data.repository.util.bufferedMutableSharedFlow
import com.bitwarden.core.data.util.decodeFromStringOrNull
import com.bitwarden.data.datasource.disk.BaseEncryptedDiskSource
import com.bitwarden.network.model.SyncResponseJson
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
import com.x8bit.bitwarden.data.platform.datasource.disk.legacy.LegacySecureStorageMigrator
import com.x8bit.bitwarden.data.platform.repository.util.bufferedMutableSharedFlow
import com.x8bit.bitwarden.data.platform.util.decodeFromStringOrNull
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"
@@ -48,7 +47,7 @@ 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].
@@ -145,6 +144,7 @@ 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)
@@ -153,6 +153,7 @@ class AuthDiskSourceImpl(
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.
@@ -280,6 +281,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))
@@ -474,19 +486,16 @@ class AuthDiskSourceImpl(
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 getLastLockTimestamp(userId: String): Instant? {
return getLong(key = LAST_LOCK_TIMESTAMP.appendIdentifier(userId))?.let {
Instant.ofEpochMilli(it)
}
}
override fun storeNewDeviceNoticeState(userId: String, newState: NewDeviceNoticeState?) {
putString(
key = NEW_DEVICE_NOTICE_STATE.appendIdentifier(userId),
value = newState?.let { json.encodeToString(it) },
override fun storeLastLockTimestamp(userId: String, lastLockTimestamp: Instant?) {
putLong(
key = LAST_LOCK_TIMESTAMP.appendIdentifier(userId),
value = lastLockTimestamp?.toEpochMilli(),
)
}

View File

@@ -1,10 +1,10 @@
package com.x8bit.bitwarden.data.auth.datasource.disk.di
import android.content.SharedPreferences
import com.bitwarden.data.datasource.disk.di.EncryptedPreferences
import com.bitwarden.data.datasource.disk.di.UnencryptedPreferences
import com.x8bit.bitwarden.data.auth.datasource.disk.AuthDiskSource
import com.x8bit.bitwarden.data.auth.datasource.disk.AuthDiskSourceImpl
import com.x8bit.bitwarden.data.platform.datasource.di.EncryptedPreferences
import com.x8bit.bitwarden.data.platform.datasource.di.UnencryptedPreferences
import com.x8bit.bitwarden.data.platform.datasource.disk.legacy.LegacySecureStorageMigrator
import dagger.Module
import dagger.Provides

View File

@@ -1,7 +1,8 @@
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 com.bitwarden.data.datasource.disk.model.EnvironmentUrlDataJson
import com.bitwarden.network.model.KdfTypeJson
import com.bitwarden.network.model.UserDecryptionOptionsJson
import kotlinx.serialization.Contextual
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.SerialName

View File

@@ -1,60 +0,0 @@
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

@@ -1,26 +1,17 @@
package com.x8bit.bitwarden.data.auth.datasource.network.di
import com.x8bit.bitwarden.data.auth.datasource.network.service.AccountsService
import com.x8bit.bitwarden.data.auth.datasource.network.service.AccountsServiceImpl
import com.x8bit.bitwarden.data.auth.datasource.network.service.AuthRequestsService
import com.x8bit.bitwarden.data.auth.datasource.network.service.AuthRequestsServiceImpl
import com.x8bit.bitwarden.data.auth.datasource.network.service.DevicesService
import com.x8bit.bitwarden.data.auth.datasource.network.service.DevicesServiceImpl
import com.x8bit.bitwarden.data.auth.datasource.network.service.HaveIBeenPwnedService
import com.x8bit.bitwarden.data.auth.datasource.network.service.HaveIBeenPwnedServiceImpl
import com.x8bit.bitwarden.data.auth.datasource.network.service.IdentityService
import com.x8bit.bitwarden.data.auth.datasource.network.service.IdentityServiceImpl
import com.x8bit.bitwarden.data.auth.datasource.network.service.NewAuthRequestService
import com.x8bit.bitwarden.data.auth.datasource.network.service.NewAuthRequestServiceImpl
import com.x8bit.bitwarden.data.auth.datasource.network.service.OrganizationService
import com.x8bit.bitwarden.data.auth.datasource.network.service.OrganizationServiceImpl
import com.x8bit.bitwarden.data.platform.datasource.network.retrofit.Retrofits
import com.bitwarden.network.BitwardenServiceClient
import com.bitwarden.network.service.AccountsService
import com.bitwarden.network.service.AuthRequestsService
import com.bitwarden.network.service.DevicesService
import com.bitwarden.network.service.HaveIBeenPwnedService
import com.bitwarden.network.service.IdentityService
import com.bitwarden.network.service.NewAuthRequestService
import com.bitwarden.network.service.OrganizationService
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import kotlinx.serialization.json.Json
import retrofit2.create
import javax.inject.Singleton
/**
@@ -33,70 +24,42 @@ object AuthNetworkModule {
@Provides
@Singleton
fun providesAccountService(
retrofits: Retrofits,
json: Json,
): AccountsService = AccountsServiceImpl(
unauthenticatedAccountsApi = retrofits.unauthenticatedApiRetrofit.create(),
authenticatedAccountsApi = retrofits.authenticatedApiRetrofit.create(),
unauthenticatedKeyConnectorApi = retrofits.createStaticRetrofit().create(),
authenticatedKeyConnectorApi = retrofits
.createStaticRetrofit(isAuthenticated = true)
.create(),
json = json,
)
bitwardenServiceClient: BitwardenServiceClient,
): AccountsService = bitwardenServiceClient.accountsService
@Provides
@Singleton
fun providesAuthRequestsService(
retrofits: Retrofits,
): AuthRequestsService = AuthRequestsServiceImpl(
authenticatedAuthRequestsApi = retrofits.authenticatedApiRetrofit.create(),
)
bitwardenServiceClient: BitwardenServiceClient,
): AuthRequestsService = bitwardenServiceClient.authRequestsService
@Provides
@Singleton
fun providesDevicesService(
retrofits: Retrofits,
): DevicesService = DevicesServiceImpl(
authenticatedDevicesApi = retrofits.authenticatedApiRetrofit.create(),
unauthenticatedDevicesApi = retrofits.unauthenticatedApiRetrofit.create(),
)
bitwardenServiceClient: BitwardenServiceClient,
): DevicesService = bitwardenServiceClient.devicesService
@Provides
@Singleton
fun providesIdentityService(
retrofits: Retrofits,
json: Json,
): IdentityService = IdentityServiceImpl(
unauthenticatedIdentityApi = retrofits.unauthenticatedIdentityRetrofit.create(),
json = json,
)
bitwardenServiceClient: BitwardenServiceClient,
): IdentityService = bitwardenServiceClient.identityService
@Provides
@Singleton
fun providesHaveIBeenPwnedService(
retrofits: Retrofits,
): HaveIBeenPwnedService = HaveIBeenPwnedServiceImpl(
api = retrofits
.createStaticRetrofit(baseUrl = "https://api.pwnedpasswords.com")
.create(),
)
bitwardenServiceClient: BitwardenServiceClient,
): HaveIBeenPwnedService = bitwardenServiceClient.haveIBeenPwnedService
@Provides
@Singleton
fun providesNewAuthRequestService(
retrofits: Retrofits,
): NewAuthRequestService = NewAuthRequestServiceImpl(
authenticatedAuthRequestsApi = retrofits.authenticatedApiRetrofit.create(),
unauthenticatedAuthRequestsApi = retrofits.unauthenticatedApiRetrofit.create(),
)
bitwardenServiceClient: BitwardenServiceClient,
): NewAuthRequestService = bitwardenServiceClient.newAuthRequestService
@Provides
@Singleton
fun providesOrganizationService(
retrofits: Retrofits,
): OrganizationService = OrganizationServiceImpl(
authenticatedOrganizationApi = retrofits.authenticatedApiRetrofit.create(),
unauthenticatedOrganizationApi = retrofits.unauthenticatedApiRetrofit.create(),
)
bitwardenServiceClient: BitwardenServiceClient,
): OrganizationService = bitwardenServiceClient.organizationService
}

View File

@@ -1,12 +0,0 @@
package com.x8bit.bitwarden.data.auth.datasource.network.model
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
/**
* Response body from the SSO prevalidate request.
*/
@Serializable
data class PrevalidateSsoResponseJson(
@SerialName("token") val token: String?,
)

View File

@@ -8,7 +8,7 @@ import com.bitwarden.core.RegisterKeyResponse
import com.bitwarden.core.RegisterTdeKeyResponse
import com.bitwarden.crypto.HashPurpose
import com.bitwarden.crypto.Kdf
import com.bitwarden.sdk.ClientAuth
import com.bitwarden.sdk.AuthClient
import com.x8bit.bitwarden.data.auth.datasource.sdk.model.PasswordStrength
import com.x8bit.bitwarden.data.auth.datasource.sdk.util.toPasswordStrengthOrNull
import com.x8bit.bitwarden.data.auth.datasource.sdk.util.toUByte
@@ -17,7 +17,7 @@ import com.x8bit.bitwarden.data.platform.manager.SdkClientManager
/**
* Primary implementation of [AuthSdkSource] that serves as a convenience wrapper around a
* [ClientAuth].
* [AuthClient].
*/
class AuthSdkSourceImpl(
sdkClientManager: SdkClientManager,

View File

@@ -1,9 +1,9 @@
package com.x8bit.bitwarden.data.auth.datasource.sdk.util
import com.bitwarden.crypto.Kdf
import com.x8bit.bitwarden.data.auth.datasource.network.model.KdfTypeJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.KdfTypeJson.ARGON2_ID
import com.x8bit.bitwarden.data.auth.datasource.network.model.KdfTypeJson.PBKDF2_SHA256
import com.bitwarden.network.model.KdfTypeJson
import com.bitwarden.network.model.KdfTypeJson.ARGON2_ID
import com.bitwarden.network.model.KdfTypeJson.PBKDF2_SHA256
/**
* Convert a [Kdf] to a [KdfTypeJson].

View File

@@ -1,11 +1,14 @@
package com.x8bit.bitwarden.data.auth.manager
import com.bitwarden.core.AuthRequestResponse
import com.bitwarden.core.data.util.asFailure
import com.bitwarden.core.data.util.asSuccess
import com.bitwarden.core.data.util.flatMap
import com.bitwarden.network.model.AuthRequestTypeJson
import com.bitwarden.network.service.AuthRequestsService
import com.bitwarden.network.service.NewAuthRequestService
import com.x8bit.bitwarden.data.auth.datasource.disk.AuthDiskSource
import com.x8bit.bitwarden.data.auth.datasource.disk.model.PendingAuthRequestJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.AuthRequestTypeJson
import com.x8bit.bitwarden.data.auth.datasource.network.service.AuthRequestsService
import com.x8bit.bitwarden.data.auth.datasource.network.service.NewAuthRequestService
import com.x8bit.bitwarden.data.auth.datasource.sdk.AuthSdkSource
import com.x8bit.bitwarden.data.auth.manager.model.AuthRequest
import com.x8bit.bitwarden.data.auth.manager.model.AuthRequestResult
@@ -16,9 +19,7 @@ import com.x8bit.bitwarden.data.auth.manager.model.AuthRequestsUpdatesResult
import com.x8bit.bitwarden.data.auth.manager.model.CreateAuthRequestResult
import com.x8bit.bitwarden.data.auth.manager.util.isSso
import com.x8bit.bitwarden.data.auth.manager.util.toAuthRequestTypeJson
import com.x8bit.bitwarden.data.platform.util.asFailure
import com.x8bit.bitwarden.data.platform.util.asSuccess
import com.x8bit.bitwarden.data.platform.util.flatMap
import com.x8bit.bitwarden.data.platform.error.NoActiveUserException
import com.x8bit.bitwarden.data.vault.datasource.sdk.VaultSdkSource
import kotlinx.coroutines.currentCoroutineContext
import kotlinx.coroutines.delay
@@ -51,7 +52,9 @@ class AuthRequestManagerImpl(
override fun getAuthRequestsWithUpdates(): Flow<AuthRequestsUpdatesResult> = flow {
while (currentCoroutineContext().isActive) {
when (val result = getAuthRequests()) {
AuthRequestsResult.Error -> emit(AuthRequestsUpdatesResult.Error)
is AuthRequestsResult.Error -> {
emit(AuthRequestsUpdatesResult.Error(error = result.error))
}
is AuthRequestsResult.Success -> {
emit(AuthRequestsUpdatesResult.Update(authRequests = result.authRequests))
@@ -70,9 +73,8 @@ class AuthRequestManagerImpl(
email = email,
authRequestType = authRequestType.toAuthRequestTypeJson(),
)
.getOrNull()
?: run {
emit(CreateAuthRequestResult.Error)
.getOrElse {
emit(CreateAuthRequestResult.Error(error = it))
return@flow
}
var authRequest = initialResult.authRequest
@@ -103,7 +105,7 @@ class AuthRequestManagerImpl(
)
}
.fold(
onFailure = { emit(CreateAuthRequestResult.Error) },
onFailure = { emit(CreateAuthRequestResult.Error(error = it)) },
onSuccess = { updateAuthRequest ->
when {
updateAuthRequest.requestApproved -> {
@@ -182,7 +184,7 @@ class AuthRequestManagerImpl(
)
}
.fold(
onFailure = { emit(AuthRequestUpdatesResult.Error) },
onFailure = { emit(AuthRequestUpdatesResult.Error(error = it)) },
onSuccess = { updateAuthRequest ->
when {
updateAuthRequest.requestApproved -> {
@@ -218,13 +220,18 @@ class AuthRequestManagerImpl(
fingerprint: String,
): Flow<AuthRequestUpdatesResult> = getAuthRequest {
when (val authRequestsResult = getAuthRequests()) {
AuthRequestsResult.Error -> AuthRequestUpdatesResult.Error
is AuthRequestsResult.Error -> {
AuthRequestUpdatesResult.Error(error = authRequestsResult.error)
}
is AuthRequestsResult.Success -> {
authRequestsResult
.authRequests
.firstOrNull { it.fingerprint == fingerprint }
?.let { AuthRequestUpdatesResult.Update(it) }
?: AuthRequestUpdatesResult.Error
?: AuthRequestUpdatesResult.Error(
error = IllegalStateException("Could not find the auth request."),
)
}
}
}
@@ -234,30 +241,28 @@ class AuthRequestManagerImpl(
): Flow<AuthRequestUpdatesResult> = getAuthRequest {
authRequestsService
.getAuthRequest(requestId)
.map { response ->
getFingerprintPhrase(response.publicKey).getOrNull()?.let { fingerprint ->
AuthRequest(
id = response.id,
publicKey = response.publicKey,
platform = response.platform,
ipAddress = response.ipAddress,
key = response.key,
masterPasswordHash = response.masterPasswordHash,
creationDate = response.creationDate,
responseDate = response.responseDate,
requestApproved = response.requestApproved ?: false,
originUrl = response.originUrl,
fingerprint = fingerprint,
)
}
.mapCatching { response ->
getFingerprintPhrase(response.publicKey)
.getOrThrow()
.let { fingerprint ->
AuthRequest(
id = response.id,
publicKey = response.publicKey,
platform = response.platform,
ipAddress = response.ipAddress,
key = response.key,
masterPasswordHash = response.masterPasswordHash,
creationDate = response.creationDate,
responseDate = response.responseDate,
requestApproved = response.requestApproved ?: false,
originUrl = response.originUrl,
fingerprint = fingerprint,
)
}
}
.fold(
onFailure = { AuthRequestUpdatesResult.Error },
onSuccess = { authRequest ->
authRequest
?.let { AuthRequestUpdatesResult.Update(it) }
?: AuthRequestUpdatesResult.Error
},
onFailure = { AuthRequestUpdatesResult.Error(error = it) },
onSuccess = { AuthRequestUpdatesResult.Update(authRequest = it) },
)
}
@@ -309,7 +314,7 @@ class AuthRequestManagerImpl(
}
}
.fold(
onFailure = { AuthRequestsResult.Error },
onFailure = { AuthRequestsResult.Error(error = it) },
onSuccess = { AuthRequestsResult.Success(authRequests = it) },
)
@@ -319,7 +324,7 @@ class AuthRequestManagerImpl(
publicKey: String,
isApproved: Boolean,
): AuthRequestResult {
val userId = activeUserId ?: return AuthRequestResult.Error
val userId = activeUserId ?: return AuthRequestResult.Error(error = NoActiveUserException())
return vaultSdkSource
.getAuthRequestKey(
publicKey = publicKey,
@@ -350,7 +355,7 @@ class AuthRequestManagerImpl(
)
}
.fold(
onFailure = { AuthRequestResult.Error },
onFailure = { AuthRequestResult.Error(error = it) },
onSuccess = { AuthRequestResult.Success(authRequest = it) },
)
}
@@ -462,7 +467,7 @@ class AuthRequestManagerImpl(
publicKey: String,
): Result<String> {
val profile = authDiskSource.userState?.activeAccount?.profile
?: return IllegalStateException("No active account").asFailure()
?: return NoActiveUserException().asFailure()
return authSdkSource.getUserFingerprint(
email = profile.email,
publicKey = publicKey,

View File

@@ -7,13 +7,13 @@ import androidx.compose.ui.graphics.Color
import androidx.core.app.NotificationChannelCompat
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import com.bitwarden.annotation.OmitFromCoverage
import com.bitwarden.data.manager.DispatcherManager
import com.x8bit.bitwarden.R
import com.x8bit.bitwarden.data.auth.datasource.disk.AuthDiskSource
import com.x8bit.bitwarden.data.auth.util.createPasswordlessRequestDataIntent
import com.x8bit.bitwarden.data.autofill.util.toPendingIntentMutabilityFlag
import com.x8bit.bitwarden.data.platform.annotation.OmitFromCoverage
import com.x8bit.bitwarden.data.platform.manager.PushManager
import com.x8bit.bitwarden.data.platform.manager.dispatcher.DispatcherManager
import com.x8bit.bitwarden.data.platform.manager.model.PasswordlessRequestData
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.launchIn

View File

@@ -0,0 +1,8 @@
package com.x8bit.bitwarden.data.auth.manager
import com.bitwarden.network.interceptor.AuthTokenProvider
/**
* A manager class for handling authentication tokens.
*/
interface AuthTokenManager : AuthTokenProvider

View File

@@ -0,0 +1,17 @@
package com.x8bit.bitwarden.data.auth.manager
import com.x8bit.bitwarden.data.auth.datasource.disk.AuthDiskSource
/**
* Default implementation of [AuthTokenManager].
*/
class AuthTokenManagerImpl(
private val authDiskSource: AuthDiskSource,
) : AuthTokenManager {
override fun getActiveAccessTokenOrNull(): String? = authDiskSource
.userState
?.activeUserId
?.let { authDiskSource.getAccountTokens(it) }
?.accessToken
}

View File

@@ -2,8 +2,9 @@ package com.x8bit.bitwarden.data.auth.manager
import com.bitwarden.core.KeyConnectorResponse
import com.bitwarden.crypto.Kdf
import com.x8bit.bitwarden.data.auth.datasource.network.model.KdfTypeJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.KeyConnectorMasterKeyResponseJson
import com.bitwarden.network.model.KdfTypeJson
import com.bitwarden.network.model.KeyConnectorMasterKeyResponseJson
import com.x8bit.bitwarden.data.auth.manager.model.MigrateExistingUserToKeyConnectorResult
/**
* Manager used to interface with a key connector.
@@ -28,7 +29,7 @@ interface KeyConnectorManager {
email: String,
masterPassword: String,
kdf: Kdf,
): Result<Unit>
): Result<MigrateExistingUserToKeyConnectorResult>
/**
* Migrates a new user to use the key connector.

View File

@@ -1,14 +1,16 @@
package com.x8bit.bitwarden.data.auth.manager
import com.bitwarden.core.KeyConnectorResponse
import com.bitwarden.core.data.util.flatMap
import com.bitwarden.crypto.Kdf
import com.x8bit.bitwarden.data.auth.datasource.network.model.KdfTypeJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.KeyConnectorKeyRequestJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.KeyConnectorMasterKeyResponseJson
import com.x8bit.bitwarden.data.auth.datasource.network.service.AccountsService
import com.bitwarden.network.model.KdfTypeJson
import com.bitwarden.network.model.KeyConnectorKeyRequestJson
import com.bitwarden.network.model.KeyConnectorMasterKeyResponseJson
import com.bitwarden.network.service.AccountsService
import com.x8bit.bitwarden.data.auth.datasource.sdk.AuthSdkSource
import com.x8bit.bitwarden.data.platform.util.flatMap
import com.x8bit.bitwarden.data.auth.manager.model.MigrateExistingUserToKeyConnectorResult
import com.x8bit.bitwarden.data.vault.datasource.sdk.VaultSdkSource
import com.x8bit.bitwarden.data.vault.datasource.sdk.model.DeriveKeyConnectorResult
/**
* The default implementation of the [KeyConnectorManager].
@@ -34,7 +36,7 @@ class KeyConnectorManagerImpl(
email: String,
masterPassword: String,
kdf: Kdf,
): Result<Unit> =
): Result<MigrateExistingUserToKeyConnectorResult> =
vaultSdkSource
.deriveKeyConnector(
userId = userId,
@@ -43,10 +45,36 @@ class KeyConnectorManagerImpl(
password = masterPassword,
kdf = kdf,
)
.flatMap { masterKey ->
accountsService.storeMasterKeyToKeyConnector(url = url, masterKey = masterKey)
.map { result: DeriveKeyConnectorResult ->
when (result) {
is DeriveKeyConnectorResult.Error -> {
MigrateExistingUserToKeyConnectorResult.Error(result.error)
}
is DeriveKeyConnectorResult.Success -> {
accountsService
.storeMasterKeyToKeyConnector(
url = url,
masterKey = result.derivedKey,
)
.flatMap {
accountsService.convertToKeyConnector()
}
.fold(
onSuccess = {
MigrateExistingUserToKeyConnectorResult.Success
},
onFailure = {
MigrateExistingUserToKeyConnectorResult.Error(it)
},
)
}
is DeriveKeyConnectorResult.WrongPasswordError -> {
MigrateExistingUserToKeyConnectorResult.WrongPasswordError
}
}
}
.flatMap { accountsService.convertToKeyConnector() }
override suspend fun migrateNewUserToKeyConnector(
url: String,

View File

@@ -1,11 +1,11 @@
package com.x8bit.bitwarden.data.auth.manager
import com.bitwarden.core.data.util.asSuccess
import com.bitwarden.core.data.util.flatMap
import com.bitwarden.crypto.TrustDeviceResponse
import com.bitwarden.network.service.DevicesService
import com.x8bit.bitwarden.data.auth.datasource.disk.AuthDiskSource
import com.x8bit.bitwarden.data.auth.datasource.network.service.DevicesService
import com.x8bit.bitwarden.data.auth.manager.util.toUserStateJson
import com.x8bit.bitwarden.data.platform.util.asSuccess
import com.x8bit.bitwarden.data.platform.util.flatMap
import com.x8bit.bitwarden.data.vault.datasource.sdk.VaultSdkSource
/**

View File

@@ -1,6 +1,7 @@
package com.x8bit.bitwarden.data.auth.manager
import com.x8bit.bitwarden.data.auth.manager.model.LogoutEvent
import com.x8bit.bitwarden.data.auth.repository.model.LogoutReason
import kotlinx.coroutines.flow.SharedFlow
/**
@@ -14,15 +15,14 @@ interface UserLogoutManager {
val logoutEventFlow: SharedFlow<LogoutEvent>
/**
* Completely logs out the given [userId], removing all data. If [isExpired] is true, a toast
* will be displayed letting the user know the session has expired.
* Completely logs out the given [userId], removing all data. The [reason] indicates why the
* user is being logged out.
*/
fun logout(userId: String, isExpired: Boolean = false)
fun logout(userId: String, reason: LogoutReason)
/**
* Partially logs out the given [userId]. All data for the given [userId] will be removed with
* the exception of basic account data. If [isExpired] is true, a toast will be displayed
* letting the user know the session has expired.
* the exception of basic account data. The [reason] indicates why the user is being logged out.
*/
fun softLogout(userId: String, isExpired: Boolean = false)
fun softLogout(userId: String, reason: LogoutReason)
}

View File

@@ -3,13 +3,14 @@ package com.x8bit.bitwarden.data.auth.manager
import android.content.Context
import android.widget.Toast
import androidx.annotation.StringRes
import com.bitwarden.core.data.repository.util.bufferedMutableSharedFlow
import com.bitwarden.data.manager.DispatcherManager
import com.x8bit.bitwarden.R
import com.x8bit.bitwarden.data.auth.datasource.disk.AuthDiskSource
import com.x8bit.bitwarden.data.auth.manager.model.LogoutEvent
import com.x8bit.bitwarden.data.auth.repository.model.LogoutReason
import com.x8bit.bitwarden.data.platform.datasource.disk.PushDiskSource
import com.x8bit.bitwarden.data.platform.datasource.disk.SettingsDiskSource
import com.x8bit.bitwarden.data.platform.manager.dispatcher.DispatcherManager
import com.x8bit.bitwarden.data.platform.repository.util.bufferedMutableSharedFlow
import com.x8bit.bitwarden.data.tools.generator.datasource.disk.GeneratorDiskSource
import com.x8bit.bitwarden.data.tools.generator.datasource.disk.PasswordHistoryDiskSource
import com.x8bit.bitwarden.data.vault.datasource.disk.VaultDiskSource
@@ -19,6 +20,7 @@ import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.launch
import timber.log.Timber
/**
* Primary implementation of [UserLogoutManager].
@@ -42,9 +44,10 @@ class UserLogoutManagerImpl(
bufferedMutableSharedFlow()
override val logoutEventFlow: SharedFlow<LogoutEvent> = mutableLogoutEventFlow.asSharedFlow()
override fun logout(userId: String, isExpired: Boolean) {
override fun logout(userId: String, reason: LogoutReason) {
authDiskSource.userState ?: return
Timber.d("logout reason=$reason")
val isExpired = reason == LogoutReason.SecurityStamp
if (isExpired) {
showToast(message = R.string.login_expired)
}
@@ -64,7 +67,9 @@ class UserLogoutManagerImpl(
mutableLogoutEventFlow.tryEmit(LogoutEvent(loggedOutUserId = userId))
}
override fun softLogout(userId: String, isExpired: Boolean) {
override fun softLogout(userId: String, reason: LogoutReason) {
Timber.d("softLogout reason=$reason")
val isExpired = reason == LogoutReason.SecurityStamp
if (isExpired) {
showToast(message = R.string.login_expired)
}

View File

@@ -1,11 +1,12 @@
package com.x8bit.bitwarden.data.auth.manager.di
import android.content.Context
import com.bitwarden.data.manager.DispatcherManager
import com.bitwarden.network.service.AccountsService
import com.bitwarden.network.service.AuthRequestsService
import com.bitwarden.network.service.DevicesService
import com.bitwarden.network.service.NewAuthRequestService
import com.x8bit.bitwarden.data.auth.datasource.disk.AuthDiskSource
import com.x8bit.bitwarden.data.auth.datasource.network.service.AccountsService
import com.x8bit.bitwarden.data.auth.datasource.network.service.AuthRequestsService
import com.x8bit.bitwarden.data.auth.datasource.network.service.DevicesService
import com.x8bit.bitwarden.data.auth.datasource.network.service.NewAuthRequestService
import com.x8bit.bitwarden.data.auth.datasource.sdk.AuthSdkSource
import com.x8bit.bitwarden.data.auth.manager.AddTotpItemFromAuthenticatorManager
import com.x8bit.bitwarden.data.auth.manager.AddTotpItemFromAuthenticatorManagerImpl
@@ -13,6 +14,8 @@ import com.x8bit.bitwarden.data.auth.manager.AuthRequestManager
import com.x8bit.bitwarden.data.auth.manager.AuthRequestManagerImpl
import com.x8bit.bitwarden.data.auth.manager.AuthRequestNotificationManager
import com.x8bit.bitwarden.data.auth.manager.AuthRequestNotificationManagerImpl
import com.x8bit.bitwarden.data.auth.manager.AuthTokenManager
import com.x8bit.bitwarden.data.auth.manager.AuthTokenManagerImpl
import com.x8bit.bitwarden.data.auth.manager.KeyConnectorManager
import com.x8bit.bitwarden.data.auth.manager.KeyConnectorManagerImpl
import com.x8bit.bitwarden.data.auth.manager.TrustedDeviceManager
@@ -22,7 +25,6 @@ import com.x8bit.bitwarden.data.auth.manager.UserLogoutManagerImpl
import com.x8bit.bitwarden.data.platform.datasource.disk.PushDiskSource
import com.x8bit.bitwarden.data.platform.datasource.disk.SettingsDiskSource
import com.x8bit.bitwarden.data.platform.manager.PushManager
import com.x8bit.bitwarden.data.platform.manager.dispatcher.DispatcherManager
import com.x8bit.bitwarden.data.tools.generator.datasource.disk.GeneratorDiskSource
import com.x8bit.bitwarden.data.tools.generator.datasource.disk.PasswordHistoryDiskSource
import com.x8bit.bitwarden.data.vault.datasource.disk.VaultDiskSource
@@ -131,4 +133,10 @@ object AuthManagerModule {
@Singleton
fun providesAddTotpItemFromAuthenticatorManager(): AddTotpItemFromAuthenticatorManager =
AddTotpItemFromAuthenticatorManagerImpl()
@Provides
@Singleton
fun providesAuthTokenManager(
authDiskSource: AuthDiskSource,
): AuthTokenManager = AuthTokenManagerImpl(authDiskSource = authDiskSource)
}

View File

@@ -14,5 +14,7 @@ sealed class AuthRequestResult {
/**
* There was an error getting the user's auth requests.
*/
data object Error : AuthRequestResult()
data class Error(
val error: Throwable,
) : AuthRequestResult()
}

View File

@@ -19,7 +19,9 @@ sealed class AuthRequestUpdatesResult {
/**
* There was an error getting the user's auth requests.
*/
data object Error : AuthRequestUpdatesResult()
data class Error(
val error: Throwable,
) : AuthRequestUpdatesResult()
/**
* The auth request has been declined.

View File

@@ -14,5 +14,7 @@ sealed class AuthRequestsResult {
/**
* There was an error getting the user's auth requests.
*/
data object Error : AuthRequestsResult()
data class Error(
val error: Throwable,
) : AuthRequestsResult()
}

View File

@@ -14,5 +14,7 @@ sealed class AuthRequestsUpdatesResult {
/**
* There was an error getting the user's auth requests.
*/
data object Error : AuthRequestsUpdatesResult()
data class Error(
val error: Throwable,
) : AuthRequestsUpdatesResult()
}

View File

@@ -23,7 +23,9 @@ sealed class CreateAuthRequestResult {
/**
* There was a generic error getting the user's auth requests.
*/
data object Error : CreateAuthRequestResult()
data class Error(
val error: Throwable,
) : CreateAuthRequestResult()
/**
* The auth request has been declined.

View File

@@ -0,0 +1,23 @@
package com.x8bit.bitwarden.data.auth.manager.model
/**
* Models result of migrating existing user to key connector.
* */
sealed class MigrateExistingUserToKeyConnectorResult {
/**
* Operation succeeded.
*/
data object Success : MigrateExistingUserToKeyConnectorResult()
/**
* There was an error.
*/
data class Error(
val error: Throwable,
) : MigrateExistingUserToKeyConnectorResult()
/**
* Incorrect password provided.
*/
data object WrongPasswordError : MigrateExistingUserToKeyConnectorResult()
}

View File

@@ -1,6 +1,6 @@
package com.x8bit.bitwarden.data.auth.manager.util
import com.x8bit.bitwarden.data.auth.datasource.network.model.AuthRequestTypeJson
import com.bitwarden.network.model.AuthRequestTypeJson
import com.x8bit.bitwarden.data.auth.manager.model.AuthRequestType
/**

View File

@@ -1,9 +1,9 @@
package com.x8bit.bitwarden.data.auth.manager.util
import com.bitwarden.crypto.TrustDeviceResponse
import com.bitwarden.network.model.TrustedDeviceUserDecryptionOptionsJson
import com.bitwarden.network.model.UserDecryptionOptionsJson
import com.x8bit.bitwarden.data.auth.datasource.disk.model.UserStateJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.TrustedDeviceUserDecryptionOptionsJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.UserDecryptionOptionsJson
/**
* Converts the given [TrustDeviceResponse] to an updated [UserStateJson], given the following

View File

@@ -1,17 +1,19 @@
package com.x8bit.bitwarden.data.auth.repository
import com.bitwarden.network.model.GetTokenResponseJson
import com.bitwarden.network.model.SyncResponseJson
import com.bitwarden.network.model.TwoFactorDataModel
import com.x8bit.bitwarden.data.auth.datasource.disk.model.ForcePasswordResetReason
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.network.model.GetTokenResponseJson
import com.x8bit.bitwarden.data.auth.datasource.network.model.TwoFactorDataModel
import com.x8bit.bitwarden.data.auth.manager.AuthRequestManager
import com.x8bit.bitwarden.data.auth.repository.model.AuthState
import com.x8bit.bitwarden.data.auth.repository.model.BreachCountResult
import com.x8bit.bitwarden.data.auth.repository.model.DeleteAccountResult
import com.x8bit.bitwarden.data.auth.repository.model.EmailTokenResult
import com.x8bit.bitwarden.data.auth.repository.model.KnownDeviceResult
import com.x8bit.bitwarden.data.auth.repository.model.LeaveOrganizationResult
import com.x8bit.bitwarden.data.auth.repository.model.LoginResult
import com.x8bit.bitwarden.data.auth.repository.model.LogoutReason
import com.x8bit.bitwarden.data.auth.repository.model.NewSsoUserResult
import com.x8bit.bitwarden.data.auth.repository.model.OrganizationDomainSsoDetailsResult
import com.x8bit.bitwarden.data.auth.repository.model.PasswordHintResult
@@ -37,7 +39,6 @@ import com.x8bit.bitwarden.data.auth.repository.util.SsoCallbackResult
import com.x8bit.bitwarden.data.auth.repository.util.WebAuthResult
import com.x8bit.bitwarden.data.auth.util.YubiKeyResult
import com.x8bit.bitwarden.data.platform.datasource.network.authenticator.AuthenticatorProvider
import com.x8bit.bitwarden.data.vault.datasource.network.model.SyncResponseJson
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
@@ -230,10 +231,33 @@ interface AuthRepository : AuthenticatorProvider, AuthRequestManager {
organizationIdentifier: String,
): LoginResult
/**
* Repeat the previous login attempt but this time with New Device OTP
* information. Password is included if available to unlock the vault after
* authentication. Updated access token will be reflected in [authStateFlow].
*/
suspend fun login(
email: String,
password: String?,
newDeviceOtp: String,
captchaToken: String?,
orgIdentifier: String?,
): LoginResult
/**
* Continue the previously halted login attempt.
*/
suspend fun continueKeyConnectorLogin(): LoginResult
/**
* Cancel the previously halted login attempt.
*/
fun cancelKeyConnectorLogin()
/**
* Log out the current user.
*/
fun logout()
fun logout(reason: LogoutReason)
/**
* Requests that a one-time passcode be sent to the user's email.
@@ -252,6 +276,11 @@ interface AuthRepository : AuthenticatorProvider, AuthRequestManager {
*/
suspend fun resendVerificationCodeEmail(): ResendEmailResult
/**
* Resend the email with the new device verification code.
*/
suspend fun resendNewDeviceOtp(): ResendEmailResult
/**
* Switches to the account corresponding to the given [userId] if possible.
*/
@@ -362,8 +391,10 @@ interface AuthRepository : AuthenticatorProvider, AuthRequestManager {
/**
* Get the password strength for the given [email] and [password] combo.
* If no value is passed for the [email] will use the active email of the current active
* account via the [userStateFlow].
*/
suspend fun getPasswordStrength(email: String, password: String): PasswordStrengthResult
suspend fun getPasswordStrength(email: String? = null, password: String): PasswordStrengthResult
/**
* Validates the master password for the current logged in user.
@@ -401,20 +432,12 @@ interface AuthRepository : AuthenticatorProvider, AuthRequestManager {
/**
* Update the value of the onboarding status for the user.
*/
fun setOnboardingStatus(userId: String, status: OnboardingStatus?)
fun setOnboardingStatus(status: OnboardingStatus)
/**
* Checks if a new device notice should be displayed.
* Leaves the organization that matches the given [organizationId]
*/
fun checkUserNeedsNewDeviceTwoFactorNotice(): Boolean
/**
* Gets the new device notice state of active user.
*/
fun getNewDeviceNoticeState(): NewDeviceNoticeState?
/**
* Stores the new device notice state for active user.
*/
fun setNewDeviceNoticeState(newState: NewDeviceNoticeState?)
suspend fun leaveOrganization(
organizationId: String,
): LeaveOrganizationResult
}

View File

@@ -1,11 +1,13 @@
package com.x8bit.bitwarden.data.auth.repository.di
import com.bitwarden.data.datasource.disk.ConfigDiskSource
import com.bitwarden.data.manager.DispatcherManager
import com.bitwarden.network.service.AccountsService
import com.bitwarden.network.service.DevicesService
import com.bitwarden.network.service.HaveIBeenPwnedService
import com.bitwarden.network.service.IdentityService
import com.bitwarden.network.service.OrganizationService
import com.x8bit.bitwarden.data.auth.datasource.disk.AuthDiskSource
import com.x8bit.bitwarden.data.auth.datasource.network.service.AccountsService
import com.x8bit.bitwarden.data.auth.datasource.network.service.DevicesService
import com.x8bit.bitwarden.data.auth.datasource.network.service.HaveIBeenPwnedService
import com.x8bit.bitwarden.data.auth.datasource.network.service.IdentityService
import com.x8bit.bitwarden.data.auth.datasource.network.service.OrganizationService
import com.x8bit.bitwarden.data.auth.datasource.sdk.AuthSdkSource
import com.x8bit.bitwarden.data.auth.manager.AuthRequestManager
import com.x8bit.bitwarden.data.auth.manager.KeyConnectorManager
@@ -13,13 +15,11 @@ import com.x8bit.bitwarden.data.auth.manager.TrustedDeviceManager
import com.x8bit.bitwarden.data.auth.manager.UserLogoutManager
import com.x8bit.bitwarden.data.auth.repository.AuthRepository
import com.x8bit.bitwarden.data.auth.repository.AuthRepositoryImpl
import com.x8bit.bitwarden.data.platform.datasource.disk.ConfigDiskSource
import com.x8bit.bitwarden.data.platform.manager.FeatureFlagManager
import com.x8bit.bitwarden.data.platform.manager.FirstTimeActionManager
import com.x8bit.bitwarden.data.platform.manager.LogsManager
import com.x8bit.bitwarden.data.platform.manager.PolicyManager
import com.x8bit.bitwarden.data.platform.manager.PushManager
import com.x8bit.bitwarden.data.platform.manager.dispatcher.DispatcherManager
import com.x8bit.bitwarden.data.platform.repository.EnvironmentRepository
import com.x8bit.bitwarden.data.platform.repository.SettingsRepository
import com.x8bit.bitwarden.data.vault.datasource.sdk.VaultSdkSource

View File

@@ -12,5 +12,8 @@ sealed class BreachCountResult {
/**
* There was an error determining if the password has been breached.
*/
data object Error : BreachCountResult()
data class Error(
val error: Throwable,
val message: String? = null,
) : BreachCountResult()
}

View File

@@ -12,5 +12,8 @@ sealed class DeleteAccountResult {
/**
* There was an error deleting the account.
*/
data class Error(val message: String?) : DeleteAccountResult()
data class Error(
val message: String?,
val error: Throwable?,
) : DeleteAccountResult()
}

View File

@@ -18,5 +18,8 @@ sealed class EmailTokenResult {
/**
* There was an error validating the token.
*/
data class Error(val message: String?) : EmailTokenResult()
data class Error(
val message: String?,
val error: Throwable?,
) : EmailTokenResult()
}

View File

@@ -12,5 +12,7 @@ sealed class KnownDeviceResult {
/**
* There was an error determining if this is a known device.
*/
data object Error : KnownDeviceResult()
data class Error(
val error: Throwable,
) : KnownDeviceResult()
}

View File

@@ -0,0 +1,18 @@
package com.x8bit.bitwarden.data.auth.repository.model
/**
* Models result of deleting an account.
*/
sealed class LeaveOrganizationResult {
/**
* Leave organization succeeded.
*/
data object Success : LeaveOrganizationResult()
/**
* There was an error leaving the organization.
*/
data class Error(
val error: Throwable?,
) : LeaveOrganizationResult()
}

View File

@@ -14,15 +14,30 @@ sealed class LoginResult {
*/
data class CaptchaRequired(val captchaId: String) : LoginResult()
/**
* Encryption key migration is required.
*/
data object EncryptionKeyMigrationRequired : LoginResult()
/**
* Two-factor verification is required.
*/
data object TwoFactorRequired : LoginResult()
/**
* User should confirm KeyConnector domain
*/
data class ConfirmKeyConnectorDomain(
val domain: String,
) : LoginResult()
/**
* There was an error logging in.
*/
data class Error(val errorMessage: String?) : LoginResult()
data class Error(
val errorMessage: String?,
val error: Throwable?,
) : LoginResult()
/**
* There was an error while logging into an unofficial Bitwarden server.
@@ -33,4 +48,9 @@ sealed class LoginResult {
* There was an error in validating the certificate chain for the server
*/
data object CertificateError : LoginResult()
/**
* New device verification is required
*/
data class NewDeviceVerification(val errorMessage: String?) : LoginResult()
}

View File

@@ -8,8 +8,12 @@ import com.x8bit.bitwarden.data.vault.repository.model.VaultUnlockResult
* the necessary `message` if applicable.
*/
fun VaultUnlockError.toLoginErrorResult(): LoginResult.Error = when (this) {
is VaultUnlockResult.AuthenticationError -> LoginResult.Error(this.message)
VaultUnlockResult.GenericError,
VaultUnlockResult.InvalidStateError,
-> LoginResult.Error(errorMessage = null)
is VaultUnlockResult.AuthenticationError -> {
LoginResult.Error(errorMessage = this.message, error = this.error)
}
is VaultUnlockResult.BiometricDecodingError,
is VaultUnlockResult.GenericError,
is VaultUnlockResult.InvalidStateError,
-> LoginResult.Error(errorMessage = null, error = this.error)
}

View File

@@ -0,0 +1,76 @@
package com.x8bit.bitwarden.data.auth.repository.model
/**
* Indicates the reason that the user is being logged out.
*/
sealed class LogoutReason {
/**
* An optional additional tag for an event.
*/
open val source: String? = null
/**
* Indicates that the logout is happening because the account was deleted.
*/
data object AccountDelete : LogoutReason()
/**
* Indicates that the logout is related to biometrics.
*/
sealed class Biometrics : LogoutReason() {
/**
* Indicates that the logout is caused by a biometrics lockout.
*/
data object Lockout : Biometrics()
/**
* Indicates that the logout is happening because biometrics is no longer supported.
*/
data object NoLongerSupported : Biometrics()
}
/**
* Indicates that the logout is happening because of an invalid state.
*/
data class InvalidState(
override val source: String,
) : LogoutReason()
/**
* Indicates that the logout is happening because the user opted to logout via a button.
*/
data class Click(
override val source: String,
) : LogoutReason()
/**
* Indicates that the logout is happening because the a logout notification was received.
*/
data object Notification : LogoutReason()
/**
* Indicates that the logout is happening because the sync security stamp was invalidated.
*/
data object SecurityStamp : LogoutReason()
/**
* Indicates that the logout is happening because of a timeout action.
*/
data object Timeout : LogoutReason()
/**
* Indicates that the logout is happening because the access token could not be refreshed.
*/
data object TokenRefreshFail : LogoutReason()
/**
* Indicates that the logout is happening because the user tried to unlock the vault
* unsuccessfully too many times.
*/
data object TooManyUnlockAttempts : LogoutReason()
/**
* Indicates that the logout is happening because the left the organization.
*/
data object LeftOrganization : LogoutReason()
}

View File

@@ -12,5 +12,7 @@ sealed class NewSsoUserResult {
/**
* There was an error while truing to create the new user.
*/
data object Failure : NewSsoUserResult()
data class Failure(
val error: Throwable,
) : NewSsoUserResult()
}

View File

@@ -1,6 +1,6 @@
package com.x8bit.bitwarden.data.auth.repository.model
import com.x8bit.bitwarden.data.vault.datasource.network.model.OrganizationType
import com.bitwarden.network.model.OrganizationType
/**
* Represents an organization a user may be a member of.
@@ -11,6 +11,7 @@ import com.x8bit.bitwarden.data.vault.datasource.network.model.OrganizationType
* own password.
* @property shouldUseKeyConnector Indicates that the organization uses a key connector.
* @property role The user's role in the organization.
* @property keyConnectorUrl The key connector domain (if applicable).
*/
data class Organization(
val id: String,
@@ -18,5 +19,6 @@ data class Organization(
val shouldManageResetPassword: Boolean,
val shouldUseKeyConnector: Boolean,
val role: OrganizationType,
val shouldUsersGetPremium: Boolean,
val keyConnectorUrl: String?,
val userIsClaimedByOrganization: Boolean,
)

View File

@@ -22,5 +22,7 @@ sealed class OrganizationDomainSsoDetailsResult {
/**
* The request failed.
*/
data object Failure : OrganizationDomainSsoDetailsResult()
data class Failure(
val error: Throwable,
) : OrganizationDomainSsoDetailsResult()
}

View File

@@ -13,5 +13,8 @@ sealed class PasswordHintResult {
/**
* There was an error.
*/
data class Error(val message: String?) : PasswordHintResult()
data class Error(
val message: String?,
val error: Throwable?,
) : PasswordHintResult()
}

View File

@@ -16,5 +16,7 @@ sealed class PasswordStrengthResult {
/**
* There was an error determining the password strength.
*/
data object Error : PasswordStrengthResult()
data class Error(
val error: Throwable,
) : PasswordStrengthResult()
}

View File

@@ -14,5 +14,8 @@ sealed class PrevalidateSsoResult {
/**
* There was an error in prevalidation.
*/
data object Failure : PrevalidateSsoResult()
data class Failure(
val message: String? = null,
val error: Throwable?,
) : PrevalidateSsoResult()
}

View File

@@ -9,7 +9,7 @@ sealed class RegisterResult {
*
* @param captchaToken the captcha bypass token to bypass future captcha verifications.
*/
data class Success(val captchaToken: String) : RegisterResult()
data class Success(val captchaToken: String?) : RegisterResult()
/**
* Captcha verification is required.
@@ -23,7 +23,10 @@ sealed class RegisterResult {
*
* @param errorMessage a message describing the error.
*/
data class Error(val errorMessage: String?) : RegisterResult()
data class Error(
val errorMessage: String?,
val error: Throwable?,
) : RegisterResult()
/**
* Password hash was found in a data breach.

View File

@@ -12,5 +12,12 @@ sealed class RemovePasswordResult {
/**
* There was an error removing the password.
*/
data object Error : RemovePasswordResult()
data class Error(
val error: Throwable,
) : RemovePasswordResult()
/**
* There was wrong password error removing the password.
*/
data object WrongPasswordError : RemovePasswordResult()
}

View File

@@ -13,5 +13,8 @@ sealed class RequestOtpResult {
/**
* Represents a failure to send the one-time passcode.
*/
data class Error(val message: String?) : RequestOtpResult()
data class Error(
val message: String?,
val error: Throwable,
) : RequestOtpResult()
}

View File

@@ -13,5 +13,8 @@ sealed class ResendEmailResult {
/**
* There was an error.
*/
data class Error(val message: String?) : ResendEmailResult()
data class Error(
val message: String?,
val error: Throwable,
) : ResendEmailResult()
}

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