1
0
mirror of https://github.com/bitwarden/mobile synced 2025-12-05 23:53:33 +00:00

Compare commits

...

1021 Commits

Author SHA1 Message Date
github-actions[bot]
72f2983885 Bumped version to 2022.6.0 (#1968)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
(cherry picked from commit d9a818279f)
2022-06-29 09:12:27 -07:00
Matt Gibson
ee68dcf3b0 Add ssoToken to limit lifetime of SSO redirect (#1965)
(cherry picked from commit 6e2e613fee)
2022-06-27 16:05:11 -04:00
Federico Andrés Maccaroni
daab473cbb SG-396 Fix tappable area after hiding account switching 2022-06-21 09:33:59 -03:00
Joseph Flinn
e6b99270cf Pin NuGet version (#1957)
* Pinning the version of NuGet to 5.x

* pinning NuGet verison to 5.9.x

* pinning NuGet to 5.9.0.7134

* pinning NuGet to 5.9.0

(cherry picked from commit c892e9fa57)
2022-06-16 14:48:47 -07:00
Federico Andrés Maccaroni
a8d9aaa7fe [SG-386] iOS Update user state when coming from background 2022-06-16 14:01:28 -03:00
mp-bw
542ef5f31a fix for missing personal items added prior to joining org with personal ownership policy (#1955) 2022-06-16 09:56:03 -04:00
mp-bw
0b2fc2a647 separate init and showVaultFilter property set (#1954) 2022-06-15 15:19:34 -04:00
mp-bw
a95fdf67a1 [SG-390] Fix for missing org items with single org & personal ownership enabled (#1953)
* fix for missing org items with single org & personal ownership enabled

* fix for ui issue with vault filter state change on pull to refresh
2022-06-15 10:45:01 -04:00
mp-bw
73890162bf Additional logic around filter display (#1951) 2022-06-14 13:05:28 -04:00
Joseph Flinn
ef14a8f850 Updating the release version check to use the new action (#1934)
* Updating the release version check to use the new action

* Update .github/workflows/release.yml

Co-authored-by: Vince Grassia <593223+vgrassia@users.noreply.github.com>

Co-authored-by: Vince Grassia <593223+vgrassia@users.noreply.github.com>
(cherry picked from commit 5579817f9f)
2022-06-13 12:59:24 -07:00
mp-bw
51a5f58258 Fixed vault filter display issue with personal ownership policy (#1950) 2022-06-13 10:30:32 -03:00
mp-bw
388ad4e840 lib updates (#1949) 2022-06-10 12:24:02 -04:00
mp-bw
48a8d9ae35 Clipboard handling adjustments for Android 13 (#1947)
* Android 13 clipboard tweaks

* adjustments

* adjustments round 2
2022-06-10 12:02:17 -04:00
mp-bw
dd6003bd4f alphabetize org list in vault filter (#1945) 2022-06-08 17:20:23 -04:00
Federico Maccaroni
fba407f3b6 SG-210 Account Switching in Autofill (iOS) (#1909)
* SG-210 Set up account switching on Autofill iOS

* SG-210 Fix refresh after sync on autofill ciphers, also added account switching on lock view on autofill. Also fix possible crash when scrolling when no items were displayed and also fixed navigation when login in on an automatically logged out account.

* SG-210 Added reference on iOS.Core project

* Fix formatting on AccountManager

* SG-210 Fix background color for dark theme
2022-06-08 14:24:01 -03:00
mp-bw
88b406544b [SG-79] Add filter to search and preselect org in new cipher (#1944)
* Add filter to search and preselect org in new cipher

* formatting

* fixes
2022-06-08 09:39:53 -04:00
dwbit
3438ed94ce Changing Report crash logs to Submit crash logs (#1937)
* Changing Report crash logs to Submit crash logs

* Updated resources keys to match the new value

Co-authored-by: Federico Andrés Maccaroni <fedemkr@gmail.com>
2022-06-07 21:47:44 -03:00
Federico Maccaroni
ec71b21264 PS-785 Added logs for exceptions on UpdateTemplatedCell and the extra data on each ExtendedCollectionView usage (#1943) 2022-06-07 15:57:53 -03:00
Federico Maccaroni
b223f5f16e EC-255 fix crash when scanning TOTP; BeginInvokeOnMainThread doesn't bubble up the exception, just crashes because it throws the exception to the current main thread context; so it was changed to InvokeOnMainThreadAsync which does bubble up the exception. (#1942) 2022-06-07 10:46:48 -04:00
Carlos Gonçalves
0a64e4c918 PS-587 - Fix searchbar search textfield and icon colors for dark themes (#1941)
* PS-587 Fix searchbar search textfield and icon colors for dark themes

* PS-587 - PR corrections
2022-06-07 15:43:25 +01:00
mp-bw
9b41db962e Added monochrome element to adaptive icon for theme support in Android 13 (#1940) 2022-06-06 14:50:52 -03:00
Federico Maccaroni
43d3c7b5d7 Update PULL_REQUEST_TEMPLATE.md (#1938) 2022-06-06 10:30:59 -03:00
CarleyDiaz-Bitwarden-zz
8168089591 Updating icons for Linked and Boolean fields (#1935)
Update to icons used for Boolean and Linked to use real icons

Co-authored-by: CarleyDiaz-Bitwarden <103955722+CarleyDiaz-Bitwarden@users.noreply.github.com>
2022-06-02 16:43:14 -04:00
github-actions[bot]
6b55fc3032 Bumped version to 2022.05.1 (#1933)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-06-02 09:30:39 -04:00
github-actions[bot]
87ab42b155 Bumped version to 2022.05.0 (#1931)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-06-01 16:18:06 -04:00
André Filipe da Silva Bispo
98130e89de PS-689 Android: Accessibility - back buttons in search and vault > bin lack appropriate accessible name (#1929)
* PS-689 Added back buttons accessibility text

* PS-689 Changed resource key from "GoBack" to "TapToGoBack"

* PS-689: class rename
2022-06-01 20:50:19 +01:00
André Filipe da Silva Bispo
121f0e3628 PS-675 Added accessibility text to password show/hide toggles (#1926)
* PS-675 Added accessibility text to password show hide toggles

* PS-675 refactor string resource key name
2022-06-01 16:02:28 +01:00
mp-bw
8a3d88b3ce [SG-79] Mobile Vault Filter (#1928)
* [SG-79] Vault Filter

* Update vault button text after sync

* formatting

* cleanup

* cleanup
2022-05-31 13:34:54 -04:00
Federico Maccaroni
b8b41fe847 [PS-536] Fix vault blank after unlocking and back navigation (#1930)
* PS-536 Fix by hack vault blank after unlocking and back navigate when previous page has value on iOS

* PS-536 Added platform check to the hack so it doesn't affect Android performance given that's an issue particular for iOS
2022-05-27 17:17:08 -04:00
André Filipe da Silva Bispo
5bbef3ee16 [PS-676] Accessibility - "Options" expand/collapse control does not announce state (#1925)
* PS-676: Accessibility - "Options" expand/collapse control does not announce state
- Moved to click event to the stacklayout
- Added accessibility text to stacklayout
- Removed accessibility on views inside stacklayout

* PS-676 Changed event to command

Co-authored-by: André Bispo <abispo@bitwarden.com>
2022-05-27 14:52:19 +01:00
Carlos Gonçalves
9a2b6c8ec9 PS-593 - View model properties are now updated on main thread (#1927) 2022-05-27 14:16:45 +01:00
André Filipe da Silva Bispo
5272c99643 PS-674: Accessibility password generator toggles (#1924)
- Additional information for VoiceOver and TalkBack
- Added new labels

Co-authored-by: André Bispo <abispo@bitwarden.com>
2022-05-25 17:25:21 +01:00
André Filipe da Silva Bispo
43e9515a03 [PS-672] Accessibility - File/Text controls unintuitive, "Text" accessible name incorrect (#1923)
* PS-672: Accessibility - File/Text controls unintuitive, "Text" accessible name incorrect
- Added new text to help identify File / Text segmented button
- Added missing text for Text button accessibility

* PS-672: refactor code with pr suggestions

* PS-672: removed unnecessary code

* PS-672: change text from "click" to "tap"

* PS-672: removed comma

Co-authored-by: André Bispo <abispo@bitwarden.com>
2022-05-25 17:20:51 +01:00
André Filipe da Silva Bispo
7e9b7398c8 PS-90: App keeps asking for 2FA even though I've checked the "remember me" checkbox (#1921)
- Logout was removing the 2FA token, portion of code deleted.
- Clear saved token when 2FA error is returned by the server.

Co-authored-by: André Bispo <abispo@bitwarden.com>
2022-05-24 15:09:24 +01:00
Jake Fink
58d7b001a5 add master password reprompt to share sheet extension (#1922) 2022-05-23 16:01:04 -04:00
André Filipe da Silva Bispo
a259560d29 PS-592 Mobile - Name field is not prioritised in search results (#1907)
- Search method now gives priority to matches in the Name property

Co-authored-by: André Bispo <abispo@bitwarden.com>
2022-05-23 10:20:48 +01:00
André Filipe da Silva Bispo
22c746543a PS-518 - Add setting to block AppCenter / Analytics - Mobile (#1905)
* PS-518 - Add setting to block AppCenter / Analytics - Mobile
- Added another entry into Settings page under the Others section
- Added prompt to ask user to enable / disable Crash Reports
- Added compilation tags to remove if the build is FDroid 

* PS-518 Add setting to block AppCenter / Analytics - Mobile
- Reduced FDroid compilation tags throughout the code
- Added Init, Enable and State methods to Logger
- Simplified SettingsPageViewModel Enable/Disable code

* PS-518 Add setting to block AppCenter / Analytics - Mobile
- Appcenter references were removed from App project, 
- Removed FDroid build.yml code that was deleting Appcenter packages from App.csproj

Co-authored-by: André Bispo <abispo@bitwarden.com>
2022-05-18 17:59:19 +01:00
André Filipe da Silva Bispo
bcbc2738ca PS-591 Fix avoid ambiguous characters #1664 (#1906)
* PS-591 - iOS - Avoid ambiguous characters is activated inside the main client, but is deactivated when creating a vault item from the autofill prompt. #1664
- Refactor the name of the property Ambiguous to AvoidAmbiguous, this naming was misleading.
- Fixed bug where the boolean value for the AvoidAmbiguous property was being stored inverted.

* PS-591 - iOS - Avoid ambiguous characters is activated inside the main client, but is deactivated when creating a vault item from the autofill prompt. #1664
- Changed AvoidAmbiguous to AllowAmbiguous
- Added wrapper Prop to bind UI Toggle to VM

Co-authored-by: André Bispo <abispo@bitwarden.com>
2022-05-18 14:58:49 +01:00
Thomas Rittson
604e3b6892 Remove testing requirements from pr template (#1901) 2022-05-10 17:02:40 -04:00
mp-bw
b081a8c634 fix a11y issue with hCaptcha on iOS (#1896) 2022-04-28 15:30:33 -04:00
Federico Maccaroni
c251b950d1 PS-77 Updated two-factor email request to include the device identifier to check whether to send the 2fa email because of a new device (#1895) 2022-04-28 10:51:13 -03:00
github-actions[bot]
1bbe8d8b98 Bumped version to 2.18.1 (#1894)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-04-27 09:04:29 -07:00
github-actions[bot]
cdc41d3bef Bumped version to 2.18.0 (#1893)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-04-27 08:24:29 -07:00
Oscar Hinton
769851adfe Update .gitattributes to fix build issue (#1892) 2022-04-26 16:51:58 -04:00
Oscar Hinton
c988175e50 [TI-8] Add .git-blame-ignore-revs (#1891) 2022-04-26 11:27:13 -04:00
Oscar Hinton
04539af2a6 Run dotnet format (#1738) 2022-04-26 17:21:17 +02:00
Oscar Hinton
e0efcfbe45 Add dotnet-format tool (#1737) 2022-04-26 17:21:07 +02:00
Federico Maccaroni
57213607a7 PS-291 Fix password history to update the collection on the main thread to load correctly (#1890) 2022-04-25 17:43:55 -04:00
Federico Maccaroni
2cab62fda5 TDL-13 Removed workaround of null reference on LabelRenderer given that Xamarin forms has been updated with the fix (#1889) 2022-04-25 16:09:47 -03:00
sneakernuts
99828c7ead Switched org (#1887) 2022-04-22 13:35:19 +00:00
mp-bw
ab6dde4a11 update XF and revert old workarounds (#1885) 2022-04-21 21:29:47 -04:00
dwbit
80bd8ba9d1 Change source string 'copy notes' to 'copy note' (#1881)
Change the value for 'copy notes' to 'copy note' since it is applying a single action on 1 item. This source string is already 'copy note' in the browser extension.
2022-04-21 08:03:21 -04:00
dwbit
35853a3815 Contribution Documentation edits (#1880)
* Update crowdin manager and forum category

Updating Crowdin contact from Kyle to dwbit. Update 'User-to-User Support' forum category to 'Ask the Bitwarden Community'

* Text corrections

Correcting title of forum category

* Add 'category' to text change

Update the 'Ask the Bitwarden Community' text change.
2022-04-20 23:25:37 +01:00
mp-bw
cfbbea59e9 account switching in autofill UI (Android) (#1882) 2022-04-19 20:38:17 -04:00
Jake Fink
14d4b2ee29 [BEEEP] add context to search titles (#1878)
* add more descriptive titles to search pages

* add App Resources
2022-04-10 13:00:52 -04:00
github-actions[bot]
b6ad3527db Autosync the updated translations (#1877)
Co-authored-by: github-actions <>
2022-04-08 11:52:21 +02:00
mp-bw
88f6b60b97 Crash fixes (#1869)
* Crash fixes

* added HasAutofillService to DeviceActionService
2022-04-01 12:07:14 -04:00
github-actions[bot]
1f58b0cabe Autosync the updated translations (#1868)
Co-authored-by: github-actions <>
2022-04-01 12:12:08 +02:00
github-actions[bot]
284d728023 Autosync the updated translations (#1863)
Co-authored-by: github-actions <>
2022-03-25 01:21:43 +01:00
mp-bw
0796bf17ce Fix for missing token when checking for key connector migration (#1861) 2022-03-24 15:53:12 -04:00
github-actions[bot]
4bd06d2393 Bump version to 2.17.1 (#1859)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-03-22 12:41:49 -06:00
github-actions[bot]
a3a508eb83 Bump version to 2.17.0 (#1858)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-03-22 10:49:58 -06:00
Matt Portune
f10307c72d Remove verbose state & value storage debug logging (#1857) 2022-03-21 16:44:54 -04:00
Federico Maccaroni
840925c479 Added null checks for iOS crash OnActivated on KeyWindow (#1856) 2022-03-21 11:34:22 -04:00
github-actions[bot]
fdcb2d76c9 Bumped version to 2.16.5 (#1854)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-03-18 13:21:46 -07:00
jnolan912
4734fe4e43 Update ios Autofill page to match setting's name (#1354)
The option in the ios menu to get to autofill settings is called "Passwords" instead of "Passwords & Accounts"
2022-03-18 20:00:37 +00:00
Federico Maccaroni
383eee6ec7 Fixed flickering on iOS while loading collections for the collection crash hotfix (#1852) 2022-03-18 15:41:15 -03:00
github-actions[bot]
1d9671bc5c Autosync the updated translations (#1851)
Co-authored-by: github-actions <>
2022-03-18 01:18:33 +01:00
Federico Maccaroni
22b00bcb33 Fix iOS 15.4 crash from empty list to adding an item by awaiting after every header add; also added that on Settings just in case there is another crash scenario. (#1850) 2022-03-17 17:33:22 -03:00
Matt Portune
c1748acf39 Misc fixes for account switching (#1849)
* Misc fixes for account switching

* use unique bio integrity key in ShareExtension
2022-03-17 14:27:01 -04:00
Micaiah Martin
507c3faea1 Updated actions (#1848) 2022-03-17 09:24:42 -06:00
Chad Scharf
020a5c072d Update SECURITY.md (#1847)
* Update SECURITY.md

Add link to our HackerOne program for submitting potential security issues.

* Revise language on SECURITY.md
2022-03-15 15:54:45 -04:00
github-actions[bot]
c47aad0412 Bumped version to 2.16.4 (#1846)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-03-15 09:27:50 -07:00
Federico Maccaroni
7c83d7b37b Removed grouping from Settings to fix a crash on iOS 15.4 (#1845) 2022-03-15 10:19:34 -04:00
Federico Maccaroni
4d4e246a47 Fix #1745 crash on scroll of grouped collection view on iOS 15.4 beta (#1842) 2022-03-14 12:49:57 -04:00
github-actions[bot]
612e458071 Autosync the updated translations (#1839)
Co-authored-by: github-actions <>
2022-03-11 02:28:34 +01:00
Matt Portune
a2ec263116 fixes for font cutoff on samsung devices (#1838) 2022-03-10 13:55:48 -05:00
Micaiah Martin
5ade10d1fe Update input name to be consistent with other workflows (#1837) 2022-03-10 11:31:49 -07:00
Matt Portune
5008e1daa8 fixed issues with logging out inactive accounts (#1836) 2022-03-10 09:02:01 -05:00
Federico Maccaroni
ad7c656868 Prevent touches when root view is obscured by another screen on Android (#1835) 2022-03-10 09:55:58 -03:00
Joseph Flinn
bdd0ea007b Update hotfix release branch name to hotfix-rc (#1834) 2022-03-09 12:46:24 -08:00
Matt Portune
bf33f23c12 Fix for short profile Name value crashing app (#1833) 2022-03-09 09:00:04 -05:00
Matt Portune
c043528a16 fix for lock & logout message parsing issue (#1832) 2022-03-08 14:26:35 -05:00
Federico Maccaroni
fd74164f82 Remove Microsoft.AppCenter.Crashes from Core.csproj on FDroid on the build.yml (#1831) 2022-03-08 14:45:55 -03:00
Matt Portune
17cdc96352 fix for logging out active account from switcher and cleanup (#1830) 2022-03-07 15:15:21 -05:00
Vincent Salucci
fcc94d85af [Captcha] Implement for 2fa (#1827) 2022-03-07 12:39:38 -06:00
Matt Portune
79a76c4638 Support for lock/logout/remove accounts from account list (#1826)
* Support for lock/logout/remove accounts via long-press

* establish and set listview height before showing

* undo modification
2022-03-07 12:28:06 -05:00
stevenlele
efd83d07dd [SupportedBrowsers] add Alook (#1814) 2022-03-07 09:16:58 -05:00
github-actions[bot]
0f14aa242c Autosync the updated translations (#1825)
Co-authored-by: github-actions <>
2022-03-04 01:26:35 +01:00
Micaiah Martin
a33232dec0 Renewed certificates and profiles (#1823) 2022-03-03 11:20:34 -07:00
Matt Gibson
084072e485 Add url encoding to data parameter (#1822) 2022-03-02 11:32:43 -06:00
Federico Maccaroni
db7ca3b93e BEEEP: Abstract and Centralize Logging (#1663)
* Abstracted App Center Logging into its own component, so that we can have it centralized in one place and we avoid checking for FDroid on all the places we want to use it

* Implemented the new logger where Crashes.TrackError was being used except on some specific cases

* Improved logging, added a debug logger and removed AppCenter to be used on DEBUG
2022-03-02 14:15:16 -03:00
Matt Portune
34d0ecf64b support for per-user biometric state tracking (#1820) 2022-03-01 14:04:17 -05:00
Daniel James Smith
2076c11cbd Bump target framework to netcoreapp3.1 (#1817)
Co-authored-by: Micaiah Martin <77340197+mimartin12@users.noreply.github.com>
2022-02-28 12:04:09 -07:00
Micaiah Martin
4a508ea7a2 Added manual trigger for builds (#1819) 2022-02-28 11:30:27 -07:00
Matt Portune
9384b3e538 fixed migration and account removal issues (#1818) 2022-02-28 13:02:33 -05:00
Daniel James Smith
317e7dad9a BEEEP: Colorize hidden custom field when value visible (#1813) 2022-02-25 21:47:21 +01:00
github-actions[bot]
fac295c97b Autosync the updated translations (#1812)
Co-authored-by: github-actions <>
2022-02-25 12:29:47 +01:00
Matt Portune
f94812719d Apply Disable Favicon setting globally to match desktop (#1811)
* Apply Disable Favicon setting globally to match desktop

* streamline the approach to applying global settings
2022-02-24 17:13:00 -05:00
Matt Portune
be993bcd02 Fix for missing bio unlock on app restart (#1810) 2022-02-24 15:33:55 -05:00
Federico Maccaroni
c74ed668b5 Changed link on Settings "Change Master Password" and "Two Step Login" to go to the web vault settings. Also refactored a bit to reuse the urls (#1809) 2022-02-24 10:27:08 -03:00
Matt Portune
9201da8515 take environment into account when checking for existing account (#1808) 2022-02-23 15:30:49 -05:00
Matt Portune
2e8824ce05 Account Switching (#1807)
* Account Switching (#1720)

* Account switching

* WIP

* wip

* wip

* updates to send test logic

* fixed Send tests

* fixes for theme handling on account switching and re-adding existing account

* switch fixes

* fixes

* fixes

* cleanup

* vault timeout fixes

* account list status enhancements

* logout fixes and token handling improvements

* merge latest (#1727)

* remove duplicate dependency

* fix for initial login token storage paradox (#1730)

* Fix avatar color update toolbar item issue on iOS for account switching (#1735)

* Updated account switching menu UI (#1733)

* updated account switching menu UI

* additional changes

* add key suffix to constant

* GetFirstLetters method tweaks

* Fix crash on account switching when logging out when having more than user at a time (#1740)

* single account migration to multi-account on app update (#1741)

* Account Switching Tap to dismiss (#1743)

* Added tap to dismiss on the Account switching overlay and improved a bit the code

* Fix account switching overlay background transparent on the proper place

* Fixed transparent background and the shadow on the account switching overlay

* Fix iOS top space on Account switching list overlay after modal (#1746)

* Fix top space added to Account switching list overlay after closing modal

* Fix top space added to Account switching list overlay after closing modal on lock, login and home views just in case we add modals in the future there as well

* Usability: dismiss account list on certain events (#1748)

* dismiss account list on certain events

* use new FireAndForget method for back button logic

* Create and use Account Switching overlay control (#1753)

* Added Account switching overlay control and its own ViewModel and refactored accordingly

* Fix account switching Accounts list binding update

* Implemented dismiss account switching overlay when changing tabs and when selecting the same tab. Also updated the deprecated listener on CustomTabbedRenderer on Android (#1755)

* Overriden Equals on AvatarImageSource so it doesn't get set multiple times when it's the same image thus producing blinking on tab chaged (#1756)

* Usability improvements for logout on vault timeout (#1781)

* accountswitching fixes (#1784)

* Fix for invalid PIN lock state when switching accounts (#1792)

* fix for pin lock flow

* named tuple values and updated async

* clear send service cache on account switch (#1796)

* Global theme and account removal (#1793)

* Global theme and account removal

* remove redundant call to hide account list overlay

* cleanup and additional tweaks

* add try/catch to remove account dialog flow

Co-authored-by: Federico Maccaroni <fedemkr@gmail.com>
2022-02-23 12:40:17 -05:00
Micaiah Martin
ded3f07fa6 Fixes incorrect path in workflow (#1806) 2022-02-23 10:29:40 -06:00
Micaiah Martin
31a3ec963b [BEEEP] - Added workflows to ignored paths (#1802)
Makes sure that edits to workflow files don't trigger a build.
2022-02-23 09:34:26 -06:00
Micaiah Martin
4722d2f632 Add dry run option to release workflow (#1801)
* Add dry-run to release workflow.
2022-02-23 08:48:07 -06:00
Federico Maccaroni
fa1bc3fa14 Changed Input keyboard on phone to be the telephone keyboard and also capitalized the keyboard on some fields of add/edit identity (#1800) 2022-02-23 11:07:54 -03:00
Federico Maccaroni
fa8d59075b Fix Options being seen in two lines on Add/edit Send (#1798) 2022-02-22 12:28:43 -05:00
Federico Maccaroni
23ca0f4b93 Fix icon image size to be adaptive on Large Font Size Accessibility which fixes row height on large vault (#1795) 2022-02-22 10:33:38 -05:00
Chad Scharf
04f4ad48f0 We're Hiring (#1797)
Added link to README.md for Bitwarden Careers page.
2022-02-22 10:28:46 -03:00
Micaiah Martin
a9be659e27 Moved to new Google Service Account (#1789) 2022-02-18 15:05:13 -07:00
Micaiah Martin
39596d7533 Moved to new Google Service Account (#1788) 2022-02-18 15:21:59 -06:00
Micaiah Martin
dd2c24dcc7 Move to using shared workflow (#1787) 2022-02-18 13:29:14 -06:00
github-actions[bot]
ad6cf9318b Autosync the updated translations (#1786)
Co-authored-by: github-actions <>
2022-02-18 10:20:24 +01:00
Federico Maccaroni
ea471b0749 Fixed some Large Font Accessibility issues on Vault and Send screens for Icons Display #1774 (#1785) 2022-02-17 19:34:22 -03:00
Micaiah Martin
dbaa32b02c Created initial workflow for workflow linting (#1783) 2022-02-16 15:26:11 -06:00
Matt Gibson
46128bcfe6 Enforce Hold label (#1779)
* Enforce Hold label

* Linting

Co-authored-by: Micaiah Martin <77340197+mimartin12@users.noreply.github.com>
2022-02-16 08:43:46 -06:00
Federico Maccaroni
02562be8c7 Fix truncated bottom on Password generator when large font size is set on Android (#1782) 2022-02-15 19:10:43 -03:00
Joseph Flinn
95581bd4d9 Patch/release new build artifact name (#1778)
* Switching the iOS build artifact and release asset names

* disabling jobs/steps to test the new release asset name

* switching to download artifacts from rc

* testing the upload of the 'Bitwarden iOS' directory

* Build zip asset of the Bitwarden iOS asset

* trying a couple of different zip paths

* Final package test

* Re-enabling all of the jobs after testing
2022-02-15 07:57:21 -08:00
Jake Fink
aba34c38e9 remove erroneous autofill description (#1780) 2022-02-15 10:46:33 -05:00
github-actions[bot]
1af447c47f Bumped version to 2.16.3 (#1777)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-02-14 12:37:14 -08:00
Federico Maccaroni
4fb811ae87 Build: Upload dSYMs to AppCenter (#1776)
* Added dsym artifact to be uploaded alongside with the ipa o the build.yml

* Added dsym artifact to be uploaded alongside with the ipa o the build.yml

* Fixed build.yml dsym artifact

* Fix upload dsym build.yml

* Fix build.yml to check what gets exported and after this will become the adjustment for the dsym (disabling Android build for this test)

* Fix build.yml to copy all dsyms and artifact them (disabling Android build for this test)

* Fix build.yml to only copy all dsyms and ipa and artifact them (disabling Android build for this test)

* Added Appcenterr CLI and upload missing symbols for dSYM to the build

* Add secret to build workflow (#1771)

* Changed build.yml upload dsym command from upload-missing-symbols to upload-symbols

* Added restrictions for uploading iOS symbols to AppCenter on build.yml

Co-authored-by: Vince Grassia <593223+vgrassia@users.noreply.github.com>
2022-02-14 11:06:35 -08:00
Matt Portune
3127295444 Fix for vault timeout not firing on resume (#1775)
* fix for vault timeout not firing on resume

* call ResumedAsync with FireAndForget
2022-02-14 11:29:04 -05:00
Vincent Salucci
615136be96 [Icons] - BUG - Update groupings icon for collections (#1773) 2022-02-12 12:27:37 +00:00
github-actions[bot]
e4230ac4f6 Autosync the updated translations (#1766)
Co-authored-by: github-actions <>
2022-02-11 22:47:48 +01:00
Jake Fink
15e9915da6 check email for null before authenticating (#1769)
* check email for null before authenticating

* add return after logging out and track error if email not found
2022-02-11 13:46:17 -05:00
Jake Fink
59ed76d956 remove datepicker style workaround (#1768) 2022-02-11 12:23:51 -05:00
github-actions[bot]
972755c725 Bump version to 2.16.2 (#1765)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-02-10 13:47:03 -07:00
Federico Maccaroni
92c40e2984 Improved code for periodic Autofocus on scan for better cancellation and task handlilng (#1764) 2022-02-10 13:03:02 -05:00
Micaiah Martin
9eed421c67 Updated Sed expression for Android manifests (#1763) 2022-02-10 09:42:57 -07:00
github-actions[bot]
15db96b06c Bumped version to 2.16.1 (#1762)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-02-10 08:19:02 -08:00
Joseph Flinn
54ccc1cbca Add iOS Share Extension to our version bump automation (#1761) 2022-02-10 07:54:43 -08:00
github-actions[bot]
ee69364b1d Bumped version to 2.16.0 (#1760)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-02-10 06:46:19 -08:00
Federico Maccaroni
76f1057951 Improved Autofocus code on ScanPage for better cancellation and exception handling #1228 (#1759) 2022-02-09 14:22:04 -03:00
Vincent Salucci
3491c1aaeb [Help] Update links to new pattern (#1758) 2022-02-08 17:42:53 -06:00
Oscar Hinton
427ff09af0 Client & Version headers (#1757) 2022-02-08 17:43:40 +01:00
github-actions[bot]
10fafaf8c8 Autosync the updated translations (#1752)
Co-authored-by: github-actions <>
2022-02-04 12:56:49 +01:00
Federico Maccaroni
31cdf401f1 Fix delete account SSO with CME that the OTP parameter was being sent incorrectly to the server (#1751) 2022-02-03 17:46:45 -03:00
Vincent Salucci
4373cee636 [Icons] Fast follower changes (#1750) 2022-02-03 10:34:20 -06:00
Federico Maccaroni
63b27f4e6d Removed punctuation on some string resources regarding send (#1747) 2022-02-02 16:07:58 -03:00
Jake Fink
fba5ecf304 Set background of biometricCell from theme (#1744) 2022-01-31 22:00:05 +00:00
Federico Maccaroni
a183861b87 Cleared About information about push registration, just left it in DEBUG mode (#1742) 2022-01-31 14:48:35 -03:00
Federico Maccaroni
d0ffb108b1 Cleared Console.WriteLine for iOS push notifications issue (#1739) 2022-01-31 11:12:24 -03:00
github-actions[bot]
c0c893fd59 Autosync the updated translations (#1734)
Co-authored-by: github-actions <>
2022-01-28 11:08:29 +01:00
Oscar Hinton
5f29fc8f89 Update FA icons on LockPasswordViewController (#1729)
Co-authored-by: Jacob Fink <jfink@bitwarden.com>
2022-01-27 18:13:23 +01:00
Federico Maccaroni
f8a7eb4c94 Add Share app Extension on iOS for Send (re-PR) (#1660)
* WIP Add Share app extension on iOS for Send

* Added Share app extension on iOS for Send and some code fixes as well

* Updated iOS csprojs configs to linkskip the new extension project and also added AdHoc and AppStore configurations to iOS.ShareExtension.csproj

* Code clean up and transformed bundle resources into links to the already used pngs of the main iOS project on ShareExtension

* Updated build.yml to include provisioning profile for iOS Share extension

* Adding in the missing provisioning profile

* Removed .DS_Store from the iOS.ShareExtension csproj Resources

* switching out the share extension profile

* Added Share extension provisioning profile configuration on export options app store for github and also removed custom info.plist config for localhost which is not necessary

* Moved property so that it's grouped with the full ones

* Added AppCenter Crashes package to Core and updated FireAndForget Task Extension

* Updated bundle reference of FontAwesome.ttf to bwi-font.ttf in order for it to compile on ShareExtension

Co-authored-by: Joseph Flinn <joseph.s.flinn@gmail.com>
Co-authored-by: Álison Fernandes <vvolkgang@users.noreply.github.com>
2022-01-25 17:41:56 -03:00
Federico Maccaroni
ef6184a05b Added hide loading after requesting OTP on verification code (#1732) 2022-01-25 17:07:10 -03:00
Federico Maccaroni
37f4439892 Added Logs for PN registration checks (#1731) 2022-01-25 16:33:33 -03:00
Jake Fink
f1ccbbc105 Expand Settings TimePicker tap recognition to entire row (#1714)
* move timepicker to separate DataTemplate
- activate timepicker when selecting row

* null check on TimePicker
2022-01-24 15:21:52 -05:00
Federico Maccaroni
74e90da662 Improve Theming (#1707)
* Improved theming logic and performance, also fixed some issues regarding changing the theme after vault timeout and fixed theme applying on password generator/history

* Removed messenger from theme update, and now the navigation stack is traversed and each IThemeDirtablePage gets theme updated

* Improved code on update theme on pages
2022-01-24 17:20:48 -03:00
Federico Maccaroni
939db8ebe0 Fix icon update on verify code view (#1728) 2022-01-24 14:19:30 -03:00
Federico Maccaroni
4e7ceaf5b5 Account Deletion on SSO with CME (#1721)
* WIP Added Verification Code page and a verification flow helper to coordinate things

* Improved Verification Code page verification flow helper and fix some issues, also added flag ApiService to choose whether to logout on Unanuthorized

* Improved Verification Code page UI/UX verification flow helper and fix some issues and made some cleanups

* Fix spelling
2022-01-24 13:25:46 -03:00
Federico Maccaroni
5a6aec51f3 Fix Progress dialog crash on tombstoning (#1682)
* Changed ProgressDialog because deprecated and improved the dismissal of the dialog in order for it not to crash the app on certain situations

* Removed android version check given that our minimum is greater that the check
2022-01-21 23:14:48 +00:00
github-actions[bot]
137c762e40 Autosync the updated translations (#1724)
Co-authored-by: github-actions <>
2022-01-21 11:53:41 +01:00
Oscar Hinton
3f1674c1f1 Icon Updates (#1541) 2022-01-21 10:31:03 +01:00
Jake Fink
52024109f7 Check for disable save prompt option before sending fill request in Android Autofill (#1722)
* Check for disable save prompt option before sending fill request
- ignore save request payload if true

* Add exception handling to Autofill Service

* move System reference outside of FDROID
2022-01-20 09:51:42 -05:00
Jake Fink
6f3999016f Supress lock and logout when showing fileswitcher on Android (#1626)
* Supress lock and logout when showing fileswitcher on Android

* convert suppress bool to delay long
- move HandleVaultTimeoutAsync to vaultTimeoutService
2022-01-19 09:09:30 -05:00
Federico Maccaroni
2791d4b8ec Fixes for iOS push notifications (#1708)
* WIP Fixes for iOS push notifications

* WIP Fixes for iOS push notifications, fix missed implementation on android

* Fix some issues on the push notifications, changed to Debug Console.WriteLine, and added update on entitlements on the build.yml
2022-01-18 11:52:08 -03:00
Indranil012
42403210a0 Added kiwi Browser "Dev" package name for autofill support (#1694)
* Added Kiwi Browser Dev support
2022-01-17 22:10:33 +00:00
Vince Grassia
5e15a2f30e Update Version Bump action (#1717) 2022-01-12 16:07:01 -05:00
github-actions[bot]
c6547771a5 Autosync the updated translations (#1709)
Co-authored-by: github-actions <>
2022-01-07 13:51:27 +01:00
Federico Maccaroni
9fdcba386e Possible fix for iOS crash after long time idling (#1700) 2022-01-03 12:46:42 -03:00
github-actions[bot]
86397a6f1e Autosync the updated translations (#1705)
Co-authored-by: github-actions <>
2022-01-01 17:52:21 +01:00
github-actions[bot]
4c2e7331e3 Autosync the updated translations (#1699)
Co-authored-by: github-actions <>
2021-12-24 01:12:47 +01:00
Micaiah Martin
b55a450f44 Added logic for version check step (#1695) 2021-12-20 13:19:46 -07:00
Federico Maccaroni
b28e265ed4 Updated Delete account view UI (#1692) 2021-12-20 12:31:12 -03:00
github-actions[bot]
6164c764b4 Autosync the updated translations (#1693)
Co-authored-by: github-actions <>
2021-12-17 01:25:55 +01:00
Jake Fink
ad3b401ed3 remove re-throws of exceptions, hiding stack trace (#1680)
* remove re-throws of exceptions, hiding stack trace

* revert to catch all ApiExceptions

* add back throw in auditService

* whitespace
2021-12-16 15:34:33 -05:00
Federico Maccaroni
adb8bb4f1b Fix by workaround crash on LabelRenderer and when changing themes #1689 (#1690) 2021-12-16 11:36:06 -03:00
Federico Maccaroni
04c7409418 Fix Unsafe deserialization of Parcel data Intent (#1691)
* Fix crash produced by unsafe deserialization of Parcel data passed on the intent

* Fix crash produced by unsafe deserialization of Parcel data passed on the intent on other activities and renamed intent extension method
2021-12-15 15:09:08 -03:00
Federico Maccaroni
705b8ac12b Fix Clipboard clear after time on iOS (#1679)
* Fixed Clipboard clear after x seconds depending on what the user set. Also refactored a bit to make the Clipboard a custom service to provide a better way to handle this situation #1464

* Clear some usings #1464
2021-12-10 17:41:36 -03:00
Jake Fink
23a164b245 include entitlements in ios.extension simulator builds (#1684) 2021-12-10 10:46:40 -05:00
github-actions[bot]
6f936343ae Bumped version to 2.15.1 (#1683)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2021-12-10 10:03:06 -05:00
github-actions[bot]
5eeec7d9ed Autosync the updated translations (#1681)
Co-authored-by: github-actions <>
2021-12-10 01:18:44 +01:00
github-actions[bot]
b95efae7fb Bumped version to 2.15.0 (#1676)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2021-12-08 09:57:29 -05:00
github-actions[bot]
4a1f28caf8 Autosync the updated translations (#1661)
Co-authored-by: github-actions <>
2021-12-07 17:03:34 +01:00
Jake Fink
dddc38ef64 move splash screen logic to OnResignActivation (#1674) 2021-12-07 09:45:05 -05:00
Jake Fink
05bcc10277 remove "singleTask" launch mode on Android 11+ (#1673)
* remove "singleTask" launch mode on Android 12+

* remove commented and unneccesary code

* fix formatting and change from Android 12 to Android 11
2021-12-06 14:17:56 -05:00
Micaiah Martin
ea1ee2c3d3 Added version bump workflow (#1669) 2021-11-30 15:53:18 -07:00
Jake Fink
2a373dd3fc only prompt for sso if using key connector (#1667) 2021-11-29 15:37:19 -05:00
Federico Maccaroni
14d2b833d8 Fix crash produced when adding a custom field on a Secure Note, because it try to load the control of linked fields even if it's not the type (#1668) 2021-11-29 15:33:29 -03:00
Federico Maccaroni
9fdf2ada6f Added account deletion feature on settings (#1621)
* Added account deletion feature on settings

* Disabled using Microsoft.AppCenter.Crashes for FDroid

* Moved drawable on Android.csproj to be with the others

Co-authored-by: Federico Maccaroni <fmaccaroni@bitwarden.com>
2021-11-24 16:09:39 -03:00
qflair
833103b2a0 Add support for Pluma Browser for Android (#1639) 2021-11-24 10:12:30 -05:00
Jonathan Almeida
6bae85b22d Update Focus/Klar accessibility and autofill IDs (#1535) 2021-11-24 09:44:10 -05:00
Jake Fink
34dfb0b57e Add workaround to Android entry renderer (#1658) 2021-11-23 08:18:31 -05:00
Thomas Rittson
ff35e3c022 [Key Connector] Hide MP input in iOS extensions (#1656)
* Hide MP on iOS unlock screen

* Update navbar if using biometric auth only

* Tidy up logic
2021-11-23 09:50:34 +10:00
Jake Fink
316cb4d21c ui changes for lock screen if using key connector with biometrics (#1654) 2021-11-19 17:25:19 -05:00
Federico Maccaroni
7d42d19ae3 Revert "Add Share app Extension on iOS for Send (#1647)" (#1655)
This reverts commit 75ed72f91b.
2021-11-19 17:00:54 -03:00
Federico Maccaroni
75ed72f91b Add Share app Extension on iOS for Send (#1647)
* WIP Add Share app extension on iOS for Send

* Added Share app extension on iOS for Send and some code fixes as well

* Updated iOS csprojs configs to linkskip the new extension project and also added AdHoc and AppStore configurations to iOS.ShareExtension.csproj

* Code clean up and transformed bundle resources into links to the already used pngs of the main iOS project on ShareExtension

* Updated build.yml to include provisioning profile for iOS Share extension

* Adding in the missing provisioning profile

* Removed .DS_Store from the iOS.ShareExtension csproj Resources

* switching out the share extension profile

* Added Share extension provisioning profile configuration on export options app store for github and also removed custom info.plist config for localhost which is not necessary

Co-authored-by: Joseph Flinn <joseph.s.flinn@gmail.com>
2021-11-19 15:05:00 -03:00
Jake Fink
e9b0bbb3a9 Bug/cme autofill unlock (#1653)
* Show SSO login if using key-connector without bio or pin

* remove additional call to enable biometrics and change method name
- ordered methods to group private and public

* allow sso for first biometric authenitcation
2021-11-19 11:24:48 -05:00
Jake Fink
94994af4a9 ui changes export vault screen for key connector (#1651)
* ui changes export vault screen for key connector

* update label and remove period
2021-11-19 09:44:01 -05:00
github-actions[bot]
68c484b67f Autosync the updated translations (#1652)
Co-authored-by: github-actions <>
2021-11-19 13:04:21 +01:00
Federico Maccaroni
1b60ac3699 Fixed missing FavIcons on Android #1640 (#1649)
* Set custom HttpClient for FFImageLoading to set AndroidClientHandler in order to load icons from icon server due to a problem with the SSL certificate when using the default HttpClientHandler #1640

* Using cleanup for FDroid  #1640

* Added System.Net.Http on Android.csproj for FDroid only to check if that fixes the build
2021-11-18 17:38:23 -03:00
Thomas Rittson
1c006d6218 Hide Master Pass On Restart for Key Connector (#1650) 2021-11-19 05:01:44 +10:00
Jake Fink
3e0e620bb7 Show SSO login if using key-connector without bio or pin (#1648)
* Show SSO login if using key-connector without bio or pin

* remove additional call to enable biometrics and change method name
- ordered methods to group private and public
2021-11-17 12:44:27 -05:00
github-actions[bot]
14177efdda Autosync the updated translations (#1642)
Co-authored-by: github-actions <>
2021-11-16 10:58:30 -05:00
Jake Fink
3ee80beda8 pass OrgId to SSO login while using CME (#1646) 2021-11-16 09:34:26 -05:00
Jake Fink
13869b5a1b [KeyConnector] Add support for key connector OTP (#1633)
* initial commit
- add UsesKeyConnector to UserService
- add models
- begin work on authentication

* finish auth workflow for key connector sso login
- finish api call for get user key
- start api calls for posts to key connector

* Bypass lock page if already unlocked

* Move logic to KeyConnectorService, log out if no pin or biometric is set

* Disable password reprompt when using key connector

* hide password reprompt checkbox when editing or adding cipher

* add PostUserKey and PostSetKeyConnector calls

* add ConvertMasterPasswordPage

* add functionality to RemoveMasterPasswordPage
- rename Convert to Remove

* Hide Change Master Password button if using key connector

* Add OTP verification for export component

* Update src/App/Pages/Vault/AddEditPage.xaml.cs

Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com>

* remove toolbar item "close"

* Update src/Core/Models/Request/KeyConnectorUserKeyRequest.cs

Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com>

* remove new line in resource string
- format warning as two labels
- set label in code behind for loading simultaneously

* implement GetAndSetKey in KeyConnectorService
- ignore EnvironmentService call

* remove unnecesary orgIdentifier

* move RemoveMasterPasswordPage call to LockPage

* add spacing to export vault page

* log out if no PIN or bio on lock page with key connector

* Delete excessive whitespace

* Delete excessive whitespace

* Change capitalisation of OTP

* add default value to models for backwards compatibility

* remove this keyword

* actually handle exceptions

* move RemoveMasterPasswordPage to TabPage using messaging service

* add minor improvements

* remove 'this.'

Co-authored-by: Hinton <oscar@oscarhinton.com>
Co-authored-by: Thomas Rittson <trittson@bitwarden.com>
Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com>
2021-11-10 20:46:48 -05:00
Thomas Rittson
90b62d61ae [Linked fields] Add Linked Field as a custom field type (#1563)
* Add linked fields support

* Fix style, don't show linked field if Secure Note

* Finish basic linked fields for Login

* Use Field.LinkedId to store linked field info

* Reset Linked Custom Fields if cipherType changes

* Refactor to use ItemView class

* Use enum for LinkedId

* Detect if no linkedFieldOptions
2021-11-09 07:34:16 +10:00
Vince Grassia
3cb8adeeff Change Release workflow to allow releases from 'rc' and 'hotfix' branches (#1632) 2021-11-08 09:48:40 -05:00
Joseph Flinn
5b972eec24 fixing a typo (#1634) 2021-11-05 11:38:51 -07:00
Joseph Flinn
e97ac1dd9b Updating the crowdin sync process (#1630) 2021-11-05 10:59:15 -07:00
Jake Fink
df496e39ff load app resources into ThemeManager before appearance adjustments (#1631) 2021-11-05 09:51:48 -04:00
Joseph Flinn
dbf94c1b56 Updating gh-pages (#1628) 2021-11-04 09:29:07 -07:00
Matt Portune
4b0fb2840e bump version for testflight (#1629) 2021-11-03 13:04:54 -04:00
stevenlele
629c696c81 [SupportedBrowsers] Add Captive Login and drop Alook (#1625) 2021-11-02 09:17:10 -04:00
Joseph Flinn
bf1aa7c4eb Version bump 2.14.2 (#1622) 2021-10-29 12:50:11 -07:00
Jake Fink
318a3e4de9 fix for bug stopping vault timeout to never (#1618)
- use nullable int on settings page and in vault service
2021-10-29 10:31:38 -04:00
Makoto Kato
0f992d27b3 Turn off autofill compatibility mode on the latest Firefox and Firefox beta. (#1592) 2021-10-28 14:44:24 -04:00
Jake Fink
83fd6736f6 add date and time formatting methods to localize service (#1616)
- uses Apple APIs for formatting on iOS
- uses .Net APIs for formatting Android
- implemented across project
- remove unnecesary calls to DateTimeConverter
2021-10-28 12:52:41 -04:00
Matt Portune
397250368a remove numeric restriction on cc number field (#1617) 2021-10-28 12:52:04 -04:00
Joseph Flinn
5e4365084b Version bump 2.14.1 (#1614) 2021-10-28 06:50:13 -07:00
Joseph Flinn
ea5e4aafa3 adding the missing flag for sed in the fdroid build (#1613) 2021-10-28 06:49:29 -07:00
Joseph Flinn
69d1de47c6 Fixing release template name (#1611) 2021-10-27 13:10:21 -07:00
Joseph Flinn
0d3f819e93 Version Bump 2.14.0 (#1610) 2021-10-27 08:40:08 -07:00
github-actions[bot]
3760e0f9f4 Autosync the updated translations (#1609)
Co-authored-by: github-actions <>
2021-10-27 07:52:31 -07:00
Thomas Rittson
5a13cb53ba Add PR template (#1608) 2021-10-27 18:59:59 +10:00
Jake Fink
0e9cbe4539 add reveal button to password reprompt on iOS (#1607)
* add reveal button to password reprompt on iOS

* format special chars as unicode
2021-10-26 17:46:11 -04:00
Federico Maccaroni
b8c1107c94 Fixed long secure notes edition scrolling when focused issue (#1257) (#1601)
* Fixed long secure notes edition scrolling when focused issue (#1257)

* Improved fix long secure notes edition scrolling when focused issue to not use a new editor custom renderer but an effect (#1257)

* Fixed long editor, on text and notes on send when scrolling when focused issue (#1257)
2021-10-25 16:28:45 -03:00
Federico Maccaroni
a07ef1a1d6 Fix html labels colors issue (#1516) (#1603) 2021-10-25 16:28:14 -03:00
Joseph Flinn
99ccd62bcd Release branch constraint on build (#1599)
* adding in the release branch constraint to the build workflow for mobile

* moving the branch check to a setup job
2021-10-22 13:16:57 -07:00
Joseph Flinn
bfb050a6f9 Change release branch contraint (#1598)
* removing the master branch release ci code execution

* updating some verbiage
2021-10-22 09:24:48 -07:00
Matt Portune
4e0b05571d utilize iOS safe area in UI (#1597) 2021-10-22 10:06:17 -04:00
Matt Portune
d93d70fd66 Autofill support for upcoming changes to google search (#1596) 2021-10-21 10:45:48 -04:00
Matt Portune
41098ff05b fix gap in background color application resulting in flashing during transitions, part 2 (#1595) 2021-10-18 09:56:20 -04:00
Matt Portune
4ed7491116 fix for crash when checking for running accessibility service without activity (#1591) 2021-10-18 09:56:12 -04:00
Matt Portune
1ebad6bca5 fix for crash when terminating app (#1589) 2021-10-16 07:56:17 -04:00
Matt Portune
48e3986264 fix gap in theme application resulting in flashing during transitions (#1588) 2021-10-15 15:46:24 -04:00
Vince Grassia
88a1d8d4e8 Add notify constraint (#1587) 2021-10-15 13:06:53 -04:00
Jake Fink
f3ff991abe check password for null before setting cursor position (#1586) 2021-10-15 10:56:12 -04:00
Kyle Spearrin
17b89dc21c New Crowdin updates (#1583)
* New translations AppResources.resx (Romanian)

* New translations AppResources.resx (Norwegian Nynorsk)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Vietnamese)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Tamil)

* New translations AppResources.resx (Bengali)

* New translations AppResources.resx (Thai)

* New translations AppResources.resx (Croatian)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Latvian)

* New translations AppResources.resx (Azerbaijani)

* New translations AppResources.resx (Hindi)

* New translations AppResources.resx (English, United Kingdom)

* New translations AppResources.resx (Filipino)

* New translations AppResources.resx (Malayalam)

* New translations AppResources.resx (Bosnian)

* New translations AppResources.resx (Sinhala)

* New translations AppResources.resx (Kannada)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Afrikaans)

* New translations AppResources.resx (Belarusian)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Greek)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Slovenian)

* New translations AppResources.resx (Serbian (Cyrillic))

* New translations AppResources.resx (English, India)

* New translations copy.resx (English, United Kingdom)

* New translations copy.resx (Chinese Simplified)

* New translations copy.resx (English, India)

* New translations copy.resx (English, United Kingdom)

* New translations copy.resx (Chinese Simplified)

* New translations copy.resx (English, India)
2021-10-14 19:22:33 -04:00
github-actions[bot]
ff76a3ec15 Autosync the updated translations (#1582)
Co-authored-by: github-actions <>
2021-10-14 18:04:06 -04:00
Vince Grassia
3a2e012c42 Add Slack alerts for Build workflow failures (#1581) 2021-10-14 14:34:24 -04:00
Matt Portune
a0bb16c35f fix for crash on startup when policies are non-existent (#1579) 2021-10-14 13:53:57 -04:00
Jake Fink
62a8d1c017 fix for Captcha crashing on account creation (#1580) 2021-10-14 13:42:48 -04:00
Matt Portune
ce4e3ed1cd support for new btnReturnText in mobile webauthn connector (#1576)
* support for new btnReturnText in mobile webauthn connector

* added header text for connector localization
2021-10-14 11:53:41 -04:00
Matt Portune
4669275680 Fix for Android 5.x crash caused by new switch styling (#1575) 2021-10-13 12:26:54 -04:00
Jake Fink
fc1000acc1 loop through URIs to find website before showing default icons (#1572)
- create static class for uri logic (keeping converter for future)
- create new property in viewmodel for icon source
- check if icons are enabled and source for icon before showing default glyph
2021-10-12 11:00:33 -04:00
Oscar Hinton
c9ce7256e5 MaximumVaultTimeout policy fixes (#1573) 2021-10-12 15:35:01 +02:00
Vincent Salucci
34aba0e168 [Reset Password] BUG - Update local policies for enforcement (#1565)
* [Reset Password] BUG - Update local policies for enforcement

* Updated with blocking sync

* add the stuff I forgot to tell vsalucci about

* removed the lies I fed vsalucci

* remove unnecessary import

Co-authored-by: Matt Portune <mportune@bitwarden.com>
2021-10-08 16:51:16 -05:00
Matt Portune
9e9e2e12d8 fix padding between sync button and last sync timestamp (#1571) 2021-10-08 15:56:36 -04:00
Jake Fink
3eec349038 Fix crash from SelectableLabelRenderer (#1570) 2021-10-08 13:14:23 -04:00
Jake Fink
69650a1ab5 Hide label if no subtitle for Cipher (#1569) 2021-10-08 12:09:26 -04:00
Jake Fink
faac7ebe5e Set cursor position after toggle password visibility (#1568)
- Lock page
- Login page
- Register page
2021-10-08 12:09:08 -04:00
Jake Fink
d3734c63fc Add SelectableLabel Custom Renderer to allow copy of note text (#1564)
* Add SelectableLabel Custom Renderer to allow copy of note text
- Remove SelectableLabelEffect

* Remove editor changes from text custom field
2021-10-08 08:49:15 -04:00
Matt Portune
4aad34cd75 Dynamic theme switching and visual tweaks (#1556)
* Dynamic theme switching and visual tweaks

* update action runner to use macos-11 for iOS 15 support

* additional tweaks

* refinements

* refinements

* formatting and tweaks
2021-10-08 08:47:40 -04:00
Matt Gibson
73eb3c2c1e Split collections permissions (#1558)
* Split collections permissions

* Remove old permissions

There is no backwards compatibility issue since these permissions are unused.

* Remove unused imports
2021-10-05 11:12:55 -05:00
Jake Fink
6109091ec0 filter Ciphers to exclude deleted items (#1559) 2021-10-04 13:46:45 -04:00
Jake Fink
c0783cd162 Exclude deleted items from folder counts (#1555) 2021-10-04 08:33:23 -04:00
Vince Grassia
a9a4fa56c1 Pipeline fixes (#1549)
* Update path to fix 'Deploy to App Store' step in Build workflow
* Change `sed` to save changes to file by using `-i` flag
2021-09-24 17:02:34 -04:00
Vincent Salucci
271e6b3d92 [Reset Password v1] Update Temp Password (#1492)
* [Reset Password v1] Update Temp Password

* fixed order of operations for reset temp password flow

* Refactored bool with auth result

* Finished removal of temp password flow from set password

* iOS extension support plus extension bugfixes

Co-authored-by: addison <addisonbeck1@gmail.com>
Co-authored-by: Matt Portune <mportune@bitwarden.com>
2021-09-24 13:14:26 -05:00
Vince Grassia
750faf8a83 Update pipeline to new model (#1472)
* Update pipelines to new model
2021-09-24 13:50:54 -04:00
Thomas Rittson
716e52f6ff Move policy checks inside PolicyService (#1533)
* Move policy checks inside PolicyService

* Remove leftover code

* Remove duplicate code

* Reorder code for consistency
2021-09-24 09:51:02 +10:00
Matt Portune
010a4210f4 bump version for testflight (#1547) 2021-09-23 14:24:52 -04:00
Matt Portune
8d23bc89e8 Update XF to remove AndroidX dependency hack (#1544)
* update forms and other libs

* change async pattern
2021-09-23 13:11:51 -04:00
Oscar Hinton
f2857397f0 Disable Private Vault Export Policy (#1546) 2021-09-23 18:30:20 +02:00
Oscar Hinton
6023374fbe Vault Timeout Policy (#1530) 2021-09-23 15:42:38 +02:00
Joseph Flinn
d3c1b58c2a Version bump to 2.13.0 (#1545) 2021-09-22 08:58:18 -07:00
github-actions[bot]
a026af2072 Autosync the updated translations (#1543)
Co-authored-by: github-actions <>
2021-09-21 14:53:36 -07:00
Vincent Salucci
51be6e522b [SSO/Auto Enroll] Fixed response object typo (#1542) 2021-09-16 23:01:12 -05:00
Vincent Salucci
024d9380c9 [SSO Auto Enroll] Auto Enroll status retrieval (#1540)
* [SSO Auto Enroll] Auto Enroll status retrieval

* Updated object property to match server
2021-09-15 12:27:27 -05:00
Matt Portune
14b51b1a7f friendly message for webauthn errors (#1534)
* friendly error message for webauthn error flow

* combine original plus friendly message

* remove redundant phrasing
2021-09-09 10:04:49 -04:00
Oscar Hinton
4667a9d643 Add issue template and template chooser (#1526) 2021-09-09 11:54:43 +02:00
Vincent Salucci
d3f00340fb [SSO] Auto enroll during set password (#1520)
* [SSO] Auto enroll during set password

* Updated with requested changes
2021-09-08 12:43:24 -05:00
Matt Portune
8866fc6322 Bump version to 2.12.1 (#1529) 2021-09-07 13:50:05 -04:00
Matt Portune
68887c5de7 Bugfix typerole (#1528)
* Fix issue with undefined CFBundleTypeRole

* format with tabs for consistency
2021-09-07 12:50:22 -04:00
Vince Grassia
99b67b680c Update workflows with linter suggestions (#1521) 2021-09-02 16:04:41 -04:00
baylorrandolph
9b5bf4306f Update README.md (#1523) 2021-09-02 16:00:25 -04:00
baylorrandolph
be55504b01 Update README.md (#1522) 2021-09-02 15:46:04 -04:00
Matt Portune
307a5a5843 FIDO2 WebAuthn support for mobile (#1519)
* FIDO2 / WebAuthn support for mobile

* fixes
2021-08-30 12:44:12 -04:00
Joseph Flinn
d050215ebc Simplifying Crowdin sync workflow (#1517) 2021-08-27 10:08:40 -07:00
Matt Portune
67e26c778b Revert "bump MinimumOSVersion to 12.0 (#1508)" (#1515)
This reverts commit 745b54bf2a.
2021-08-25 17:03:33 -04:00
Matt Portune
efb10d155d Revert "enable LLVM in iOS builds (#1510)" (#1514)
This reverts commit 244a6a7f41.
2021-08-25 17:03:02 -04:00
Matt Portune
913c673773 Revert "enable LLVM in iOS extensions (#1511)" (#1513)
This reverts commit 380c3583fb.
2021-08-25 17:02:49 -04:00
Joseph Flinn
339decafe4 Reverting changes to Chinese and Portuguese translations (#1512) 2021-08-24 11:57:34 -07:00
Matt Portune
380c3583fb enable LLVM in iOS extensions (#1511) 2021-08-23 11:40:16 -04:00
Matt Portune
244a6a7f41 enable LLVM in iOS builds (#1510) 2021-08-23 10:16:46 -04:00
Matt Portune
745b54bf2a bump MinimumOSVersion to 12.0 (#1508) 2021-08-20 09:54:39 -04:00
Joseph Flinn
4f86bb2043 Reverting English changes from the Auto Crowdin Sync (#1507) 2021-08-19 10:47:15 -07:00
github-actions[bot]
ada8a73849 Autosync Crowdin Translations (#1498)
* Autosync Crowdin translations

* Autosync Crowdin translations

Co-authored-by: github-actions <>
2021-08-18 15:14:15 -07:00
Matt Gibson
1e3204f91d Version bump to 2.12.0 (#1505) 2021-08-17 14:02:00 -05:00
Joseph Flinn
b5c6a57fa0 Crowdin sync workflow (#1499)
* Initial addition of the crowdin sync workflow for testing

* adding logic to handle the case where there are no Crowdin updates
2021-08-13 13:28:07 -07:00
Joseph Flinn
6ca5b66aa7 stubbing out the crowdin sync workflow (#1497) 2021-08-13 07:31:36 -07:00
Matt Gibson
24a0396d0f Fix iphone captcha throws (#1495) 2021-08-12 08:23:02 -05:00
Chad Scharf
7f7b673b0a Fix for EMM system configuration for mobile (#1434) 2021-08-11 10:36:36 -04:00
Matt Gibson
f79ff3fd63 Encode auth email for unicode email support (#1491) 2021-08-10 11:48:51 -05:00
Matt Gibson
2f2fa8a25b Feature/use hcaptcha if bot (#1476)
* Add captcha to login models and methods

* Add captcha web auth to login

* Extract captcha to abstract base class

* Add Captcha to register

* Null out captcha token after each successful challenge

* Cancel > close
2021-08-04 14:47:23 -05:00
Matt Gibson
9042b1009e Revert "Revert "Redefine cipher "share" to "move to organization""" (#1459)
* Revert "Revert "Redefine cipher "share" to "move to organization" (#1433)" (#1440)"

This reverts commit bd4a275558.

* Cancel > close
2021-08-04 14:46:28 -05:00
Vince Grassia
dbc0f490c5 Add Release workflow stub (#1482) 2021-07-27 13:25:12 -04:00
Matt Portune
6d8f627772 disable send test (#1481) 2021-07-27 10:51:47 -04:00
Jonathan Browne
b4c016c9d4 Change Close to Cancel in editing prompts. (#1480) 2021-07-27 09:25:42 -04:00
howyay
ae763ebca8 Add support for Mull browser (#1435) 2021-07-26 09:20:47 -04:00
Matt Portune
880483ac79 bump app version to 2.11.3 for testflight (#1477) 2021-07-23 16:33:15 -04:00
Georges Varouchas
f44e6ab75f bugfix in AuthService.LogInSsoAsync (#1474) (#1475)
add missing parameter in call to LogInHelperAsync
2021-07-23 14:36:49 -04:00
Matt Portune
10a718b0c7 bump version to 2.11.2 (#1473) 2021-07-23 11:33:53 -04:00
Thomas Rittson
9ec4050e4d Move remaining primary buttons in login flow (#1470)
* Fix show/hide logic on Continue button

* Fix bug in 2FA method selection modal

* Move Log In button in SSO flow

* Fix linting
2021-07-22 07:56:39 +10:00
Matt Portune
93e2c0df7c keep app version at 2.11.1 for now (#1471) 2021-07-21 14:03:38 -04:00
Matt Portune
8d07397a59 Revert "lib updates and app version bump (#1468)" (#1469)
This reverts commit 15d44b873b.
2021-07-20 16:21:41 -04:00
Matt Portune
15d44b873b lib updates and app version bump (#1468)
* lib updates and app version bump

* added explicit androidx core dependency
2021-07-20 12:57:01 -04:00
Sang
6a979d0ff5 2FA screen: move continue to a button (#1427)
* Move continue to a button

* Resolve pr comments

* Move use another two step method button

* Resolve code suggestions

* Resolve for iPhone

* Apply suggestions from code review

Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com>

Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com>
2021-07-20 14:50:45 +10:00
Matt Portune
a4db088eda bugfix for incorrect type and nullable for some org vars (#1465) 2021-07-16 13:57:15 -04:00
Matt Portune
96454b7cbf add toggle for removing links to pages containing subscription info (#1463) 2021-07-16 12:02:00 -04:00
Matt Portune
9c1df2179c bump version to 2.11.1 (#1462) 2021-07-14 14:46:18 -04:00
Matt Portune
52c9125404 bump version to 2.11.0 (#1461) 2021-07-13 12:52:14 -04:00
Matt Portune
172a857604 handle intent exceptions to prevent denial of service (#1458) 2021-07-12 12:31:39 -04:00
Matt Portune
d8e68a266c bugfixes for lock block when setting timeout to immediate (#1455) 2021-07-12 10:58:17 -04:00
Matt Portune
1f57ba6c50 workaround for off-screen draw bug in XF4.5+ part 2 (#1454) 2021-07-09 17:29:57 -04:00
Matt Portune
ff19578807 Fix for password unlock for autofill and share-to-send on Android (#1453) 2021-07-09 11:48:03 -04:00
Matt Portune
9298d57f22 fix for resuming autofill when back button was previously used to exit (#1451) 2021-07-06 11:10:17 -04:00
Martin Choutka
8cf5d5728e MaximumAccessCountInfo locale string update (#1441)
String MaximumAccessCountInfo doesn't have "Send" with a capital "s".
2021-07-02 12:20:40 -04:00
Matt Portune
bdf6d764ca update csv lib and skip link (#1449) 2021-07-02 11:21:36 -04:00
Matt Portune
05e8da4bcc Workaround for off-screen draw bug in XF4.5+ (#1447)
* workaround for off-screen draw bug in xf4.5+

* check cols even if orgId is present
2021-06-30 17:46:59 -04:00
Matt Portune
382e547f74 fix for export password handling (#1448) 2021-06-30 16:05:30 -04:00
Kyle Spearrin
4f9985d2b0 New Crowdin updates (#1444)
* New translations AppResources.resx (Romanian)

* New translations copy.resx (Bosnian)

* New translations copy.resx (Kannada)

* New translations copy.resx (Tamil)

* New translations copy.resx (Tamil)

* New translations copy.resx (Bosnian)

* New translations copy.resx (Kannada)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Vietnamese)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Serbian (Cyrillic))

* New translations AppResources.resx (Slovenian)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Bengali)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Afrikaans)

* New translations AppResources.resx (Belarusian)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Greek)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Tamil)

* New translations AppResources.resx (Thai)

* New translations AppResources.resx (Croatian)

* New translations AppResources.resx (Sinhala)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Latvian)

* New translations AppResources.resx (Hindi)

* New translations AppResources.resx (English, United Kingdom)

* New translations AppResources.resx (Malayalam)

* New translations AppResources.resx (Bosnian)

* New translations AppResources.resx (Kannada)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (English, India)

* New translations copy.resx (Bosnian)

* New translations copy.resx (German)

* New translations copy.resx (Danish)

* New translations copy.resx (Czech)

* New translations copy.resx (Catalan)

* New translations copy.resx (Bulgarian)

* New translations copy.resx (Belarusian)

* New translations copy.resx (Afrikaans)

* New translations copy.resx (Spanish)

* New translations copy.resx (French)

* New translations copy.resx (Romanian)

* New translations copy.resx (English, India)

* New translations copy.resx (Norwegian Bokmal)

* New translations copy.resx (Kannada)

* New translations copy.resx (Sinhala)

* New translations copy.resx (Malayalam)

* New translations copy.resx (Finnish)

* New translations copy.resx (Persian)

* New translations copy.resx (Ukrainian)

* New translations copy.resx (Chinese Simplified)

* New translations copy.resx (Chinese Traditional)

* New translations copy.resx (Vietnamese)

* New translations copy.resx (Portuguese, Brazilian)

* New translations copy.resx (Indonesian)

* New translations copy.resx (Tamil)

* New translations copy.resx (English, United Kingdom)

* New translations copy.resx (Bengali)

* New translations copy.resx (Thai)

* New translations copy.resx (Croatian)

* New translations copy.resx (Estonian)

* New translations copy.resx (Latvian)

* New translations copy.resx (Hindi)

* New translations copy.resx (Greek)

* New translations copy.resx (Hebrew)

* New translations copy.resx (Swedish)

* New translations copy.resx (Latvian)

* New translations copy.resx (Persian)

* New translations copy.resx (Tamil)

* New translations copy.resx (Bengali)

* New translations copy.resx (Thai)

* New translations copy.resx (Croatian)

* New translations copy.resx (Estonian)

* New translations copy.resx (Hindi)

* New translations copy.resx (Portuguese, Brazilian)

* New translations copy.resx (English, United Kingdom)

* New translations copy.resx (Malayalam)

* New translations copy.resx (Bosnian)

* New translations copy.resx (Sinhala)

* New translations copy.resx (Kannada)

* New translations copy.resx (Norwegian Bokmal)

* New translations copy.resx (Indonesian)

* New translations copy.resx (Vietnamese)

* New translations copy.resx (Hungarian)

* New translations copy.resx (Russian)

* New translations copy.resx (Italian)

* New translations copy.resx (Japanese)

* New translations copy.resx (Korean)

* New translations copy.resx (Dutch)

* New translations copy.resx (Polish)

* New translations copy.resx (Portuguese)

* New translations copy.resx (Slovak)

* New translations copy.resx (Chinese Traditional)

* New translations copy.resx (Slovenian)

* New translations copy.resx (Serbian (Cyrillic))

* New translations copy.resx (Swedish)

* New translations copy.resx (Turkish)

* New translations copy.resx (Ukrainian)

* New translations copy.resx (Chinese Simplified)

* New translations copy.resx (Turkish)

* New translations copy.resx (Serbian (Cyrillic))

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Italian)

* New translations copy.resx (Slovenian)

* New translations copy.resx (Italian)

* New translations copy.resx (Danish)

* New translations copy.resx (German)

* New translations copy.resx (Greek)

* New translations copy.resx (Finnish)

* New translations copy.resx (Hebrew)

* New translations copy.resx (Hungarian)

* New translations copy.resx (Japanese)

* New translations copy.resx (Catalan)

* New translations copy.resx (Korean)

* New translations copy.resx (Dutch)

* New translations copy.resx (Polish)

* New translations copy.resx (Portuguese)

* New translations copy.resx (Russian)

* New translations copy.resx (Slovak)

* New translations copy.resx (Czech)

* New translations copy.resx (Bulgarian)

* New translations copy.resx (Belarusian)

* New translations copy.resx (Romanian)

* New translations copy.resx (French)

* New translations copy.resx (Spanish)

* New translations copy.resx (Afrikaans)

* New translations copy.resx (English, India)
2021-06-29 15:41:27 -04:00
Matt Portune
ef97417cd7 disable send tests (#1443) 2021-06-29 15:29:10 -04:00
Chad Scharf
7bdf4d8b18 Fix encoding of & in resx XML (#1445) 2021-06-29 14:32:07 -04:00
Matt Portune
a6c95d06b5 fix for vault timeout locking issue on android (#1442) 2021-06-29 10:23:20 -04:00
Matt Gibson
bd4a275558 Revert "Redefine cipher "share" to "move to organization" (#1433)" (#1440)
This reverts commit 2003ac9d2c.
2021-06-24 14:33:19 -05:00
Oscar Hinton
a2b46ee7cb Add help link to password reprompt (#1439) 2021-06-24 17:26:47 +02:00
Matt Gibson
2003ac9d2c Redefine cipher "share" to "move to organization" (#1433) 2021-06-18 06:52:01 -05:00
Oscar Hinton
2a5667251e Add a 250ms sleep before prompting for password (#1431) 2021-06-15 20:29:11 +02:00
Thomas Rittson
79589b07fc Use 2 iterations for local password hashing (#1423)
* Add HashPurpose parameter to HashPasswordAsync

* Use 2 iterations for local password hashing

* Force logout if user has old keyHash stored

* Revert "Force logout if user has old keyHash stored"

This reverts commit 497d4928fa.

* Add backwards compatability with existing keyHash
2021-06-15 07:39:34 +10:00
Oscar Hinton
0aed13a2cf Fix selecting ciphers in search not working (#1426) 2021-06-11 15:20:42 +02:00
Oscar Hinton
df412e75d1 More Autofill fixes (#1425) 2021-06-11 15:20:21 +02:00
Oscar Hinton
2b8dbde923 Fixes for password reprompt (#1416) 2021-06-10 17:57:18 +02:00
Matt Portune
33791a03ac track failed unlock attempts in storage (#1421) 2021-06-09 10:03:05 -04:00
Matt Gibson
80a33e98a2 Use type to ensure transmitted data is encrypted (#1422) 2021-06-09 08:45:30 -05:00
Trey Greer
afed18908b Asset update (#1417)
* updated screenshots and copy for iOS + Android

* fixed data for copy file

* fixed data for copy file for Google

* fixed more file formatting items for resx

* added Google video
2021-06-01 10:16:52 -04:00
Thomas Rittson
fe58dea3e0 Add encKeyValidation string to encrypted exports (#1412) 2021-05-29 06:16:19 +10:00
Kyle Spearrin
569045fcd5 add auth-email header to auth request (#1414) 2021-05-28 14:06:42 -04:00
Matt Portune
fdda670311 replaced blank taskaffinity with singletask launchmode (#1410) 2021-05-26 14:18:01 -04:00
CookieJarApps
fbb7b05b9c Added support for SmartCookieWeb and SmartCookieWeb Preview (#1411) 2021-05-26 13:41:16 -04:00
Oscar Hinton
976eeab6d7 Password reprompt (#1365)
* Make card number hidden

* Add support for password reprompt

* Rename PasswordPrompt to Reprompt

* Protect autofill

* Use Enums.CipherRepromptType

* Fix iOS not building

* Protect iOS autofill

* Update to match jslib

* Fix failing build
2021-05-21 15:13:54 +02:00
Matt Portune
e61bcd2785 fix for activity exporting and workaround for task affinity (#1408) 2021-05-19 15:55:16 -04:00
Captain Trips
570edb4319 fixes bitwarden/mobile#967 (#1067) 2021-05-17 15:38:21 -04:00
Vince Grassia
8fe8c42765 Pin versions of actions in workflow (#1405) 2021-05-17 15:15:08 -04:00
Matt Gibson
0eebe6b156 Encode exports as UTF8 (#1404) 2021-05-17 11:40:20 -05:00
Matt Portune
946831b37e version bumps (#1399) 2021-05-13 15:21:24 -04:00
Matt Portune
1d4e742d66 Forms update with CollectionView conversion (#1374)
* Forms update with CollectionView conversion

* updates

* removed unnecessary import
2021-05-13 14:36:20 -04:00
Matt Portune
29979f6b04 expand package visibility for Android 11+ (#1384) 2021-05-13 14:16:53 -04:00
Matt Portune
2f6e1ff477 lib updates (#1381)
* lib updates

* included csv and biometric lib
2021-05-13 14:15:26 -04:00
Thomas Rittson
c1030c48fa Explain how to verify email for file Sends (#1395)
* Explain how to verify email for file Sends

* Revert "Explain how to verify email for file Sends"

This reverts commit b72314bc93.

* Explain how to verify email for file Sends
2021-05-11 17:52:18 -04:00
Kyle Spearrin
ef5d08cb75 New Crowdin updates (#1397)
* New translations AppResources.resx (Romanian)

* New translations copy.resx (Tamil)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Vietnamese)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Tamil)

* New translations copy.resx (Tamil)

* New translations AppResources.resx (Bengali)

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Thai)

* New translations AppResources.resx (Croatian)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Latvian)

* New translations AppResources.resx (Hindi)

* New translations AppResources.resx (English, United Kingdom)

* New translations AppResources.resx (Malayalam)

* New translations AppResources.resx (Sinhala)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Serbian (Cyrillic))

* New translations AppResources.resx (French)

* New translations AppResources.resx (Greek)

* New translations AppResources.resx (Spanish)

* New translations copy.resx (Spanish)

* New translations AppResources.resx (Afrikaans)

* New translations AppResources.resx (Belarusian)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (Slovenian)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (English, India)
2021-05-11 14:03:24 -04:00
Matt Portune
faa6904ce3 update firebase messaging lib and implementation (#1383)
* update firebase messaging lib and implementation

* update clean-fdroid script for updated firebase
2021-05-03 13:36:09 -04:00
Matt Portune
c27da8e7c4 fix for disappearing share sheet (#1386) 2021-04-27 17:49:01 -04:00
Matt Gibson
3ef5ca9cc0 Limit file upload sizes to 100MB (#1385)
both iOS and Android are having trouble with the current method
of loading the entire file to memory, encrypting it, and sending
to azure in one go.

We will need to come up with a chunking scheme to support
larger files in the future
2021-04-27 15:14:54 -05:00
Vincent Salucci
2fbd3b4538 [Version] Bump to 2.10.0 (#1382) 2021-04-22 12:00:01 -05:00
laymanZ
b3b21ea6b1 add microsoft package to support beta/dev/canary (#1370)
* add microsoft package to support beta/dev/canary

* Add package name in the necessary file
2021-04-22 00:16:19 -04:00
Matt Gibson
a3b4ede8f3 Use CipherByteArray to signify encrypted byte[] (#1366)
* Use CipherByteArray to signify encrypted  byte[]

* Rename CipherString and CipherByteArray to EncString and EncByteArray
2021-04-21 15:27:14 -05:00
Matt Portune
10ea6a86e3 clear cache on logout (#1375) 2021-04-19 15:38:49 -04:00
Thomas Rittson
3b2b37b3b0 Use UserService to manage emailVerified (#1367) 2021-04-15 14:54:58 +10:00
Matt Gibson
75e27ffbe3 Move renew endpoint to fix overlapping endpoint issue (#1362) 2021-04-12 09:45:17 -05:00
Thomas Rittson
a2cff6da28 Require user to verify email to use file Send (#1360) 2021-04-08 06:42:00 +10:00
Daniel James Smith
fe80fd0ba1 Replaced appveyor build badge with one from Github Workflow (#1350)
* Deleted appveyor.yml

* Remove Include of appveyor.yml from sln-file

* Deleted ci-build-apks.ps1 referenced by appveyor.yml

* Replaced build badge in README.md
2021-04-05 07:28:37 -07:00
dldhk97
5c6b9fa471 Add support for Soul browser (#1348) 2021-04-01 14:01:21 -04:00
Matt Portune
d926565358 Share-to-Send for Android (#1343)
* Android implementation

* remove iOS attempt for now
2021-03-31 10:19:05 -04:00
Matt Gibson
ce0b8bc62d Attachment azure upload blobs (#1345)
* Update Size limits

* Add new Api paths for direct upload of Cipher Attachments

* Add Attachment upload to fileUploadService

* Save with direct upload and fallback to legacy uplaod

CipherID is required for direct upload to request an upload URL

* Inform on when to remove legacy code

* Test Attachment upload
2021-03-30 18:42:43 -05:00
Thomas Rittson
04aeddc5de Hide email address in Sends (#1340)
* Add HideEmail model properties and locale strings

* Fix UI strings

* Add HideEmail to SendService

* Add HideEmail option to UI

* Tidy up declarations

* Add Bitwarden Send translation warning
2021-03-29 12:01:42 -04:00
Matt Gibson
13ffbe911a Send azure upload (#1334)
* Add direct upload api endpoints

* Create azure upload service

* Update max file size

* Update send file upload test

* Move internationalization string to correct document

* Allow for one shot blob uploads

* Remove unused helper

* Use FileUploadService

Fallback to legacy method on old server implementations.
2021-03-29 09:45:04 -05:00
Jamal
ab04759b0e Add support for Styx browser. (#1336)
https://github.com/jamal2362/Styx
2021-03-23 15:09:32 -04:00
Stéphane Lenclud
798cfef391 Add support for Fulguris browser. (#1333) 2021-03-22 16:54:55 -04:00
Matt Portune
3b5cdfe03c bump to 2.9.2 (#1321) 2021-03-16 15:56:28 -04:00
Contribucious
63449a3832 [KnownUsernameField] Entries update (Amazon) (#1320) 2021-03-16 14:57:45 -04:00
Matt Portune
23011aa8ae version bump to 2.9.1 (#1316) 2021-03-13 13:02:56 -05:00
Matt Portune
654d71cbbc use hardcoded kdfiterations for send passwords (#1315) 2021-03-13 12:40:41 -05:00
Matt Portune
d0e424abd9 fix for incorrect times during Send creation (#1313) 2021-03-11 20:52:35 -05:00
Kyle Spearrin
5cee71ce8a New Crowdin updates (#1312)
* New translations AppResources.resx (Romanian)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Latvian)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Serbian (Cyrillic))

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Czech)
2021-03-11 13:52:50 -05:00
Kyle Spearrin
c3be4f44a4 fix profile refs 2021-03-11 12:12:41 -05:00
Kyle Spearrin
ff3ac10bc3 new certs and profiles for 2021 2021-03-11 11:47:32 -05:00
Matt Portune
37bee011dc fix for establishing Send url in cloud vs on-prem (#1311) 2021-03-11 10:34:22 -05:00
Thomas Rittson
3c7029bdc8 Minor release version bump to 2.9.0 (#1308) 2021-03-10 09:33:16 +10:00
Matt Portune
29369b7bb2 added missing filesize on Send edit screen (#1307) 2021-03-09 14:44:22 -05:00
Kyle Spearrin
f2b9214836 New Crowdin updates (#1306)
* New translations AppResources.resx (French)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Slovenian)

* New translations AppResources.resx (Persian)
2021-03-09 13:19:05 -05:00
Kyle Spearrin
8b7b8a5e43 New Crowdin updates (#1305)
* New translations AppResources.resx (Romanian)

* New translations copy.resx (Bengali)

* New translations copy.resx (Turkish)

* New translations copy.resx (Turkish)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Chinese Simplified)

* New translations copy.resx (Chinese Simplified)

* New translations copy.resx (Chinese Simplified)

* New translations AppResources.resx (Chinese Traditional)

* New translations copy.resx (Chinese Traditional)

* New translations copy.resx (Chinese Traditional)

* New translations AppResources.resx (Vietnamese)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Bengali)

* New translations copy.resx (Bengali)

* New translations AppResources.resx (Hindi)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (Sinhala)

* New translations AppResources.resx (Malayalam)

* New translations copy.resx (English, United Kingdom)

* New translations copy.resx (English, United Kingdom)

* New translations AppResources.resx (English, United Kingdom)

* New translations copy.resx (Latvian)

* New translations AppResources.resx (Thai)

* New translations copy.resx (Latvian)

* New translations AppResources.resx (Latvian)

* New translations AppResources.resx (Estonian)

* New translations copy.resx (Croatian)

* New translations copy.resx (Croatian)

* New translations AppResources.resx (Croatian)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (French)

* New translations copy.resx (Czech)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (Greek)

* New translations copy.resx (German)

* New translations copy.resx (German)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Danish)

* New translations copy.resx (Czech)

* New translations copy.resx (Finnish)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Belarusian)

* New translations AppResources.resx (Afrikaans)

* New translations AppResources.resx (Spanish)

* New translations copy.resx (Finnish)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Serbian (Cyrillic))

* New translations AppResources.resx (Slovenian)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (English, India)
2021-03-09 11:49:02 -05:00
Matt Portune
142d056393 added about send option and resources (#1301) 2021-03-05 18:57:57 -05:00
Thomas Rittson
2b81bd2c8a Add extra encrypted export warning (#1299) 2021-03-05 09:33:29 +10:00
Matt Portune
53c82f23bf fix for users unable to edit existing personal vault items when org policy set (#1298) 2021-03-04 16:57:40 -05:00
Matt Portune
9b621bd1d0 fix for small gap at the top of send list when not disabled by policy (#1297) 2021-03-03 12:57:59 -05:00
Matt Portune
9165cb2b0e Removed fast deployment hack for Android 11 emulation (#1296) 2021-03-03 12:57:12 -05:00
Matt Gibson
2c13cef17c Send file model changes (#1293)
* Remove Url from SendFile.
Add file length hit to SendRequest

* Populate SendRequest file length
2021-03-02 10:09:26 -06:00
Addison Beck
1098686d51 clear Send password if whitespace (#1292)
* clear Send password if whitespace

* Update SendAddEditPageViewModel.cs
2021-03-01 12:07:04 -05:00
Matt Portune
6fa23475e3 fix for send list refresh on android (#1283) 2021-02-22 17:45:41 -05:00
stevenlele
685548ab72 [SupportedBrowsers] Update browsers (#1281)
* add Alook browser to autofillservice.xml

* add Alook browser to AutofillHelpers.cs

* add Alook browser to AccessibilityHelpers.cs, update Via's URL bar
2021-02-22 11:22:53 -05:00
Matt Portune
3799eb4603 Support for Disable Send policy (#1271)
* add support for disable send policy

* cleanup

* show/hide options support for send search results

* additional failsafes and copy function consolidation

* added missing disabled send icon to android renderer

* async fix and string updates
2021-02-18 16:58:20 -05:00
Matt Portune
20d5c6a63a use primary color for options label & chevron (#1269) 2021-02-17 14:32:45 -05:00
Matt Portune
ce11232cbe formatting (#1268) 2021-02-17 10:46:04 -05:00
Matt Portune
233319a0a3 options expander for send (#1265) 2021-02-16 15:24:51 -05:00
Matt Portune
7cf64ff088 fixed launch url on Android 11 (#1266) 2021-02-16 15:18:08 -05:00
Matt Portune
a8acd36b1e Send bugfixes & tweaks (#1262)
* bugfixes

* request name focus only if field is empty
2021-02-12 14:20:07 -05:00
Thomas Rittson
d88695f5d5 Fix autofill on Chrome from the iOS Share Extension (#1254)
* Process UTTypeURL data received from host app

* Disable autofill via Share extension for Chrome
2021-02-12 08:14:37 +10:00
Matt Portune
5e70d03dbe Added disabled icon and make File default type for new Sends if premium (#1261)
* Added disabled icon and make File default type for new Sends if premium

* forgot to expand colspan for extra icon
2021-02-11 16:27:22 -05:00
Matt Portune
2602a09443 UX tweaks for Send (#1260)
* additional help text

* replace send type picker with segmented control

* formatting

* added note about rider issue

* additional design tweaks
2021-02-11 14:38:30 -05:00
Matt Portune
a18e59a28a Send feature for mobile (#1256)
* Send feature for mobile

* added fallback for KdfIterations

* additional property exclusions for tests

* support encryptedFileData as byte array comparison in SendServiceTests

* formatting

* requested changes

* additional changes

* change position of send service registration to match declaration order
2021-02-10 19:50:10 -05:00
Thomas Rittson
52ba9f2ba7 Fix crash when using Yubikey via usb on Android (#1246)
* Fix crash when using yubikey via usb on Android

* Fix crash when using usb keyboard on Android
2021-02-03 05:56:44 +10:00
Matt Gibson
8d5614cd7b Port send jslib to mobile (#1219)
* Expand Hkdf crypto functions

* Add tests for hkdf crypto functions

Took the testing infrastructure from bitwarden/server

* Move Hkdf to cryptoFunctionService

* Port changes from bitwarden/jslib#192

* Port changes from bitwarden/jslib#205

* Make Send Expiration Optional implement changes from bitwarden/jslib#242

* Bug fixes found by testing

* Test helpers

* Test conversion between model types

* Test SendService

These are mostly happy-path tests to ensure a reasonably correct
implementation

* Add run tests step to GitHub Actions

* Test send decryption

* Test Request generation from Send

* Constructor dependencies on separate lines

* Remove unused testing infrastructure

* Rename to match class name

* Move fat arrows to previous lines

* Handle exceptions in App layer

* PR review cleanups

* Throw when attempting to save an unkown Send Type

I think it's best to only throw on unknown send types here.
I don't think we want to throw whenever we encounter one since that would
do bad things like lock up Sync if clients get out of date relative to
servers. Instead, keep the client from ruining saved data by complaining
last minute that it doesn't know what it's doing.
2021-01-25 14:27:38 -06:00
Thomas Rittson
9b6bf136f1 Add passphrase generator to iOS Extensions (#1230)
* Add passphrase generator options to iOS extension

* Set custom indentation on WordSeparator control

* Set correct RowsInSection for passphrase controls

* Fix RowsInSection for password controls

* Add avoid ambiguous characters control
2021-01-26 06:23:50 +10:00
Matt Portune
10677f3705 version bump to 2.8.2 (#1240) 2021-01-25 10:37:04 -05:00
Matt Portune
9d4d09810a revert "temporarily disable throwing on failure" (#1239) 2021-01-25 09:59:38 -05:00
Matt Portune
28a1bd5219 temporarily disable throwing on failure (#1236) 2021-01-22 16:10:45 -05:00
Matt Portune
1197c10592 bump google publisher dep (#1235) 2021-01-22 15:38:15 -05:00
Matt Portune
3bb92d452b bump to 2.8.1 (#1234) 2021-01-22 14:32:27 -05:00
Kyle Spearrin
2bfabfd838 Revert "fdroid.. just do it..."
This reverts commit 9876cd547f.
2021-01-22 14:23:07 -05:00
Kyle Spearrin
9876cd547f fdroid.. just do it... 2021-01-22 14:17:20 -05:00
Kyle Spearrin
4a8d261a82 New Crowdin updates (#1229)
* New translations AppResources.resx (Romanian)

* New translations AppResources.resx (Vietnamese)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Slovenian)

* New translations copy.resx (Slovenian)

* New translations copy.resx (Slovenian)

* New translations AppResources.resx (Serbian (Cyrillic))

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Thai)

* New translations AppResources.resx (Croatian)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Latvian)

* New translations AppResources.resx (Hindi)

* New translations AppResources.resx (English, United Kingdom)

* New translations AppResources.resx (Malayalam)

* New translations AppResources.resx (Sinhala)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Polish)

* New translations copy.resx (Romanian)

* New translations AppResources.resx (Greek)

* New translations copy.resx (Romanian)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Afrikaans)

* New translations AppResources.resx (Belarusian)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (Dutch)

* New translations copy.resx (Finnish)

* New translations copy.resx (Finnish)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (Hungarian)

* New translations copy.resx (Hungarian)

* New translations copy.resx (Hungarian)

* New translations AppResources.resx (Italian)

* New translations copy.resx (Italian)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (English, India)
2021-01-19 21:52:31 -05:00
Addison Beck
c4823f1c37 null checked all the permissions (#1227) 2021-01-19 17:45:12 -05:00
Chad Scharf
6e9238329c Version bump 2.8.0 (#1225) 2021-01-19 16:10:02 -05:00
Matt Portune
c86cb962b9 bump version to 2.7.3 (#1221) 2021-01-15 14:13:32 -05:00
Matt Portune
56935a7210 restore vault timeout timer for Android (#1220) 2021-01-15 14:04:07 -05:00
Addison Beck
cdc08e7e8a Implemented Custom role and permissions (#1189)
* Implemented Custom role and permissions

* changed permissions to permissions model

* added a semicolon
2021-01-13 14:31:27 -05:00
Matt Gibson
ca7794e6f2 Update revision date from server on restore (#1211) 2021-01-08 08:53:45 -06:00
Vincent Salucci
3b5cae01e0 initial commit of ownership banner (#1210) 2021-01-07 11:16:34 -06:00
Matt Gibson
edb8dc58f7 Use .json extension for encrypted json export (#1202) 2020-12-31 10:58:58 -06:00
Vincent Salucci
3fc69f16d5 Fix UI bug with cloning item while personal ownership is disabled (#1193) 2020-12-29 15:37:50 -06:00
Matt Gibson
bd3fdcab26 Do not export items that have been deleted (#1200) 2020-12-29 11:38:12 -06:00
Kyle Spearrin
201191e96d bump version 2020-12-21 14:36:44 -05:00
Kyle Spearrin
f545eafa77 New Crowdin updates (#1188)
* New translations AppResources.resx (Romanian)

* New translations AppResources.resx (Vietnamese)

* New translations copy.resx (Russian)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Serbian (Cyrillic))

* New translations copy.resx (Serbian (Cyrillic))

* New translations copy.resx (Serbian (Cyrillic))

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Ukrainian)

* New translations copy.resx (Ukrainian)

* New translations copy.resx (Ukrainian)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Russian)

* New translations copy.resx (Portuguese, Brazilian)

* New translations copy.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Thai)

* New translations AppResources.resx (Croatian)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Latvian)

* New translations AppResources.resx (Hindi)

* New translations AppResources.resx (English, United Kingdom)

* New translations AppResources.resx (Malayalam)

* New translations AppResources.resx (Sinhala)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations copy.resx (Russian)

* New translations AppResources.resx (Portuguese)

* New translations copy.resx (Romanian)

* New translations copy.resx (Danish)

* New translations copy.resx (Romanian)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Afrikaans)

* New translations AppResources.resx (Belarusian)

* New translations copy.resx (Belarusian)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Danish)

* New translations copy.resx (Danish)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Greek)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Dutch)

* New translations copy.resx (Dutch)

* New translations copy.resx (Dutch)

* New translations AppResources.resx (English, India)

* New translations AppResources.resx (Finnish)
2020-12-21 14:32:21 -05:00
Contribucious
5583c59e96 [SupportedBrowsers] Small update (#1187)
* [SupportedBrowsers] Small update

See PR for more info.

* Remove `org.ungoogled.chromium` from AutofillHelpers.CompatBrowsers too

Reason: deprecated.

* Remove `org.ungoogled.chromium` from autofillservice.xml too

Reason: deprecated.

* url -> URL
2020-12-21 13:15:29 -05:00
aaxdev
fbcf9c900c Fix auto biometric prompt on vault timeout (#1048)
* Fix auto biometric prompt on vault timeout

* Revert "Fix auto biometric prompt on vault timeout"

This reverts commit 67663d7be9.

* Let biometric prompt on vault timeout (android)
2020-12-21 12:15:32 -05:00
Matt Gibson
0801dea6e6 Attempt URI healing with https prior to http (#1186)
* Attempt URI healing with https prior to http

Browsers are moving away from displaying URI scheme in a way
accessibility can easily grab. This causes this URI healing to be relied
upon more frequently. It should attempt https prior to http due to
prevelence of https and security concerns with passwords over http.

* Just use https as the URI healing scheme
2020-12-21 09:58:26 -06:00
Matt Gibson
217514af66 Show vault export warning as popup (#1185) 2020-12-18 16:47:34 -06:00
Matt Gibson
e0191c573d Add encrypted hint json property (#1184) 2020-12-18 16:17:04 -06:00
Matt Portune
ef4b53b337 Workaround for lack of shared DB support (#1182)
* workaround for lack of shared DB support

* dispose db in finally
2020-12-16 16:37:26 -05:00
Matt Portune
acf2e4360f Use monotonic clock for vault timeout (#1175)
* Use monotonic clock for vault timeout

* free memory

* removed vault timeout timers and added crash logging to iOS clock hack
2020-12-14 15:29:30 -05:00
Matt Gibson
3227daddaf Enable Encrypted json export of vaults (#1174)
* Enable Encrypted json export of vaults

* Match jslib export of non-org ciphers

* Clean up export

* Update src/App/Pages/Settings/ExportVaultPage.xaml.cs

Co-authored-by: Kyle Spearrin <kspearrin@users.noreply.github.com>

Co-authored-by: Matt Gibson <mdgibson@Matts-MBP.lan>
Co-authored-by: Kyle Spearrin <kspearrin@users.noreply.github.com>
2020-12-14 11:56:13 -06:00
Vincent Salucci
6e40b7f25b [Policy] Personal Ownership (#1166)
* Initial commit of personal ownership policy

* Updated logic for returning from allowing cipher creation from notification

* fixed small edge case when user in one org // adjusted error message to match all platforms

* Removed test code
2020-12-14 08:46:54 -06:00
Lyndon Shi
0dd87bbf78 Change clipboard clear text to "<space>" instead of string.Empty. (#1172) 2020-12-10 12:27:46 -05:00
Matt Portune
dcfdc7d0ea make kdfIterations nullable (#1169) 2020-12-08 10:54:58 -05:00
Matt Portune
e79097603f bump version to 2.7.1 (#1163) 2020-12-01 16:19:20 -05:00
Matt Portune
ffd8f9951f Fix for missing biometric integrity check in iOS extensions under certain conditions (#1162)
* Fix for biometric check in extension on fresh install

* make sure bio integrity values are written to pref storage

* integrity state migration to pref storage

* remove automatic state saving upon null validation
2020-12-01 15:30:23 -05:00
Matt Gibson
e27370cf32 Include revision date in cipher requests (#1152)
Co-authored-by: Matt Gibson <mdgibson@Matts-MBP.lan>
2020-11-23 14:41:43 -06:00
Kyle Spearrin
405c4d1706 New Crowdin updates (#1155)
* New translations AppResources.resx (Romanian)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations copy.resx (Serbian (Cyrillic))

* New translations copy.resx (Serbian (Cyrillic))

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Vietnamese)

* New translations AppResources.resx (Indonesian)

* New translations copy.resx (Slovak)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Thai)

* New translations AppResources.resx (Croatian)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Latvian)

* New translations AppResources.resx (Hindi)

* New translations AppResources.resx (English, United Kingdom)

* New translations AppResources.resx (Malayalam)

* New translations AppResources.resx (Sinhala)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (Serbian (Cyrillic))

* New translations copy.resx (Slovak)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Finnish)

* New translations copy.resx (French)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Afrikaans)

* New translations AppResources.resx (Belarusian)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Greek)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (English, India)

* New translations copy.resx (French)

* New translations copy.resx (French)
2020-11-19 09:05:37 -05:00
Matt Portune
f7e081ba5d bump version to 2.7.0 (#1153) 2020-11-17 15:23:41 -05:00
Matt Portune
c71deb5051 Enhanced autofill settings (#1150)
* enhanced autofill settings

* cleanup
2020-11-17 09:37:57 -05:00
Vincent Salucci
edab722a76 Updated privacy policy links for theming (#1149) 2020-11-13 14:00:01 -06:00
Kyle Spearrin
2d280bd995 New Crowdin updates (#1148)
* New translations AppResources.resx (Romanian)

* New translations copy.resx (Ukrainian)

* New translations copy.resx (Portuguese, Brazilian)

* New translations copy.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations copy.resx (Vietnamese)

* New translations copy.resx (Vietnamese)

* New translations copy.resx (Chinese Traditional)

* New translations copy.resx (Chinese Traditional)

* New translations copy.resx (Chinese Simplified)

* New translations copy.resx (Chinese Simplified)

* New translations AppResources.resx (Chinese Simplified)

* New translations copy.resx (Ukrainian)

* New translations copy.resx (Indonesian)

* New translations AppResources.resx (Ukrainian)

* New translations copy.resx (Turkish)

* New translations copy.resx (Turkish)

* New translations copy.resx (Swedish)

* New translations copy.resx (Swedish)

* New translations copy.resx (Serbian (Cyrillic))

* New translations copy.resx (Serbian (Cyrillic))

* New translations AppResources.resx (Serbian (Cyrillic))

* New translations copy.resx (Slovak)

* New translations copy.resx (Slovak)

* New translations AppResources.resx (Indonesian)

* New translations copy.resx (Indonesian)

* New translations copy.resx (Russian)

* New translations copy.resx (English, United Kingdom)

* New translations copy.resx (English, India)

* New translations copy.resx (Norwegian Bokmal)

* New translations copy.resx (Norwegian Bokmal)

* New translations copy.resx (Sinhala)

* New translations copy.resx (Sinhala)

* New translations copy.resx (Malayalam)

* New translations copy.resx (Malayalam)

* New translations AppResources.resx (Malayalam)

* New translations copy.resx (English, United Kingdom)

* New translations AppResources.resx (English, United Kingdom)

* New translations copy.resx (Persian)

* New translations copy.resx (Hindi)

* New translations copy.resx (Hindi)

* New translations copy.resx (Latvian)

* New translations copy.resx (Latvian)

* New translations copy.resx (Estonian)

* New translations copy.resx (Estonian)

* New translations copy.resx (Croatian)

* New translations copy.resx (Croatian)

* New translations copy.resx (Thai)

* New translations copy.resx (Thai)

* New translations copy.resx (Persian)

* New translations AppResources.resx (Slovak)

* New translations copy.resx (Russian)

* New translations copy.resx (Romanian)

* New translations copy.resx (Bulgarian)

* New translations copy.resx (German)

* New translations AppResources.resx (German)

* New translations copy.resx (Danish)

* New translations copy.resx (Danish)

* New translations AppResources.resx (Danish)

* New translations copy.resx (Czech)

* New translations copy.resx (Czech)

* New translations copy.resx (Catalan)

* New translations copy.resx (Catalan)

* New translations AppResources.resx (Catalan)

* New translations copy.resx (Bulgarian)

* New translations AppResources.resx (Greek)

* New translations copy.resx (Belarusian)

* New translations copy.resx (Belarusian)

* New translations copy.resx (Afrikaans)

* New translations copy.resx (Afrikaans)

* New translations copy.resx (Spanish)

* New translations copy.resx (Spanish)

* New translations AppResources.resx (Spanish)

* New translations copy.resx (French)

* New translations copy.resx (French)

* New translations AppResources.resx (French)

* New translations copy.resx (Romanian)

* New translations copy.resx (German)

* New translations copy.resx (Greek)

* New translations AppResources.resx (Russian)

* New translations copy.resx (Korean)

* New translations copy.resx (Portuguese)

* New translations copy.resx (Portuguese)

* New translations AppResources.resx (Portuguese)

* New translations copy.resx (Polish)

* New translations copy.resx (Polish)

* New translations AppResources.resx (Polish)

* New translations copy.resx (Dutch)

* New translations copy.resx (Dutch)

* New translations AppResources.resx (Dutch)

* New translations copy.resx (Korean)

* New translations copy.resx (Japanese)

* New translations copy.resx (Greek)

* New translations copy.resx (Japanese)

* New translations copy.resx (Italian)

* New translations copy.resx (Italian)

* New translations copy.resx (Hungarian)

* New translations copy.resx (Hungarian)

* New translations AppResources.resx (Hungarian)

* New translations copy.resx (Hebrew)

* New translations copy.resx (Hebrew)

* New translations copy.resx (Finnish)

* New translations copy.resx (Finnish)

* New translations AppResources.resx (Finnish)

* New translations copy.resx (English, India)
2020-11-12 21:45:25 -05:00
Trey Greer
27e3c6553e updated english copy for the app stores (#1101) 2020-11-12 15:14:46 -05:00
eliykat
6258a9cff9 reposition buttons in Log In and Unlock pages (#1073)
* reposition buttons in Log In and Unlock pages

-   Log In page: move Log In button to primary location below password
    entry, move Get Your Master Password Hint to the More Options menu
-   Unlock page (Verify Master Password): swap position of Unlock
    and Log Out buttons

* finish changes to improved login ui

- move Log Out button in lock screen to secondary menu
- show Get Hint button on login screen in the iOS autofill login flow

Co-authored-by: Matt Portune <59324545+mportune-bw@users.noreply.github.com>
2020-11-12 11:23:34 -05:00
eliykat
a72f497581 expand contributing guide (#1147) 2020-11-12 09:39:24 -05:00
Matt Portune
311d3dd635 Android 11 inline autofill (#1145)
* Inline autofill support for Android 11 - initial commit

* null check intent before getting bool extra

* Updated xamarin androidx autofill

* fixed broken overlay fallback

* fixed filename

* auto-compat-check cleanup

* simplification
2020-11-10 17:24:24 -05:00
Kyle Spearrin
e80b3e4542 New Crowdin updates (#1146)
* New translations AppResources.resx (Romanian)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Serbian (Cyrillic))

* New translations copy.resx (Serbian (Cyrillic))

* New translations copy.resx (Serbian (Cyrillic))

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Vietnamese)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Thai)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Croatian)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Latvian)

* New translations AppResources.resx (Hindi)

* New translations AppResources.resx (English, United Kingdom)

* New translations AppResources.resx (Malayalam)

* New translations AppResources.resx (Sinhala)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (English, India)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Portuguese)

* New translations copy.resx (Romanian)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Afrikaans)

* New translations AppResources.resx (Belarusian)

* New translations copy.resx (Belarusian)

* New translations copy.resx (Belarusian)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Greek)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Dutch)

* New translations copy.resx (English, India)

* New translations copy.resx (English, India)
2020-11-10 17:20:44 -05:00
Vincent Salucci
82c96555dc [GDPR] Adjusted TOS/Privacy acceptance (#1138)
* GDPR acceptance flows

* Added specialized margin by platform

* Changed property name
2020-11-05 10:50:18 -06:00
Matt Portune
75b6e69d34 testing removal of setup-nuget (#1137) 2020-11-03 13:46:13 -05:00
Matt Portune
532b5f7c33 change msbuild reference to v1 (#1136) 2020-11-03 13:23:31 -05:00
Matt Portune
a841419c30 Use plain shield icon for accessibility overlay for quick identification (#1135) 2020-11-03 12:30:34 -05:00
Matt Portune
730a56380a Replacement of bitmap icons with vector versions (Android) (#1133) 2020-11-02 11:44:39 -05:00
stevenlele
97aa974443 Update support for several browsers and HTML viewer (#1121)
* Update accessibility support for Via browser

* Add Via browser (CN) & HTML viewer to AutofillHelpers

* Add Via browser (CN) & HTML viewer to autofillservice

* Add browsers to AccessibilityHelpers

* Add browsers to AutofillHelpers

* Add browsers to autofillservice
2020-10-21 09:10:31 -04:00
Matt Portune
b2eee8bde7 remove deprecated info.plist key (#1127) 2020-10-20 16:15:13 -04:00
Matt Portune
3cbe932248 Additional support for system theme setting (#1124)
* first pass with iOS 13+ support

* tweaks for ios pre-13

* Added Android support for dark/light splash & detection with default theme

* update cipher cell text color on system theme change (android)
2020-10-20 15:26:25 -04:00
Vincent Salucci
26d5504a2f Added New policy types (only org & require sso) (#1122) 2020-10-19 11:48:42 -05:00
Matt Portune
b163a0fe77 fix for stuck extension sheets when dismissed by swipe (#1117)
* fix for stuck extension sheets when dismissed by swipe

* simplify dismiss action assignments
2020-10-15 14:34:31 -04:00
Contribucious
523e713d7a [KnownUsernameField] Entries update (Top 20 JP enhancement) (#1051)
This adds support for alternative access for NTT DOCOMO (KnownUsernameField > Top 20 Japan).
2020-10-15 13:10:08 -04:00
Contribucious
c7cf634a94 Update support for Ungoogled Chromium browser (#1119) 2020-10-15 12:34:32 -04:00
Contribucious
c8c14396f1 Firefox (+ some forks): switch resource-id priority order (#1116) 2020-10-15 12:24:40 -04:00
Vincent Salucci
e72ccaf440 Initial commit for new user provision flow (#1091) 2020-10-13 15:01:14 -05:00
Matt Portune
0b7e07ebab clear cipher cache when replacing ios autofill identities (#1112)
* clear cipher cache when replacing ios autofill identities

* changed to be service-centric

* support for multiple cache keys

* async suffix

* added cache keys for android
2020-10-13 15:39:36 -04:00
Matt Portune
37e19d9a60 Support for storing multiple biometric integrity states for iOS (#1110)
* support for storing multiple biometric integrity states for iOS

* remove unused var & save new extension bio state upon password validation
2020-10-07 12:18:36 -04:00
yaakovfeldman
8f533bc576 Add support for Iceraven browser (#1106)
* Add support for Iceraven browser

* Remove legacy Firefox support from Iceraven
2020-10-05 09:15:01 -04:00
Matt Portune
096a9561ed workaround for xamarin.android issue with Android 11 emulator debugging (#1102) 2020-10-01 14:36:52 -04:00
Matt Portune
c6ac9376fc re-select support for android tabbed page buttons (#1100)
* re-select support for android tabbed page buttons

* applied Sane Person Technology (tm) to index check

* remove extra line
2020-10-01 14:16:37 -04:00
TheDuffman85
fd55cf6996 Update AddEditPage.xaml (#1097)
Removed Keyboard="Numeric" property from CardNumberEntry. European debit card numbers are alphanumeric. See also https://en.wikipedia.org/wiki/International_Bank_Account_Number.
2020-09-30 10:45:07 -04:00
Matt Portune
0359705361 fix issue with bio unlock button visibility (#1098) 2020-09-30 10:23:55 -04:00
Chad Scharf
e31a7e5236 Remap pt to pt-BR instead of pt-PT and handle valid mapping of pt to pt-BR initially (#1096)
* Rename pt-BR to pt, mapping for crowdin

* Map localized pt to pt-BR

* Revert "Rename pt-BR to pt, mapping for crowdin"

This reverts commit 42a09e14b7.
2020-09-29 10:58:50 -04:00
Kyle Spearrin
bb477908ef map en-IN 2020-09-28 14:22:09 -04:00
Matt Portune
26175fbe1b fix issue with search bar color on iOS (#1095) 2020-09-28 10:14:31 -04:00
Matt Portune
67bc59f6b6 bump version to 2.6.2 (#1094) 2020-09-26 07:41:02 -04:00
Matt Portune
7b358b1bbb biometric integrity check in iOS extensions (#1093) 2020-09-25 21:14:10 -04:00
Trey Greer
0387d5bdd1 Android + iOS screenshot updates (#971)
* added Android Screenshots

* added new iOS Screenshots

* fixed resolution for some screenshots

* fixed resolution for iPad pro #5

* modified iPhone 6+ images
2020-09-23 09:06:44 -04:00
Matt Portune
2ddf624f7d fix for sso login when bio unlock already enabled (#1086) 2020-09-23 09:02:20 -04:00
Indranil012
74b34661a5 To add autofill support for Idm browser (#1085)
* Update AutofillHelpers.cs

* Update autofillservice.xml

* Update AccessibilityHelpers.cs

* Update AccessibilityHelpers.cs
2020-09-22 09:17:47 -04:00
Matt Portune
dc9765ef58 version bumps to 2.6.1 (#1083) 2020-09-21 19:56:49 -04:00
Oscar Hinton
a50e66faf4 Handle if GetState is null in biometric integrity check (#1082) 2020-09-21 12:34:22 -04:00
Matt Portune
0388738e02 fix issue with biometric validation (#1081)
* fix issue with biometric validation

* null check key & cipher
2020-09-21 11:59:56 -04:00
Kyle Spearrin
d33e38012a update languages (#1080) 2020-09-21 10:20:45 -04:00
vachan-maker
785d0b21c6 Update MobileI18nService.cs (#1075) 2020-09-21 08:23:51 -04:00
Kyle Spearrin
db12cd92b7 check authed before checking if token has premium (#1074) 2020-09-18 15:07:32 -04:00
Kyle Spearrin
52261f99d7 New Crowdin updates (#1071)
* New translations AppResources.resx (Romanian)

* New translations AppResources.resx (Bulgarian)
2020-09-15 12:54:53 -04:00
Kyle Spearrin
692dc154ef New Crowdin updates (#1070)
* New translations AppResources.resx (Romanian)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations copy.resx (Chinese Simplified)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Dutch)

* New translations copy.resx (Korean)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (English, United Kingdom)

* New translations AppResources.resx (Malayalam)
2020-09-14 10:49:42 -04:00
Matt Portune
22101d8f4a fix for passphrase generator persistent settings (#1065) 2020-09-10 12:19:02 -04:00
Matt Portune
f68db90b1f fix state comparison (value vs instance) (#1063) 2020-09-09 11:51:28 -04:00
Kyle Spearrin
5e680531da New Crowdin updates (#1062)
* New translations AppResources.resx (Romanian)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Vietnamese)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Belarusian)

* New translations AppResources.resx (Afrikaans)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Greek)

* New translations copy.resx (Latvian)

* New translations copy.resx (Latvian)

* New translations AppResources.resx (Hindi)

* New translations copy.resx (Hindi)

* New translations AppResources.resx (English, United Kingdom)

* New translations AppResources.resx (Sinhala)

* New translations AppResources.resx (Malayalam)

* New translations copy.resx (Malayalam)

* New translations copy.resx (Malayalam)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (Latvian)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Thai)

* New translations AppResources.resx (Croatian)
2020-09-08 11:30:08 -04:00
Matt Portune
93cd31018e publish to google play internal test track (#1061)
publish directly to internal test track to skip play store approval process for internal testers (artifact can then be manually promoted to alpha > beta > prod like before).  This should bring the testing experience up to speed with TestFlight for iOS (i.e. push code > ci build > immediate availability)
2020-09-06 20:18:44 -04:00
Chad Scharf
277c570723 version bump (#1060) 2020-09-05 21:50:38 -04:00
Matt Portune
f1419a75f6 Added SSO flows and functionality (#1047)
* SSO login flow for pre-existing user and no 2FA

* 2FA progress

* 2FA support

* Added SSO flows and functionality

* Handle webauthenticator cancellation gracefully

* updates & bugfixes

* Added state validation to web auth response handling

* SSO auth, account registration, and environment settings support for iOS extensions

* Added SSO prevalidation to auth process

* prevalidation now hitting identity service base url

* additional error handling

* Requested changes

* fixed case
2020-09-03 12:30:40 -04:00
Contribucious
3af08a4727 [KnownUsernameField] Entries update (Yandex) (#1044)
This adds all missing entries for Yandex (exhaustive list of Yandex domain names obtained by contacting their support).
2020-08-20 09:56:11 -04:00
Contribucious
a535cea85f [KnownUsernameField] Fix for the special case "eBay India" (#1041)
See explanations in the PR.
2020-08-17 15:13:13 -04:00
Kyle Spearrin
29e443ed76 base64 url encode/decode heleprs (#1038) 2020-08-14 10:08:50 -04:00
Oscar Hinton
f95cddd05a Return the correct value for valid biometric (#1037) 2020-08-12 15:55:15 -04:00
Oscar Hinton
ae28de4159 Invalidate biometric on change (#1026)
* Initial working version for Android

* Add a fallback for when upgrading from older app version.

* Ensure biometric validity is re-checked on focus

* Only setup biometric integrity key if biometric is turned on.

* Fix styling according to comments

* Fallback for Android 5.

* Improve comment

* Add boilerplate for iOS

* Change BiometricService to public

* Untested iOS implementation.

* Convert IBiometricService to async. Fix code style for iOS.

* Base64 NSData.

* Review comments for Android BiometricService.

* Rename methods in BiometricService to append Async

* Ensure we wait for async SetupBiometricAsync.

* Update BiometricService.cs

Co-authored-by: Kyle Spearrin <kspearrin@users.noreply.github.com>
2020-08-08 21:33:49 -04:00
Contribucious
39de2c1d25 [KnownUsernameField] Entries update (main ones) (#1034)
* [KUF] Fix Google; Add natl/dskp Amazon/eBay & Atlassian+Bitly ENT.+Tumblr+Yandex

... also, add missing OAuth support for PayPal. And add "My docomo" from NTT DOCOMO, as part of a Top 20 Japan.

* Less spacing

* Even less spacing

* Additional reduction of spacing

* [Perf. optim.] Google: most frequently used entry in first position
2020-08-07 11:02:08 -04:00
Contribucious
22570e08aa [KnownUsernameField] Engine update (make the system more flexible) (#1011)
* [KnownUsernameField] Engine update (make the system more flexible)

* [KnownUsernameField] Engine update (make the system more flexible)

* Use of tuples array instead of multidimensional array (string[,])

* Use of tuples array instead of multidimensional array (string[,])

* [FIX] IndexOf -> Contains
2020-08-06 12:38:25 -04:00
aaxdev
3b4ef4d238 Feature sync on refresh (#937)
* Added new option: Sync on refresh

* Removed unused field

* Fixed refreshing on disappearing & unnecessary codes removed

* Requested changes

* Calling storage service instead of a dedicated service function (mobile-specific)
2020-08-05 13:19:27 -04:00
Chad Scharf
c5a71c4304 Fix Pin cannot be hidden after showing it #1025 (#1027) 2020-07-30 13:46:06 -04:00
K. Sasa
4f37c2cb73 Replace copy value button fa-clipboard(&#xf0ea;) to fa-clone(&#xf24d;) (#1024) 2020-07-27 13:22:27 -04:00
Chad Scharf
c1ec97055c Added android:installLocation=internalOnly (#1019) 2020-07-23 09:19:11 -04:00
Matt Smith
086c71126f Allow only non-deleted creds to be added to autofill (#1015) 2020-07-16 11:53:02 -05:00
Matt Smith
10a78c1c94 Modified listing of website from Hostname to Host (#1012)
* Modified listing of website from Hostname to Host

* Removed last _hostname artifact.
2020-07-14 13:17:08 -05:00
Gal Szkolnik
cf6021d898 Don't break when CipherType data is null (#1008)
as explained in issue https://github.com/bitwarden/mobile/issues/1006
2020-07-11 09:06:48 -04:00
Matt Smith
ff322cd2dd Modified Permissions Flow (#1005)
Permissions flow for Android was causing the white screen on initial permission grant on occasion. Moved permission grant to pre-TOTP page load.
2020-07-08 14:09:08 -05:00
Kyle Spearrin
1a96d3c38e bump version 2020-07-06 14:36:10 -04:00
Kyle Spearrin
cfe84963fa switch to access token, bump version 2020-07-06 13:54:44 -04:00
Kyle Spearrin
d908a599b1 bump version and build fixes 2020-07-06 13:28:19 -04:00
Kyle Spearrin
9b3ddb8da3 bump version via hub release command 2020-07-06 11:56:00 -04:00
Kyle Spearrin
56d994a69d bump version 2020-07-06 11:27:19 -04:00
Kyle Spearrin
67cd17c604 do actions on master push or release event 2020-07-06 11:26:51 -04:00
Kyle Spearrin
f4fb7eb8b7 New Crowdin updates (#1003)
* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Slovak)
2020-07-06 10:39:38 -04:00
Kyle Spearrin
b9021e4331 bump version 2020-07-06 10:36:23 -04:00
Kyle Spearrin
3583836d3e Upload release assets for ios too 2020-07-06 09:55:16 -04:00
Kyle Spearrin
278815119f update workflow for release tasks 2020-07-06 09:50:26 -04:00
Contribucious
1bb678e455 [KnownUsernameField] Compatibility with more browsers (#1000) 2020-07-01 10:31:12 -04:00
Kyle Spearrin
b9e5fc604b New Crowdin updates (#999)
* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Polish)

* New translations copy.resx (Polish)

* New translations copy.resx (Polish)
2020-06-29 11:30:02 -04:00
Kyle Spearrin
b65e8c48ce New Crowdin updates (#996)
* New translations AppResources.resx (Romanian)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Vietnamese)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Thai)

* New translations AppResources.resx (Hindi)

* New translations AppResources.resx (English, United Kingdom)

* New translations AppResources.resx (Sinhala)

* New translations copy.resx (Sinhala)

* New translations copy.resx (Sinhala)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Portuguese)

* New translations copy.resx (Romanian)

* New translations copy.resx (Romanian)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Afrikaans)

* New translations AppResources.resx (Belarusian)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Norwegian Bokmal)
2020-06-26 21:28:06 -04:00
Chad Scharf
e59bc1a08e version bump (#994)
* version bump

* version bump + fix manifest XML formatting
2020-06-25 17:30:14 -04:00
Kyle Spearrin
ff994629de Do not process hostname for regex logins (#987) 2020-06-18 11:58:19 -04:00
Matt Portune
a458b9bc88 Workaround for disabling predictive text in visible password fields (#983)
* Workaround for disabling predictive text in visible password fields

* Fix for non-master branch iOS builds (#984)

* Enable extra workflow steps to allow iOS builds to succeed from non-master branch

* re-enable provisioning profile setup
2020-06-16 11:09:26 -04:00
Matt Portune
2834e25151 Fix for non-master branch iOS builds (#984)
* Enable extra workflow steps to allow iOS builds to succeed from non-master branch

* re-enable provisioning profile setup
2020-06-16 09:55:08 -04:00
Oscar Hinton
c2582fe055 Resolve new ciphers defaulting to ViewPassword = false, causing passwords to be non editable. (#982) 2020-06-15 12:33:36 -04:00
Matt Portune
0980219c8d Add autofill/a11y support for ungoogled.chromium browser (#978) 2020-06-12 15:01:23 -04:00
Oscar Hinton
c5f158f1cf Resolve all passwords being hidden after upgrade (#977) 2020-06-12 09:50:36 -04:00
Kyle Spearrin
62afc023c8 print github ref 2020-06-11 16:26:10 -04:00
Oscar Hinton
52ca84946b Add support for hidden passwords (#920)
* Add support for hidden passwords

* Hide TOTP, hide hidden fields.

* Change _cipher to Cipher.
2020-06-11 16:16:43 -04:00
Kyle Spearrin
e64fb39c32 bump version 2020-06-10 13:49:58 -04:00
Kyle Spearrin
1066598150 fix ipa path 2020-06-10 13:30:08 -04:00
Kyle Spearrin
caed8c2cf0 explore paths 2020-06-10 13:13:03 -04:00
Kyle Spearrin
663be2402d list file system 2020-06-10 12:43:52 -04:00
Kyle Spearrin
6fd24c842f get proper ipa for app store 2020-06-10 12:24:52 -04:00
Kyle Spearrin
302631c4fa set CFBundlePackageType 2020-06-10 11:54:21 -04:00
Kyle Spearrin
8a94623b2b type ios 2020-06-10 11:48:02 -04:00
Kyle Spearrin
016dfdb455 dont archive for app store if not master 2020-06-10 11:33:43 -04:00
Kyle Spearrin
097415385e deploy to app store 2020-06-10 11:32:16 -04:00
Kyle Spearrin
8e6c6e04a3 cleanup export, ipa artifact 2020-06-10 10:53:57 -04:00
Kyle Spearrin
81a30e580e export ipa for app store 2020-06-10 10:02:15 -04:00
Kyle Spearrin
676efe7253 ls archive folder 2020-06-10 09:24:27 -04:00
Kyle Spearrin
39e0e77824 archive on build 2020-06-10 09:03:12 -04:00
Kyle Spearrin
363f5be8ff increment version for ios 2020-06-09 21:23:10 -04:00
Kyle Spearrin
df15fa2f0e move stuff to setup keychain script 2020-06-09 20:47:46 -04:00
Kyle Spearrin
e8c1fbb86f allow codesign to access certs and key 2020-06-09 20:36:44 -04:00
Kyle Spearrin
df986b9ecf timeout settings are for build.keychain 2020-06-09 20:32:23 -04:00
Kyle Spearrin
daabf4bab9 build again 2020-06-09 20:16:03 -04:00
Kyle Spearrin
3095948024 set keychain timeout 2020-06-09 20:14:40 -04:00
Kyle Spearrin
fad289305f add codesign to set-key-partition-list 2020-06-09 17:43:40 -04:00
Kyle Spearrin
97d8f07e0d Merge branch 'master' of github.com:bitwarden/mobile 2020-06-09 17:33:03 -04:00
Kyle Spearrin
dc374c7ce9 try unlocking keychain 2020-06-09 17:32:53 -04:00
Matt Portune
1584475bc3 added hi-res icon for google play (#966)
* added hi-res icon for google play

* moved to proper location
2020-06-09 17:24:19 -04:00
Kyle Spearrin
8f1db25c5c move cloc to its own job 2020-06-09 13:18:22 -04:00
Kyle Spearrin
092b536009 remove debug 2020-06-09 13:14:11 -04:00
Kyle Spearrin
f95bbaa0f7 resolve path of ~ 2020-06-09 13:09:00 -04:00
Kyle Spearrin
bc1f6464d3 change home path to ~ 2020-06-09 13:00:43 -04:00
Kyle Spearrin
b828cd5975 write out homePath 2020-06-09 12:56:53 -04:00
Kyle Spearrin
766b4f7971 create profiles dir path if it doesnt exist 2020-06-09 12:35:39 -04:00
Kyle Spearrin
45e2ffd71e properly escape space 2020-06-09 12:31:18 -04:00
Kyle Spearrin
98757c3f11 use proper params for copy-item 2020-06-09 12:27:40 -04:00
Kyle Spearrin
9aed6d350b setup provisioning profiles 2020-06-09 12:25:09 -04:00
Kyle Spearrin
ca6ce6db32 add mobile profiles 2020-06-09 12:15:06 -04:00
Kyle Spearrin
1c9a6a02af change all seps to / so that it works x-platform 2020-06-09 11:52:23 -04:00
Kyle Spearrin
ba9bafcb5f fix sep character 2020-06-09 11:48:11 -04:00
Kyle Spearrin
0628394122 update path sep character 2020-06-09 11:46:16 -04:00
Kyle Spearrin
99b2cd2ad0 fix pathing 2020-06-09 11:41:03 -04:00
Kyle Spearrin
707a6ecbaa setup ios keychain 2020-06-09 11:37:40 -04:00
Kyle Spearrin
aa2bc40f03 decrypt ios secrets 2020-06-09 11:19:02 -04:00
Kyle Spearrin
5e00e76c4b ios secrets 2020-06-09 11:16:13 -04:00
Kyle Spearrin
0dba992dd4 fix build for app store script path 2020-06-09 10:51:35 -04:00
Kyle Spearrin
b6f61cac9b build play store publisher 2020-06-09 10:47:20 -04:00
Kyle Spearrin
0e41945a8a build ios 2020-06-09 10:47:09 -04:00
Kyle Spearrin
a05e037308 deploy to play store 2020-06-09 10:21:46 -04:00
Kyle Spearrin
f40576c39d print lines of code from CLOC 2020-06-09 10:17:26 -04:00
Kyle Spearrin
9fc810182a print dotnet info 2020-06-09 09:58:28 -04:00
Kyle Spearrin
dd7a52ba08 print version code 2020-06-08 16:10:17 -04:00
Kyle Spearrin
fa6d2a3080 break steps out a bit more 2020-06-08 16:04:04 -04:00
Laurent Tréguier
36efc0c877 Tweak icons to better blend with Android and iOS (#962)
* Add shadow to Android icon

* Add gradient to iOS icon
2020-06-08 15:02:20 -04:00
Kyle Spearrin
e9efcf1b92 rework build scripts 2020-06-08 13:19:44 -04:00
Kyle Spearrin
f4ad1ec8e7 fix secretOutputPath 2020-06-08 13:02:38 -04:00
Kyle Spearrin
0027c21630 more pathing fixes 2020-06-08 13:00:52 -04:00
Kyle Spearrin
6173cab99f fix decryptSecretPath 2020-06-08 12:56:58 -04:00
Kyle Spearrin
80c8097a71 fix paths to ps scripts 2020-06-08 12:55:02 -04:00
Kyle Spearrin
ba3d577125 try shell: pwsh 2020-06-08 12:29:57 -04:00
Kyle Spearrin
8ce4ebb16e powershell Invoke-Expression 2020-06-08 12:25:39 -04:00
Kyle Spearrin
4358ff2338 run powershell commands 2020-06-08 12:21:43 -04:00
Kyle Spearrin
53f9eb083d branches ignore and only on master 2020-06-08 12:17:53 -04:00
Kyle Spearrin
0a3a982cb9 github action android build steps 2020-06-08 12:14:22 -04:00
Kyle Spearrin
c30239b3a8 encrypted GPG files for github actions 2020-06-08 12:14:22 -04:00
Matt Portune
183834689d Fix for accessibility overlay on Android 5 & 6 (#965)
* Fix for accessibility overlay on Android 5 & 6

* changed to skip check outright until API 26
2020-06-08 08:25:24 -04:00
Matt Portune
5da2f3279b biometrics cleanup (#964) 2020-06-08 08:25:13 -04:00
Kyle Spearrin
ec7d87e757 bump version 2020-06-07 11:56:16 -04:00
Kyle Spearrin
4155f69e3c formatting fixes 2020-06-07 11:54:14 -04:00
Matt Portune
473e93ea16 Fix for deadlock in iOS autofill & share extensions (#960) 2020-06-07 00:15:51 -04:00
Kyle Spearrin
fd1941cc3e target iPhone 2020-06-05 15:31:30 -04:00
Kyle Spearrin
dbb51b58db update platforms for ios core builds 2020-06-05 15:30:24 -04:00
Kyle Spearrin
e7d00cfe54 set iphone and sim platforms for ios core 2020-06-05 15:23:15 -04:00
Kyle Spearrin
63453fa962 fix syntax 2020-06-05 14:40:44 -04:00
Kyle Spearrin
689eb7f87b CI updates 2020-06-05 14:39:29 -04:00
Kyle Spearrin
67a4646a50 try out github actions 2020-06-05 13:51:57 -04:00
Kyle Spearrin
a4e0535464 null check all the things (#957) 2020-06-05 13:30:53 -04:00
Kyle Spearrin
61495cd428 bumping ios version to match what was released 2020-06-04 09:48:10 -04:00
Carl
9e7b7415a5 Add support for Bromite's vanilla build of Chromium (#951) 2020-06-02 23:18:30 -04:00
Kyle Spearrin
06a462d48c skip litedb from ios linker 2020-06-02 14:06:53 -04:00
Kyle Spearrin
d3e6e415b9 bump version 2020-06-02 13:08:04 -04:00
Kyle Spearrin
7e633d31a0 sign fdroid builds with a different keystore (#949) 2020-06-02 10:36:16 -04:00
Kyle Spearrin
0fcf006484 Send vaultTimeoutActionChanged event after save (#948) 2020-06-02 09:50:08 -04:00
Kyle Spearrin
48e5b1686f bump version 2020-06-02 09:21:58 -04:00
Kyle Spearrin
608d879c80 New Crowdin translations (#947)
* New translations AppResources.resx (French)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Greek)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Hindi)
2020-06-02 09:20:55 -04:00
Kyle Spearrin
66055f1d7c Singleton LiteDatabase (#946)
* update litedb. initialize db as a static singleton instance.

* dont need to dispose anymore
2020-06-02 09:13:57 -04:00
Kyle Spearrin
1120bff34d Don't build the keyboard index for autofill if using logout action (#943)
* Don't build the keyboard index for autofill if using logout action

* trigger index rebuild on vault timeout changed event
2020-06-01 14:46:53 -04:00
Kyle Spearrin
24547e67bf check for empty string on malformed URL (#944)
* treat empty string host as null

* use `string.IsNullOrEmpty`
2020-06-01 14:46:37 -04:00
Kyle Spearrin
f8c7285f56 update ios language metadata. 2020-06-01 09:45:15 -04:00
Kyle Spearrin
82eb6a4568 New Crowdin translations (#942)
* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Dutch)
2020-06-01 09:32:26 -04:00
Kyle Spearrin
a3f1f7c78d New Crowdin translations (#941)
* New translations AppResources.resx (Romanian)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Vietnamese)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Thai)

* New translations AppResources.resx (Croatian)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Hindi)

* New translations copy.resx (Hindi)

* New translations AppResources.resx (English, United Kingdom)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (French)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Afrikaans)

* New translations AppResources.resx (Belarusian)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Greek)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Norwegian Bokmal)
2020-06-01 08:53:20 -04:00
Kyle Spearrin
c377c4a52b bump version 2020-05-30 10:49:51 -04:00
Kyle Spearrin
e5a74cf43c downgrade litedb 2020-05-29 15:26:00 -04:00
Kyle Spearrin
ccf2bf84da allow ios projects to deploy 2020-05-29 15:25:18 -04:00
Kyle Spearrin
fbf3d97d57 check app options ios extension on nfc check (#933) 2020-05-29 15:25:06 -04:00
Chad Scharf
6da0f82ddd Avoid Task.Result usage (#930) 2020-05-29 12:38:26 -04:00
Vincent Salucci
4c3df2e1e1 [Auto Logout] Final review of feature (#932)
* Initial commit of LockService name refactor (#831)

* [Auto-Logout] Update Service layer logic (#835)

* Initial commit of service logic update

* Added default value for action

* Updated ToggleTokensAsync conditional

* Removed unused variables, updated action conditional

* Initial commit: lockOption/lock refactor app layer (#840)

* [Auto-Logout] Settings Refactor - Application Layer Part 2 (#844)

* Initial commit of app layer part 2

* Updated biometrics position

* Reverted resource name refactor

* LockOptions refactor revert

* Updated method casing :: Removed VaultTimeout prefix for timeouts

* Fixed dupe string resource (#854)

* Updated dependency to use VaultTimeoutService (#896)

* [Auto Logout] Xamarin Forms in AutoFill flow (iOS) (#902)

* fix typo in PINRequireMasterPasswordRestart (#900)

* initial commit for xf usage in autofill

* Fixed databinding for hint button

* Updated Two Factor page launch - removed unused imports

* First pass at broadcast/messenger implentation for autofill

* setting theme in extension using theme manager

* extension app resources

* App resources from main app

* fix ref to twoFactorPage

* apply resources to page

* load empty app for sytling in extension

* move ios renderers to ios core

* static ref to resources and GetResourceColor helper

* fix method ref

* move application.current.resources refs to helper

* switch login page alerts to device action dialogs

* run on main thread

* showDialog with device action service

* abstract action sheet to device action service

* add support for yubikey

* add yubikey iimages to extension

* support close button action

* add support to action extension

* remove empty lines

Co-authored-by: Jonas Kittner <54631600+theendlessriver13@users.noreply.github.com>
Co-authored-by: Kyle Spearrin <kyle.spearrin@gmail.com>

* [Auto Logout] Update lock option to be default value (#929)

* Initial commit - make lock action default

* Removed extra whitespace

Co-authored-by: Jonas Kittner <54631600+theendlessriver13@users.noreply.github.com>
Co-authored-by: Kyle Spearrin <kyle.spearrin@gmail.com>
Co-authored-by: Kyle Spearrin <kspearrin@users.noreply.github.com>
2020-05-29 12:26:36 -04:00
Kyle Spearrin
39e10ff01c New Crowdin translations (#931)
* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Chinese Simplified)
2020-05-29 12:14:35 -04:00
Kyle Spearrin
0b29c6e5a4 Dispost of LiteDatabase instance (#928) 2020-05-28 15:44:27 -04:00
Contribucious
cd3585be58 Early support for future versions of Firefox (+ some forks) (#923)
* Early support for future versions of Firefox

Note: Ideally, a swapping of the two entries of this resource-id value will be done when the time comes; `url_bar_title` becoming Legacy.

* Early support for future versions of some Firefox forks

Note: Ideally, a swapping of the two entries of these resource-id values will be done when the time comes; `url_bar_title` becoming Legacy.
2020-05-26 10:41:27 -04:00
Kyle Spearrin
4e1f91f4d5 New Crowdin translations (#925)
* New translations AppResources.resx (French)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (English, United Kingdom)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Belarusian)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Catalan)

* New translations copy.resx (Belarusian)

* New translations copy.resx (Belarusian)

* New translations AppResources.resx (Norwegian Bokmal)
2020-05-26 10:35:44 -04:00
Kyle Spearrin
272c2e5303 New Crowdin translations (#921)
* New translations AppResources.resx (Romanian)

* New translations AppResources.resx (Vietnamese)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Thai)

* New translations AppResources.resx (Croatian)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Hindi)

* New translations AppResources.resx (English, United Kingdom)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Afrikaans)

* New translations AppResources.resx (Belarusian)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Greek)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Norwegian Bokmal)
2020-05-23 09:42:00 -04:00
Contribucious
2a82b09f7b Fix support for Firefox Beta (#918) 2020-05-23 09:38:24 -04:00
Contribucious
fd26492577 Partial revert of "Fix support for Firefox Nightly for Developers" (#919)
My mistake: `org.mozilla.fennec_fdroid` is not an "F-Droid version of Firefox Nightly for Developers". This corrects my error.
2020-05-23 09:38:01 -04:00
Contribucious
528b90b694 Fix support for Firefox Nightly for Developers (#917) 2020-05-23 00:20:51 -04:00
Contribucious
9c7961ff6b Adblock Browser: clarification (#916) 2020-05-22 23:00:27 -04:00
Contribucious
954ed6457c Add support for Privacy Browser (Free/Standard). Closes #407 (#915)
* Add Privacy Browser (Free/Standard) to SupportedBrowsers dict

* Add Privacy Browser (Free/Standard) to CompatBrowsers

* Add Privacy Browser (Free/Standard) compatibility-package entries
2020-05-22 21:06:11 -04:00
Matt Portune
5a8fc2dabc Workaround for pasting into editor within scrollview (#913) 2020-05-20 17:23:59 -04:00
Chad Scharf
ce965ba5e1 Soft delete feature (#890)
* [Soft Delete] Added trash folder to mobile (#856)

* [Soft Delete] Added trash folder to mobile

* [Soft Delete] - Revert send to trash label

Co-authored-by: Chad Scharf <cscharf@users.noreply.github.com>

* [Soft Delete] - Fix for iOS autofill index behavior (#859)

* [Soft Delete] Added trash folder to mobile

* [Soft Delete] - Revert send to trash label

* [Soft Delete] - iOS autofill index behavior fix

Co-authored-by: Chad Scharf <cscharf@users.noreply.github.com>

Co-authored-by: Chad Scharf <cscharf@users.noreply.github.com>
2020-05-20 13:35:20 -04:00
Matt Portune
4b9a036e5e Removal of lifecycle hack for 2FA resume flow (#912) 2020-05-20 09:57:48 -04:00
Matt Portune
4576f378cc lock screen drawing & 2FA entry bugfixes (#910)
* lock screen drawing & 2FA entry bugfixes

* cleanup whitespace
2020-05-20 09:09:28 -04:00
Kyle Spearrin
4c65daa995 New Crowdin translations (#908)
* New translations AppResources.resx (Romanian)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Hebrew)

* New translations copy.resx (Hebrew)

* New translations AppResources.resx (Hungarian)

* New translations copy.resx (Hungarian)

* New translations copy.resx (Hungarian)

* New translations AppResources.resx (Italian)

* New translations copy.resx (Italian)

* New translations copy.resx (Italian)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Finnish)

* New translations copy.resx (Korean)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Polish)

* New translations copy.resx (Polish)

* New translations copy.resx (Polish)

* New translations AppResources.resx (Portuguese)

* New translations copy.resx (Portuguese)

* New translations copy.resx (Romanian)

* New translations AppResources.resx (Russian)

* New translations copy.resx (Finnish)

* New translations copy.resx (Portuguese)

* New translations AppResources.resx (Greek)

* New translations AppResources.resx (Bulgarian)

* New translations copy.resx (German)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Spanish)

* New translations copy.resx (Spanish)

* New translations copy.resx (Spanish)

* New translations AppResources.resx (Afrikaans)

* New translations copy.resx (Afrikaans)

* New translations copy.resx (Afrikaans)

* New translations AppResources.resx (Belarusian)

* New translations copy.resx (Romanian)

* New translations copy.resx (Bulgarian)

* New translations AppResources.resx (Catalan)

* New translations copy.resx (Catalan)

* New translations copy.resx (Catalan)

* New translations AppResources.resx (Czech)

* New translations copy.resx (Czech)

* New translations AppResources.resx (Danish)

* New translations copy.resx (Danish)

* New translations AppResources.resx (German)

* New translations copy.resx (Bulgarian)

* New translations copy.resx (Persian)

* New translations AppResources.resx (Thai)

* New translations copy.resx (Portuguese, Brazilian)

* New translations copy.resx (Persian)

* New translations AppResources.resx (Persian)

* New translations copy.resx (Indonesian)

* New translations AppResources.resx (Indonesian)

* New translations copy.resx (Thai)

* New translations copy.resx (Estonian)

* New translations copy.resx (Thai)

* New translations AppResources.resx (Croatian)

* New translations copy.resx (Croatian)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Hindi)

* New translations copy.resx (Hindi)

* New translations AppResources.resx (English, United Kingdom)

* New translations copy.resx (English, United Kingdom)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations copy.resx (Portuguese, Brazilian)

* New translations copy.resx (Ukrainian)

* New translations copy.resx (Vietnamese)

* New translations copy.resx (Turkish)

* New translations AppResources.resx (Slovak)

* New translations copy.resx (Slovak)

* New translations copy.resx (Slovak)

* New translations AppResources.resx (Swedish)

* New translations copy.resx (Swedish)

* New translations copy.resx (Swedish)

* New translations AppResources.resx (Turkish)

* New translations copy.resx (Turkish)

* New translations AppResources.resx (Ukrainian)

* New translations copy.resx (Vietnamese)

* New translations copy.resx (Ukrainian)

* New translations AppResources.resx (Chinese Simplified)

* New translations copy.resx (Chinese Simplified)

* New translations copy.resx (Chinese Simplified)

* New translations AppResources.resx (Chinese Traditional)

* New translations copy.resx (Chinese Traditional)

* New translations copy.resx (Chinese Traditional)

* New translations AppResources.resx (Vietnamese)

* New translations copy.resx (Norwegian Bokmal)
2020-05-18 15:57:30 -04:00
Jonas Kittner
9159e14dd9 fix typo in PINRequireMasterPasswordRestart (#900) 2020-05-13 13:30:07 -04:00
Matt Portune
da661c229c Lib updates (#889)
* lib updates

* updated libs
2020-05-07 17:03:13 -04:00
Matt Portune
973f09f98a Usability improvements to accessibility settings (#888) 2020-05-07 16:32:42 -04:00
Matt Portune
fef370ad88 Fixed issue with autofill icon image (#887) 2020-05-07 13:54:06 -04:00
Matt Portune
bc46b7172d Updated iOS app icon (#886) 2020-05-07 13:20:07 -04:00
Matt Portune
71f546b467 Updated resources (#884) 2020-05-07 09:03:38 -04:00
Contribucious
a66f66c8ac Add support for AVG Browser (#883)
* Add AVG Browser to SupportedBrowsers dict

* Add AVG Browser to CompatBrowsers

* Add AVG Browser compatibility-package entry
2020-05-06 17:32:53 -04:00
Chad Scharf
c2c6ca22db Fixed spacing on known username field list (#882) 2020-05-06 12:11:58 -04:00
Matt Portune
b29440556a Support for establishing a username field without a password field (#880)
* Support for establishing a username field without a password field

* added aws login
2020-05-06 09:48:34 -04:00
Kyle Spearrin
4104f6f772 Color updates for new branding (#879) 2020-05-05 19:13:18 -04:00
Contribucious
01c56dabdf Add support for LG "Dual Window" mode (Android < 7.0 users) (#878) 2020-05-05 17:38:05 -04:00
Contribucious
fafd8f8ee6 [Browser lists] Global clarification (#876)
* AccessibilityHelpers.cs: global clarification

* AutofillHelpers.cs: global clarification

* autofillservice.xml: global clarification
2020-05-05 10:52:54 -04:00
Contribucious
e2033eee23 Add support for Samsung "Multi Window" mode (Android < 7.0 users) (#877)
... including "Pen Window" support, too.
2020-05-05 10:49:55 -04:00
Contribucious
780761664d Add support for Tor Browser (Alpha) (#872)
* Add Tor Browser (Alpha) to SupportedBrowsers dict

* Add Tor Browser (Alpha) to CompatBrowsers

* Add Tor Browser (Alpha) compatibility-package entry
2020-05-04 09:28:28 -04:00
Contribucious
0cfa737eff Add support for GNU IceCat (#873)
* Add GNU IceCat to SupportedBrowsers dict

* Add GNU IceCat to CompatBrowsers

* Add GNU IceCat compatibility-package entry
2020-05-04 09:27:47 -04:00
Contribucious
6463898c5d Add support for Avast Secure Browser (#874)
* Add Avast Secure Browser to SupportedBrowsers dict

* Add Avast Secure Browser to CompatBrowsers

* Add Avast Secure Browser compatibility-package entry
2020-05-04 09:26:44 -04:00
Contribucious
7d4fffa8b6 Adblock Browser: support for v2+ (stable/beta) + Autofill Framework (#868)
* Adblock Browser (AccessibilityHelpers.SupportedBrowsers): add support for v2+ (stable/beta)

Support for older versions (based on Firefox for Android, instead of Chromium) in the list remains.

* Adblock Browser (AutofillHelpers.CompatBrowsers): add it to the list

* Adblock Browser (autofillservice.xml): add it to the list
2020-05-04 09:25:53 -04:00
Contribucious
bcc415ccb3 Add support for Brave Nightly (also: variants "_dev" and "_default") (#869)
* [Brave] Add all other variants to AccessibilityHelpers.SupportedBrowsers

* [Brave] Add all other variants to AutofillHelpers.CompatBrowsers

* [Brave] Add all other variants to autofillservice.xml
2020-05-04 09:23:09 -04:00
Contribucious
827fead347 AccessibilityHelpers.SupportedBrowsers: add Tor Browser, Firefox Lite and Opera Mini Beta (#866) 2020-05-01 14:00:01 -04:00
Matt Portune
36cdc7dd1c Additional URI parsing fix (#865)
* Additional URI parsing fix

* name cleanup
2020-04-30 16:47:29 -04:00
Contribucious
99dceda8ac [Autofill - Browser lists] Sort the entries alphabetically (#864)
* AccessibilityHelpers.SupportedBrowsers: sort the entries alphabetically

* AutofillHelpers.TrustedBrowsers: sort the entries alphabetically

* AutofillHelpers.CompatBrowsers: sort the entries alphabetically

* autofillservice.xml: sort the entries alphabetically
2020-04-30 11:32:56 -04:00
Matt Portune
9d27f111bf Additional uri parsing intelligence (#861) 2020-04-29 13:09:46 -04:00
Matt Portune
69e0906491 Fixes to uri parsing (#860) 2020-04-29 11:04:50 -04:00
Matt Portune
1d48171fd5 Prevent actionsheet command execution if vault is locked (#857) 2020-04-28 10:25:13 -04:00
Matt Portune
cb0a3e3edf Added additional smarts for establishing permission to draw over other apps (#853) 2020-04-24 14:45:11 -04:00
Chris
2b3915a91f Allow a BiometricPrompt to succeed after an initial failure (#791) (#847)
Previously a call to BiometricPrompt.AuthenticationCallback#OnAuthenticationFailed()
was treated as though an unrecoverable failure had occurred. However this is called on
each failed fingerprint match, for example, and is not a terminal failure. Now these
intermittent failures are ignored and a call to #OnAuthenticationError() is recognised
as an unrecoverable failure instead.
2020-04-23 10:28:43 -04:00
Matt Portune
9a403ba0ed Fixed clipboard not clearing on Android 10 (#851) 2020-04-23 10:01:41 -04:00
Matt Portune
0f35885d1c Set Google publisher upload timeout to 3 minutes (#850) 2020-04-22 13:50:25 -04:00
Matt Portune
e3e07b6bfe Only publish to Google Play if master branch (#848) 2020-04-22 10:54:58 -04:00
Contribucious
84a6d1db71 Add support for Vivaldi Sopranos browser. Closes #673 (#845)
* Add Vivaldi Sopranos to SupportedBrowsers dict

* Add Vivaldi Sopranos to CompatBrowsers

* Add Vivaldi Sopranos compatibility-package entry
2020-04-21 08:49:03 -04:00
Contribucious
8cee50299f Add support for Brave Beta browser (#846)
* Add Brave Beta to SupportedBrowsers dict

* Add Brave Beta to CompatBrowsers

* Add Brave Beta compatibility-package entry
2020-04-21 08:48:29 -04:00
Matt Portune
5a78cbef02 Tracing bundles (#842)
* Output to bundle (play store build only) and enable startup tracing

* Update ci build script to recognize bundle (.aab) for Google Play build

* Added bundle awareness to `appveyor.yml` and `Program.cs`

* Log upload exception

* Restore original apk creation alongside the bundle

* Remove link skip as AOT doesn't support linking
2020-04-17 17:06:37 -04:00
Kyle Spearrin
ae66a781d1 dont use encrypted keystore 2020-04-17 12:55:12 -04:00
Kyle Spearrin
5ae3b66e06 add slash 2020-04-16 17:19:56 -04:00
Kyle Spearrin
c3f1cee5d6 remove salt 2020-04-16 17:12:30 -04:00
Kyle Spearrin
5552c42e37 try secure-file ... again.... 2020-04-16 17:11:25 -04:00
Kyle Spearrin
6f146b888b update secure-file tool 2020-04-16 16:54:32 -04:00
Kyle Spearrin
56c09eae90 add salt to upload key decryption step 2020-04-16 16:43:00 -04:00
Kyle Spearrin
6883864e2d sign with upload keystore 2020-04-16 16:31:52 -04:00
Ash Thompson
15bc395454 Add support for Naver Whale. #600 (#837)
* Add Naver Whale to SupportedBrowsers dict

* Add Naver Whale to CompatBrowsers

* Add Naver Whale compatibility-package
2020-04-16 10:08:16 -04:00
Matt Portune
41997d5fe0 Resync autofill compatibility package list with values from AutofillHelpers (#834) 2020-04-15 13:58:00 -04:00
Jose F. Fernandez
ed259cd130 [FIX] Consider default URI match type on filtering (#830) 2020-04-14 14:56:57 -04:00
Vincent Salucci
1dc027cf49 [Autofill] Apply locked autofill flow to logged out state (#827)
* Initial commit: apply locked auto-fill flow to log out auto-fill

* Alphabetized imports

* Removed unnecessary else conditional

* Fix for talkback slider control (#828)

* Initial commit: apply locked auto-fill flow to log out auto-fill

* Alphabetized imports

* Removed unnecessary else conditional

* Fixed variable init order

Co-authored-by: Matt Portune <59324545+mportune-bw@users.noreply.github.com>
2020-04-13 11:32:23 -05:00
Matt Portune
b2abcda111 Fix for talkback slider control (#828) 2020-04-10 13:30:02 -04:00
Matt Portune
d66eaf8855 Additional accessibility tweaks (#825)
* Additional accessibility tweaks

* Cleanup
2020-04-09 14:57:06 -04:00
Dustin Falgout
78cfd82fdd Remove Unnecessary Toast Message (#808)
Remove unnecessary info message when clicking search during the autofill flow. Fixes #807
2020-04-06 13:19:15 -04:00
Matt Portune
8ad44b405d Add support for Vivaldi snapshot browser (#822)
* Add support for Vivaldi snapshot browser

* Added to autofill helpers CompatBrowsers set as well
2020-04-06 11:43:45 -04:00
Matt Portune
4ce4288f68 Updated dependencies (#820) 2020-04-03 17:17:24 -04:00
Matt Portune
d635555576 Tweaks to autofill tile naming & fixed missing plus icon (#819) 2020-04-03 09:57:04 -04:00
Matt Portune
44999557c0 Tweaks to accessibility autofill overlay (#818) 2020-04-02 19:24:31 -04:00
Matt Portune
5d64bab719 Added handled exception tracking for vault export and bumped CsvHelper to latest (#816)
* Added handled exception tracking for vault export and bumped CsvHelper to latest

* Prevent tracking for FDroid builds

* Remove AppCenter import for FDroid builds
2020-04-02 10:30:21 -04:00
Matt Portune
4d3d8b643a Conversion of HockeyApp to AppCenter for crash reporting (#810)
* Conversion of HockeyApp to AppCenter for crash reporting

* Corrected older-style nuget package definition
2020-04-02 09:02:38 -04:00
Kyle Spearrin
915e8cf072 add litedb to linker skip 2020-03-31 13:23:56 -04:00
Chad Scharf
3c18fd7636 Changed all C# control flow block statements to include space between keyword and open paren (#800) 2020-03-28 09:16:28 -04:00
Matt Portune
6c00ac43fc Added Quick Settings tile for triggering accessibility autofill (#795)
* Added Quick Settings tile for triggering accessibility autofill

* Fix crash when tile attempt to cancel non-visible but non-null overlay

* Persist tile state plus cleanup
2020-03-26 12:15:33 -04:00
Kyle Spearrin
5d9a597d8d switch to stable image 2020-03-26 09:27:24 -04:00
Kyle Spearrin
92930955c3 New Crowdin translations (#794)
* New translations AppResources.resx (Korean)

* New translations copy.resx (Korean)

* New translations copy.resx (Korean)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Greek)

* New translations copy.resx (Greek)

* New translations copy.resx (Greek)
2020-03-24 14:49:44 -04:00
Matt Portune
145482ea30 Project lib updates and migration (#789)
* Replace 3rd party FAB lib with our own code

* merged

* merged

* WIP

* WIP

* WIP

* WIP

* Updated LiteDB

* Update ZXing libs to 2.4.1

* Missing semicolon

* rename fab style to btn-fab

* Revert project guid modified by VSmac
2020-03-20 17:54:23 -04:00
Matt Portune
6fdb1e3356 Add support for inverse data matrix QR codes (#787) 2020-03-19 17:07:15 -04:00
Vincent Salucci
55dff81b9f Sanitize Password Length (#783)
* Sanitize Password Length

* Formatting updates

* Else if format

Co-authored-by: Vincent Salucci <vsalucci@bitwarden.com>
2020-03-18 13:43:20 -05:00
Matt Portune
ed37972b99 Updated .gitignore with latest from Xamarin repo and removed Android Resource.designer.cs file (#781)
* Updated .gitignore with latest from Xamarin repo and removed Android Resource.designer.cs file

* didn't mean to leave vscode settings line in
2020-03-18 11:42:20 -04:00
Kyle Spearrin
c6b37307b0 use string.Empty 2020-03-16 21:07:54 -04:00
Kyle Spearrin
5d719ba235 bump version 2020-03-16 21:05:56 -04:00
Vincent Salucci
c19795cce0 Fix bug with policy banner visibility (#777)
Co-authored-by: Vincent Salucci <vsalucci@bitwarden.com>
2020-03-16 11:17:45 -05:00
Vincent Salucci
df8f44d77d Enforce Passphrase Policy (#772)
* Enforce passphrase policy

* Update multi-line conditional formatting

* Updated formatting round 2

Co-authored-by: Vincent Salucci <vsalucci@bitwarden.com>
2020-03-13 23:02:38 -05:00
Matt Portune
a4eff45534 Testing Google publisher fix (#773) 2020-03-13 21:50:00 -04:00
Kyle Spearrin
b2b12be3b0 update google publisher lib 2020-03-13 11:55:03 -04:00
Matt Portune
9c77c53366 Bumped csvhelper to 15.0.1 and added missing error dialog in export failure flow (#771) 2020-03-13 11:02:49 -04:00
Kyle Spearrin
1449f165dd New Crowdin translations (#770)
* New translations AppResources.resx (Belarusian)

* New translations copy.resx (Hebrew)

* New translations copy.resx (Hindi)

* New translations copy.resx (Hungarian)

* New translations copy.resx (Indonesian)

* New translations copy.resx (Italian)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations copy.resx (Norwegian Bokmal)

* New translations AppResources.resx (Polish)

* New translations copy.resx (German)

* New translations copy.resx (Chinese Simplified)

* New translations copy.resx (Czech)

* New translations copy.resx (Croatian)

* New translations copy.resx (Danish)

* New translations AppResources.resx (Dutch)

* New translations copy.resx (Finnish)

* New translations copy.resx (Estonian)

* New translations AppResources.resx (Estonian)

* New translations copy.resx (English, United Kingdom)

* New translations AppResources.resx (English, United Kingdom)

* New translations AppResources.resx (Russian)

* New translations copy.resx (Russian)

* New translations AppResources.resx (Spanish)
2020-03-12 21:15:15 -04:00
Matt Portune
94216cf745 Null check policies from SyncResponse before parsing (#767)
* Null check policies from SyncResponse before parsing

* Update src/Core/Services/SyncService.cs

formatting

Co-Authored-By: Kyle Spearrin <kspearrin@users.noreply.github.com>

Co-authored-by: Kyle Spearrin <kspearrin@users.noreply.github.com>
2020-03-12 15:45:34 -04:00
Kyle Spearrin
120e179fb8 Move tab bar colors to styles (#764) 2020-03-11 09:46:48 -04:00
kspearrin
f10114ee17 * iOS.Autofill.csproj: Fix profiles used for builds
* iOS.csproj:
* iOS.Extension.csproj:
2020-03-11 09:33:52 -04:00
Matt Portune
8a059e0fbb Fixed issue where multiple threads were attempting to modify search result list (#761)
* Fixed issue where multiple threads were attempting to modify search result list

* Fixed race condition
2020-03-09 18:43:28 -04:00
Kyle Spearrin
6263788d6a New Crowdin translations (#758)
* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Greek)

* New translations AppResources.resx (German)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Italian)
2020-03-06 11:30:58 -05:00
Matt Portune
6ffb3136d4 Workaround for older bug in Xamarin.Forms by waiting for app to resume before attempting to set Application.Current.MainPage (#757) 2020-03-05 16:18:04 -05:00
Matt Portune
b65b01fe3d Fixed potential broadcast leak & policy value parsing (#756) 2020-03-05 12:44:01 -05:00
Kyle Spearrin
b9c134654f Allows us to pass in some options to have policies enforced upon. (#755) 2020-03-05 10:11:54 -05:00
Kyle Spearrin
d1a1342587 New Crowdin translations (#754)
* New translations AppResources.resx (Afrikaans)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Japanese)

* New translations copy.resx (Japanese)

* New translations copy.resx (Japanese)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Polish)

* New translations copy.resx (Polish)

* New translations copy.resx (Polish)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Romanian)

* New translations AppResources.resx (Russian)

* New translations copy.resx (Russian)

* New translations copy.resx (Russian)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Thai)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Hindi)

* New translations AppResources.resx (Belarusian)

* New translations copy.resx (Dutch)

* New translations copy.resx (Belarusian)

* New translations copy.resx (Belarusian)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Croatian)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Dutch)

* New translations copy.resx (Dutch)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (English, United Kingdom)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (French)

* New translations copy.resx (French)

* New translations copy.resx (French)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Greek)

* New translations copy.resx (Greek)

* New translations copy.resx (Greek)

* New translations AppResources.resx (Vietnamese)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Italian)
2020-03-05 09:39:05 -05:00
Kyle Spearrin
1ec2ac472a Update ISSUE_TEMPLATE.md 2020-03-04 09:18:27 -05:00
Clayton
9894322c17 Update ISSUE_TEMPLATE.md (#752)
* Update ISSUE_TEMPLATE.md

Added a uniform template to be used for all issues that are reported.

* Update ISSUE_TEMPLATE.md

Added Beta Version, Build Version, and Videos to the list.
2020-03-04 09:11:38 -05:00
Matt Portune
7edbf4ffc8 Added null check for loading non-existent policies (#753) 2020-03-03 10:53:03 -05:00
Matt Portune
2b1d186611 New Android attachment handling to support saving or opening attachments (#751)
* New Android attachment handling to support saving or opening (when available) attachments

* Simplified options dialog logic & changed error text
2020-03-02 22:14:14 -05:00
Kyle Spearrin
70c49922b0 adjust setting.Value on empty string 2020-02-29 00:44:36 -05:00
Kyle Spearrin
30d6a4d9eb restrictions apparantly cannot have a null default value 2020-02-29 00:42:11 -05:00
Matt Portune
033b2b9ba0 Fixes for html wrapping and encoding (#746) 2020-02-28 15:20:59 -05:00
Matt Portune
25aec80e4c Change switch binding back to using EnforcedPolicyOptions directly (#744) 2020-02-27 23:14:26 -05:00
Matt Portune
cf3d52772d Fixed password color and alignment on iOS password generator (#743) 2020-02-27 21:18:09 -05:00
Matt Portune
f78f303a79 Password generator policy enforcement (#741)
* Password generator policy enforcement

* Formatting

* Changed to simple cast (double unboxing for int64/long)

* Added ui indication of active policy on password generator page and fixed issue with switch enable logic
2020-02-27 19:53:02 -05:00
Kyle Spearrin
02cffa01e2 formatting 2020-02-24 08:58:15 -05:00
Oldřich Jedlička
c2f2a5e52f Make callbacks from UI thread. (#739)
The code expects to be called form UI thread, but it loks like JavaScript
callbacks are not. Switch to UI thread when invoking a callback.

Signed-off-by: Oldřich Jedlička <oldium.pro@gmail.com>
2020-02-24 08:57:36 -05:00
Oldřich Jedlička
d8e19415e3 Fix runtime exception. (#738)
In the callback the processing does not go in the main UI thread, so we
need to switch there. Otherwise on Android this throws
Android.Util.AndroidRuntimeException with detail “Only the original thread
that created a view hierarchy can touch its views”.

Discovered by trying to login with Duo as a two-factor login type.

Signed-off-by: Oldřich Jedlička <oldium.pro@gmail.com>
2020-02-22 21:09:10 -05:00
Matt Portune
387dc2f59c Beginning of policy support (#736)
* Model & service support for policies

* Formatting

* Changes to match existing service and model patterns
2020-02-21 10:23:38 -05:00
Kyle Spearrin
ec3660a86d bitwarden inc 2020-02-18 22:39:35 -05:00
Vincent Salucci
36fb23d467 Add ability to clone personal vault items (#734)
* Add clone ability to personal vault items

* Fixed formatter

* Made requested changes and removed some extra whitespace added by Rider formatter

* Removed formatting on AppResources file

* Fixed casing on UpdateCipherId method

* Update calling method
2020-02-18 15:48:23 -06:00
Matt Portune
33df456cfd In-app vault export support (#729)
* First pass at vault export UI

* Password validation via cryptoService

* Export service framework

* support for constructing json export data

* Support for constructing csv export data

* Cleanup and simplification

* Completion of vault export feature

* Formatting and simplification

* Use dialog instead of toast for invalid master password entry
2020-02-14 16:10:58 -05:00
Kyle Spearrin
7a6fe5ed5f Check blacklist before showing overlay (#730) 2020-02-13 18:33:37 -05:00
Kyle Spearrin
558b10499b var 2020-02-12 09:40:16 -05:00
Kyle Spearrin
1fb3698ba2 support for appconfig settings (#727) 2020-02-10 14:07:06 -05:00
Kyle Spearrin
89f26bbc6b Migrate EnvironmentUrlsKey to pref storage (#725) 2020-02-10 11:32:58 -05:00
Matt Portune
bbd8615cda Align overlay to bottom or top of anchor view depending on available space (bottom by default on initial focus). Establishing visible app height now works much better on Android 5.0+. (#718) 2020-02-05 19:40:44 -05:00
Kyle Spearrin
93132f5d7b version bump 2020-02-03 09:26:29 -05:00
Matt Portune
179514ddf1 Support for multiple browser UriViewIds when extracting a uri (#713)
* Support for multiple browser UriViewIds when extracting a uri

* Simplified
2020-01-29 12:59:17 -05:00
Matt Portune
4b9cff2271 Removal of double-event block for known browsers since it's no longer necessary and was preventing the overlay from working with some browsers (#712) 2020-01-29 09:59:35 -05:00
Kyle Spearrin
c3649a9c80 formatting touchups 2020-01-29 08:46:21 -05:00
Matt Portune
9a66b9003f Made node recycling approach a bit more surgical to appease older versions of Android, and adjusted anchor position offset for older versions of Android (#711) 2020-01-29 07:23:49 -05:00
Matt Portune
34e32403b0 Accessibility fixes (#709)
* Show/hide accessibility overlay on scroll based on several visibility factors

* Improvements to accessibility overlay anchor view tracking

* Increase recursion limit and check for null children when walking the node tree

* Cleanup

* Hide overlay when expanding status (notification) bar

* use .Any() instead of .Count()
2020-01-27 17:36:20 -05:00
Kyle Spearrin
c2e34a8b0e skip linking on OldAndroidSSLSocketFactory 2020-01-27 08:22:46 -05:00
Matt Portune
d0ba4b6702 Accessibility overlay support for username field and scroll tracking (#700)
* Trigger overlay prompt when focusing on username field

* Adjust accessibility overlay position in response to scroll events

* Get username EditText with a single pass of the node tree, plus additional cleanup
2020-01-13 17:14:57 -05:00
Kyle Spearrin
eb16025800 tweaks to accessibility changes 2020-01-10 15:42:50 -05:00
Matt Portune
9f06c9a051 Removal of deprecated Android Accessibility Service options (#698) 2020-01-10 11:34:17 -05:00
Matt Portune
641122b16f UI support in app settings for handling overlay permission requirement in Accessibility Service implementation (#697)
* UI support in app settings for handling overlay permission requirement in Accessibility Service implementation

* Cleaned up shorthand operator with new var
2020-01-10 10:20:19 -05:00
Kyle Spearrin
fbe8708378 cleanup on accessibility service 2020-01-09 13:17:17 -05:00
Matt Portune
21c7b486ff Replaced accessibility service notification with in-line overlay. (#695)
* Replaced accessibility service notification with in-line overlay.  Requires draw-over permission to be enabled (will prompt if not, though this will be enhanced in subsequent commits)

* Updated with requested changes

* Fix for FDroid build
2020-01-09 12:17:16 -05:00
Matt Portune
c33728d418 * AccessibilityHelpers.cs: If (#689)
AccessibilityNodeInfo.FindAccessibilityNodeInfosByViewId(..) returns
  null when the source package is a supported browser, return a null
  uri to prevent overwriting the existing notification's pendingIntent
  uri extra with the brower's packageName.

* AccessibilityService.cs: Added null uri checks as it is now possible
  for AccessibilityHelpers.getUri(..) to return a null uri when the
  Accessibility Service is misbehaving.
2020-01-03 15:19:20 -05:00
ShirokaiLon
a9dacd561c Change password generator to use ColoredPassword (#686)
* Change password generator to use ColoredPassword

* Change ColoredPassword from FormattedString to HTML string for improved performance

* PasswordFormatter fixes

* Correct || to && condition

* Apply password colouring to history pages
2020-01-03 14:56:55 -05:00
Kyle Spearrin
051e15215d bump version 2019-12-26 15:15:15 -05:00
proletarius101
fee8f58c0a Add support for Tor browser (#680) 2019-12-26 07:29:20 -05:00
Kyle Spearrin
cc036cf3c5 Set lock page on resume for android 2019-12-16 09:43:14 -05:00
Kyle Spearrin
4e51517ddb update libs 2019-12-16 09:14:54 -05:00
Kyle Spearrin
3b7454961d New Crowdin translations (#663)
* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Romanian)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Polish)

* New translations copy.resx (Persian)

* New translations copy.resx (Persian)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (German)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (English, United Kingdom)

* New translations copy.resx (Dutch)

* New translations copy.resx (Dutch)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Croatian)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Ukrainian)
2019-12-03 11:35:09 -05:00
Kyle Spearrin
88009e1a63 bump versions 2019-12-03 11:11:30 -05:00
Kyle Spearrin
0afca29b0c still load list if there are any ciphers 2019-11-22 09:51:30 -05:00
Kyle Spearrin
46a75a2944 Revert "try new http client handler for icons"
This reverts commit c099f82752.
2019-11-22 08:24:23 -05:00
Kyle Spearrin
c099f82752 try new http client handler for icons 2019-11-20 17:38:05 -05:00
Kyle Spearrin
1da94bd9c8 completed status on track release 2019-11-20 10:39:15 -05:00
Kyle Spearrin
96ce8165e9 upgrade to v3 publisher apis 2019-11-20 09:57:40 -05:00
Kyle Spearrin
f9b617339d try builds with VS 2019 preview 2019-11-20 08:25:52 -05:00
Kyle Spearrin
58084810f3 don't auto-capitalize password field when viewed 2019-11-20 08:24:08 -05:00
Kyle Spearrin
429e62e6b5 Don't index a "never" uri match. 2019-11-19 07:47:01 -05:00
Kyle Spearrin
b0b7f2afdf Merge branch 'master' of github.com:bitwarden/mobile 2019-11-15 08:55:31 -05:00
Kyle Spearrin
55f160d125 Show exception message from Api errors 2019-11-15 08:55:22 -05:00
Wasim Malik
f6352f5392 Updated Incorrect Check Condition (#648)
Issue is fixed No 361
Now tested on android device extra comma is not appended anymore
2019-11-12 16:28:12 -05:00
Kyle Spearrin
ac7e90c0aa blacklist com.android.settings from autofill 2019-11-08 11:57:07 -05:00
Kyle Spearrin
88fccfd6cd try setting http version 1.0 2019-11-05 09:14:55 -05:00
Kyle Spearrin
5fdf8e6045 set fingerprint lock prop on login 2019-11-05 09:03:48 -05:00
Kyle Spearrin
d9907cdbeb style fixes for xamarin forms 4 2019-10-30 09:30:45 -04:00
Kyle Spearrin
d308f1ca3b update libs and to xamarin forms 4 2019-10-30 08:27:40 -04:00
Kyle Spearrin
0cdc138ba3 dont immediatly prompt biometric when locked 2019-10-30 08:08:15 -04:00
Kyle Spearrin
59d5314164 New Crowdin translations (#639)
* New translations AppResources.resx (Afrikaans)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Romanian)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Thai)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Hindi)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Croatian)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (English, United Kingdom)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (French)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Vietnamese)
2019-10-23 20:55:51 -04:00
Kyle Spearrin
9c08a37772 UseNativeBiometric only for SDK 29 2019-10-23 11:54:53 -04:00
Kyle Spearrin
b13f5356fe FingerprintManager to detect fingerprints on SDK 28 2019-10-23 11:26:00 -04:00
Kyle Spearrin
5f0c9725ce bump version 2019-10-23 09:27:31 -04:00
Kyle Spearrin
f951fea555 use bio strings for native android bio 2019-10-23 09:24:34 -04:00
Kyle Spearrin
4b989b01e9 use native biomatrics on Android 2019-10-23 09:11:48 -04:00
Kyle Spearrin
aed3ec5474 check authed and unlocked before trying to load 2019-10-22 16:42:05 -04:00
Kyle Spearrin
b354986199 null check apiexception error 2019-10-22 16:37:40 -04:00
Kyle Spearrin
e1983a7d66 fix error when login token expires 2019-10-22 16:30:28 -04:00
Kyle Spearrin
0400d79f43 android 10 and bio permission 2019-10-18 20:41:04 -04:00
Kyle Spearrin
c911484632 upgrade builds to vs 2019 2019-10-18 14:21:07 -04:00
Kyle Spearrin
713e441d2e upgrade to android 10 sdk 2019-10-18 14:19:56 -04:00
Kyle Spearrin
d4b577732b npm audit fix 2019-10-17 08:01:50 -04:00
Kyle Spearrin
440a410d7f skip com.treydev.pns 2019-10-17 08:00:58 -04:00
Kyle Spearrin
37a536b138 catch thrown sync errors from ui 2019-10-15 11:05:56 -04:00
Kyle Spearrin
a0aca3e837 add tf browser 2019-10-11 09:29:33 -04:00
Kyle Spearrin
b58c29111a bump version 2019-10-07 09:42:55 -04:00
Kyle Spearrin
b0f86ea161 focus search bar on appear 2019-10-07 09:23:41 -04:00
Kyle Spearrin
93b59a75a4 remove migration code 2019-10-05 21:36:47 -04:00
Kyle Spearrin
54fcabaea6 shorter delays 2019-10-05 21:31:55 -04:00
Kyle Spearrin
0e966c0304 fix min character assignments for pw gen 2019-10-05 20:39:42 -04:00
Kyle Spearrin
a363712127 use black text for search bar on light theme 2019-10-04 09:32:59 -04:00
Kyle Spearrin
4d8c665917 fix light theme 2019-10-04 09:11:14 -04:00
kspearrin
53bdd92e72 support dark theme default on extensions 2019-09-30 21:40:05 -04:00
Kyle Spearrin
e51aa39ede New Crowdin translations (#614)
* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Croatian)

* New translations copy.resx (German)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Dutch)

* New translations copy.resx (Dutch)

* New translations copy.resx (Dutch)
2019-09-30 21:35:24 -04:00
Kyle Spearrin
33c82129ff bump version 2019-09-30 21:19:20 -04:00
kspearrin
7c5b8c0e9f modal full screen 2019-09-30 21:17:53 -04:00
kspearrin
9dc01bca1c detect dark mode theme. set modal to full screen 2019-09-30 20:38:22 -04:00
Kyle Spearrin
3c7920b84c XF 3.6 update 2019-09-30 20:33:54 -04:00
Kyle Spearrin
b92f3abbaf support dark theme logos 2019-09-30 16:52:20 -04:00
Kyle Spearrin
b6747a63ed stub out support for dark theme by default 2019-09-30 16:41:31 -04:00
Kyle Spearrin
41a44548d2 use TextColor for search bar text color 2019-09-30 16:33:53 -04:00
Kyle Spearrin
a79d3a0d7c uisearchbar tint color 2019-09-30 16:28:07 -04:00
kspearrin
f3a17709e5 get proper hex string from nsdata token 2019-09-30 16:24:35 -04:00
Kyle Spearrin
ced9d33d2e memory stored pinProtectedKey 2019-09-20 16:43:03 -04:00
Kyle Spearrin
23b1373f80 add tag to entitlement 2019-09-20 08:17:37 -04:00
Kyle Spearrin
a80eb1f533 bump version 2019-09-20 07:56:49 -04:00
Kyle Spearrin
f657edf195 add support for vivaldi browser. resolves #599 2019-09-10 17:21:11 -04:00
Kyle Spearrin
d34279dca5 more null checks on add/edit save 2019-09-06 10:03:11 -04:00
Kyle Spearrin
954aa1112a added locale names dictionary 2019-09-06 09:44:25 -04:00
Kyle Spearrin
b35a3339cb device type should be int 2019-09-06 09:44:25 -04:00
Kyle Spearrin
b59433debd New Crowdin translations (#594)
* New translations copy.resx (Bulgarian)

* New translations copy.resx (Bulgarian)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (French)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Romanian)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Turkish)
2019-09-04 13:10:18 -04:00
Kyle Spearrin
fb2db9c652 version bump 2019-09-04 13:02:00 -04:00
Kyle Spearrin
2507f3301b device user agent 2019-09-04 11:52:32 -04:00
Kyle Spearrin
bdad5e4f0a fixes to opening file types on android 2019-08-30 16:43:58 -04:00
Kyle Spearrin
b5dcdc74d7 dark keyboard on dark themes. resolves #588 2019-08-28 20:27:15 -04:00
Kyle Spearrin
e2d1da02d3 more null checking on save 2019-08-27 15:03:33 -04:00
Kyle Spearrin
8253f18312 null check cipher service 2019-08-27 14:55:15 -04:00
kenjirooo
f4a98a2031 Added support for Sleipnir Mobile (https://play.google.com/store/apps/details?id=jp.co.fenrir.android.sleipnir). (#583) 2019-08-22 08:00:03 -04:00
Kyle Spearrin
224845cfd3 bump version 2019-08-12 09:41:12 -04:00
Kyle Spearrin
fc8c2ad67a add back references for autofill projects 2019-08-12 09:36:10 -04:00
Kyle Spearrin
c9d6f58563 delay for 1s on SyncIfNeeded 2019-08-12 09:35:18 -04:00
Kyle Spearrin
325b557506 null check on SyncIfNeeded 2019-08-12 08:51:49 -04:00
Kyle Spearrin
ce751cfc87 fix unlock logic 2019-08-12 08:05:45 -04:00
Kyle Spearrin
0f451fd4b9 set FingerprintUnlockKey before setKey 2019-08-10 00:19:01 -04:00
Kyle Spearrin
b7819838b8 parse fallback package id from first node title 2019-08-01 16:39:01 -04:00
Kyle Spearrin
67c6cf6b8c load previous view/edit page after lock 2019-07-31 16:50:16 -04:00
Kyle Spearrin
d91d71333b LastClipboardValue using static store rather than state 2019-07-31 11:21:07 -04:00
Kyle Spearrin
431804ea80 loop on reset with range instead of clear 2019-07-29 22:35:53 -04:00
Kyle Spearrin
7a7ab7bd0e New Crowdin translations (#570)
* New translations AppResources.resx (French)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Hungarian)

* New translations copy.resx (Hungarian)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Russian)
2019-07-29 15:15:21 -04:00
Kyle Spearrin
b8cdee383b bump version 2019-07-27 12:42:42 -04:00
Kyle Spearrin
580fa02ee1 enable event logging 2019-07-27 12:41:38 -04:00
Kyle Spearrin
421834153d catch InteractionNotAllowed 2019-07-27 12:39:59 -04:00
Kyle Spearrin
011f04e1dc editorconfig 2019-07-26 11:44:43 -04:00
Kyle Spearrin
3d8056704c yubikey token entry is password field 2019-07-25 16:10:46 -04:00
Kyle Spearrin
41263f3419 New Crowdin translations (#569)
* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Polish)
2019-07-24 10:48:49 -04:00
Kyle Spearrin
9fe9210cb7 null check on id 2019-07-24 10:42:13 -04:00
Kyle Spearrin
2272b10820 null check on cipher when autofilling 2019-07-24 10:40:12 -04:00
Kyle Spearrin
9d6fc73fcc New Crowdin translations (#568)
* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (German)

* New translations AppResources.resx (French)

* New translations AppResources.resx (English, United Kingdom)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Ukrainian)
2019-07-23 09:30:01 -04:00
Kyle Spearrin
73ecd67b20 New Crowdin translations (#567)
* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (German)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Estonian)
2019-07-23 09:16:10 -04:00
Kyle Spearrin
e5ce3dbd32 visibility typo 2019-07-23 09:11:01 -04:00
Kyle Spearrin
a0a5e30f48 re-work hockeyapp init 2019-07-23 09:08:16 -04:00
Kyle Spearrin
0eddee5816 check $LastExitCode 2019-07-23 00:10:25 -04:00
Kyle Spearrin
6d2dcb73ae event service func 2019-07-23 00:06:34 -04:00
Kyle Spearrin
0d6cc91b67 don't allow device PIN fallback 2019-07-22 23:34:39 -04:00
Kyle Spearrin
ae52922698 version bump 2019-07-22 23:07:00 -04:00
Kyle Spearrin
236496e69f formatting 2019-07-22 21:37:56 -04:00
kspearrin
fe5cdb0004 * CredentialProviderViewController.cs:
* LoadingViewController.cs: reset after using event service
2019-07-22 21:35:05 -04:00
Kyle Spearrin
f9547f158e log autofill events 2019-07-22 15:50:59 -04:00
Kyle Spearrin
0c75374c0f New Crowdin translations (#565)
* New translations AppResources.resx (Afrikaans)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Romanian)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Thai)

* New translations AppResources.resx (Vietnamese)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Croatian)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Hindi)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (German)

* New translations AppResources.resx (English, United Kingdom)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (Estonian)
2019-07-22 14:53:12 -04:00
Kyle Spearrin
0b249d4dd4 check yubico token length == 44 2019-07-22 13:59:12 -04:00
Kyle Spearrin
a2bac9d368 a11y labeling 2019-07-22 12:04:17 -04:00
Kyle Spearrin
392e429dfd more options button for ios on folder add/edit 2019-07-22 10:52:19 -04:00
Kyle Spearrin
50623b9b29 fix no folder reference 2019-07-22 10:52:04 -04:00
Kyle Spearrin
e7ce050324 use fingerprintButtonText on extension unlock 2019-07-22 10:24:18 -04:00
Kyle Spearrin
762b574d49 rebuild same fingerprintName string 2019-07-22 10:12:14 -04:00
Kyle Spearrin
d73bf6d225 assign new messageCallback when subbing 2019-07-22 09:21:00 -04:00
Kyle Spearrin
c2108fdda0 null checking 2019-07-22 08:44:55 -04:00
Kyle Spearrin
2062a284e3 fix lock checks on sleep of app 2019-07-22 08:37:06 -04:00
Kyle Spearrin
9164c9b946 InitAppIfNeeded 2019-07-22 08:22:02 -04:00
Kyle Spearrin
13ddd10c40 update autofill identities if needed 2019-07-22 07:09:51 -04:00
Kyle Spearrin
e407acd2a7 bump version 2019-07-13 20:28:20 -04:00
Kyle Spearrin
11cdf52ec8 disable events funcionality for now 2019-07-13 20:27:15 -04:00
Kyle Spearrin
40a3541e8e handle sleep event on ios manually 2019-07-13 20:25:31 -04:00
Kyle Spearrin
7da13e22ad process event uploads on ios 2019-07-12 20:56:54 -04:00
Kyle Spearrin
38d702b6fe log some events 2019-07-12 17:29:40 -04:00
Kyle Spearrin
df2af5459e register event service with container 2019-07-12 15:51:47 -04:00
Kyle Spearrin
40d68b1654 add event service 2019-07-11 09:30:25 -04:00
Kyle Spearrin
a240a4ac66 get autofill web scheme for android p devices 2019-07-11 08:55:40 -04:00
Kyle Spearrin
416ec3812d iphone x screenshots 2019-07-10 14:17:28 -04:00
Kyle Spearrin
ff24891903 update event log types 2019-07-09 10:51:33 -04:00
Kyle Spearrin
ddcbe298ac 6.5 inch screenshots for ios 2019-07-09 09:48:27 -04:00
Kyle Spearrin
6d8f647aee two new screenshots for iphone, update 1 2019-07-09 01:09:53 -04:00
Kyle Spearrin
a654987175 upadte screenshots for 5.5 inch iphone 6 2019-07-08 17:34:04 -04:00
Kyle Spearrin
a5f960d8a1 show proper name for faceid. homepage margin on ios 2019-07-08 13:37:45 -04:00
Kyle Spearrin
1f707cda68 New Crowdin translations (#556)
* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (French)
2019-07-08 13:12:09 -04:00
Kyle Spearrin
4e7f195fd2 bump versions 2019-07-08 13:02:48 -04:00
Kyle Spearrin
7728e930be delay focus on entry on ios too 2019-07-08 12:06:37 -04:00
Kyle Spearrin
ab84200347 change default lock on new installs to 15 minutes 2019-07-06 23:04:10 -04:00
Kyle Spearrin
62d8824450 clear cache in main app if change made in extension 2019-07-06 22:49:17 -04:00
Kyle Spearrin
cf35d20adb refresh search on appear if has text 2019-07-06 22:19:29 -04:00
Kyle Spearrin
65725b5a38 yubikey token must be > 40 in length too 2019-07-06 22:09:20 -04:00
Kyle Spearrin
eca4777b99 yubikey fixes for ios 2019-07-06 21:59:13 -04:00
Kyle Spearrin
066b3aba5b wait 5 seconds after migration 2019-07-05 17:37:21 -04:00
Kyle Spearrin
8e485ff26f add back refs for extensions 2019-07-05 17:14:08 -04:00
Kyle Spearrin
341b66f44f settings shim with ios group id 2019-07-05 17:10:37 -04:00
Kyle Spearrin
19c62d3320 Merge branch 'master' of github.com:bitwarden/mobile 2019-07-05 16:37:12 -04:00
Kyle Spearrin
13ffbd7675 add app extension flags to migration 2019-07-05 16:36:56 -04:00
Kyle Spearrin
9af6aae699 fix baseurl check when return web vault url 2019-07-05 13:46:54 -04:00
Kyle Spearrin
2e562e8318 ios migration from old version 2019-07-05 13:35:22 -04:00
Kyle Spearrin
c6db763716 New Crowdin translations (#554)
* New translations AppResources.resx (English, United Kingdom)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (French)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Ukrainian)
2019-07-04 08:43:40 -04:00
Kyle Spearrin
a3383af4ae hides shadow on nav bar 2019-07-03 20:39:00 -04:00
Kyle Spearrin
6c56e44b61 prefix keychain key with appid 2019-07-03 20:04:23 -04:00
Kyle Spearrin
64506a7080 UINavigationBar appearance for no bottom line 2019-07-03 17:37:33 -04:00
Kyle Spearrin
fac9ae4b6c only init hockeyapp once 2019-07-03 16:50:12 -04:00
Kyle Spearrin
a2dc73afef New Crowdin translations (#553)
* New translations AppResources.resx (Afrikaans)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Romanian)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Croatian)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Hindi)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (English, United Kingdom)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Vietnamese)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Thai)
2019-07-03 15:15:21 -04:00
Kyle Spearrin
59c5a34cd0 adjust bundle signing config 2019-07-03 15:03:09 -04:00
Kyle Spearrin
3321e6b0e2 set entitlements 2019-07-03 14:54:12 -04:00
Kyle Spearrin
8b7ac179fa in memory storage service 2019-07-03 12:31:18 -04:00
Kyle Spearrin
ea745665c8 remove continue button if no 2fa available 2019-07-03 12:21:06 -04:00
Kyle Spearrin
ca8f6ee10b FFImageLoading only for main app 2019-07-03 10:08:59 -04:00
Kyle Spearrin
3e51ff46f3 forget bg colors :( 2019-07-02 23:31:52 -04:00
Kyle Spearrin
fa2e814559 style headers and footer 2019-07-02 22:27:21 -04:00
Kyle Spearrin
87e337cbeb try color header bg again 2019-07-02 20:52:44 -04:00
Kyle Spearrin
abb39df547 reset service container from extensions 2019-07-02 20:45:54 -04:00
Kyle Spearrin
43e15bf911 more bg color for header 2019-07-02 20:14:23 -04:00
Kyle Spearrin
4d79d0af89 bg for header/footer is tint color 2019-07-02 19:49:50 -04:00
Kyle Spearrin
69100d7db5 search bar bg is same as list header 2019-07-02 19:36:11 -04:00
Kyle Spearrin
a064a6cf9b theme updates to extensions 2019-07-02 19:35:01 -04:00
Kyle Spearrin
7953a9a3ce autofill activated regular color 2019-07-02 17:28:57 -04:00
Kyle Spearrin
be3c6f210d remove see apps from ext page 2019-07-02 17:27:55 -04:00
Kyle Spearrin
f7cbddab4b remove navibar outlet 2019-07-02 17:17:20 -04:00
Kyle Spearrin
d423818764 add hockeyapp to extensions 2019-07-02 16:28:01 -04:00
Kyle Spearrin
519acd43aa provisioning profiles 2019-07-02 16:13:09 -04:00
Kyle Spearrin
2682a0d9e4 --nodevcodeshare on debug 2019-07-02 14:58:18 -04:00
Kyle Spearrin
8629ae048c update build props 2019-07-02 14:43:07 -04:00
Kyle Spearrin
905d01e804 adjust settings 2019-07-02 14:14:59 -04:00
Kyle Spearrin
0588bbc41d remove remaining jsonnet deps 2019-07-02 14:06:21 -04:00
Kyle Spearrin
b308b4c54f move some json dependencies out of extension project 2019-07-02 14:03:59 -04:00
Kyle Spearrin
c2c73d5460 autofill pages for ios 2019-07-02 13:15:00 -04:00
Kyle Spearrin
e01bf57874 re-set state for website icons on login/unlock
resolves #549
2019-07-02 08:05:34 -04:00
Kyle Spearrin
7ced93225b logic on autoPromptFingerprint when locked 2019-07-02 07:50:09 -04:00
Kyle Spearrin
b5e61864af adjust header for autofill page 2019-07-02 00:19:59 -04:00
Kyle Spearrin
1e5aaea8f4 restore lockOptionMs 2019-07-01 23:45:31 -04:00
Kyle Spearrin
ab3bebf06a use background tasks to keep timers alive 2019-07-01 23:44:47 -04:00
Kyle Spearrin
4a294d6a77 save some lines 2019-07-01 21:16:28 -04:00
Kyle Spearrin
e0fda1a0bc fix ui thread issue 2019-07-01 21:15:53 -04:00
Kyle Spearrin
d17da80f19 lock timer 2019-07-01 21:10:24 -04:00
Kyle Spearrin
2e7658f857 clear clipboard timer 2019-07-01 16:56:42 -04:00
Kyle Spearrin
53d0b28c7c fix add matching eq domains
resolves #550
2019-07-01 16:06:52 -04:00
Kyle Spearrin
33ba4d3871 add capitalize and include num to generator 2019-07-01 15:35:26 -04:00
Kyle Spearrin
225db6397d ios app extension theming 2019-07-01 15:12:54 -04:00
Nicholas
73b5d1b3f1 add support for org.mozilla.fenix.nightly (#551)
* Update autofillservice.xml

* Update AutofillHelpers.cs

* Update AccessibilityHelpers.cs
2019-07-01 11:35:58 -04:00
Kyle Spearrin
8da2eac6d0 add support for org.mozilla.fennec_fdroid
resolves #548
2019-06-28 23:23:51 -04:00
Kyle Spearrin
fbd62153ee theme splash for extensions 2019-06-28 12:30:48 -04:00
Kyle Spearrin
9145fa1c48 improvement to lock screen 2019-06-28 11:47:04 -04:00
Kyle Spearrin
caa0af1258 remove old action view controllers 2019-06-28 10:45:42 -04:00
Kyle Spearrin
7a230ee5f5 app extension for autofill ios 2019-06-28 08:57:08 -04:00
Kyle Spearrin
f237fa98d2 ios autofill extension implemented 2019-06-28 08:21:44 -04:00
Kyle Spearrin
be4ae605a9 implement ASHelpers from messages 2019-06-27 16:22:58 -04:00
Kyle Spearrin
9c2cbc0ecb add shared controllers and view to ios core 2019-06-27 15:48:25 -04:00
Kyle Spearrin
fb3009fc66 core utils 2019-06-27 14:07:25 -04:00
Kyle Spearrin
04c32e28cd move device action to ios core 2019-06-27 13:58:08 -04:00
Kyle Spearrin
645576c949 port over models 2019-06-27 13:45:16 -04:00
Kyle Spearrin
775bee3546 fix dependency hell 2019-06-27 13:41:32 -04:00
Kyle Spearrin
88aea96034 add autofill resources 2019-06-26 20:52:17 -04:00
Kyle Spearrin
5f474dfaf5 add some missing resources 2019-06-26 20:43:14 -04:00
Kyle Spearrin
fe7aad0835 autofill extension project 2019-06-26 20:39:45 -04:00
Kyle Spearrin
79746efa2d action extension project 2019-06-26 20:28:23 -04:00
Kyle Spearrin
a158021f46 return selection collection logic 2019-06-26 17:50:57 -04:00
Kyle Spearrin
2d91a893f7 fix cursor color to renderers 2019-06-26 10:20:42 -04:00
Kyle Spearrin
dd4561d985 style cursor color 2019-06-26 10:12:34 -04:00
Kyle Spearrin
92764eeae0 hide status bar on homepage for ios 2019-06-26 10:05:31 -04:00
Kyle Spearrin
b72808ab40 splash screen bg colors and white logo 2019-06-26 09:35:18 -04:00
Kyle Spearrin
14f3f99218 fix attachments selection on ios 2019-06-25 17:46:37 -04:00
Kyle Spearrin
d7130d9b67 no entities state adjustments 2019-06-25 17:16:47 -04:00
Kyle Spearrin
3f94eee4d5 events url 2019-06-25 16:36:21 -04:00
Kyle Spearrin
72cbdcbc8d use internal FilesDir for temp photo 2019-06-25 11:54:31 -04:00
Kyle Spearrin
e33b49e78c externalsFileDir w/ FileProvider for temp store 2019-06-25 10:30:16 -04:00
Kyle Spearrin
8e04945d4e box-row-input-options-platform on share 2019-06-24 17:38:29 -04:00
Kyle Spearrin
3ca5da55cb fix more options for sharing on view/add/edit 2019-06-24 17:34:00 -04:00
Kyle Spearrin
ea30373a09 picker SetUpdateMode for ios 2019-06-24 17:32:24 -04:00
Kyle Spearrin
4b4757d0e5 ios resumed 2019-06-24 17:02:05 -04:00
Kyle Spearrin
4bc837509d fix double key formatting 2019-06-24 16:51:54 -04:00
Kyle Spearrin
c9d1e8dc65 nord theme toast for ios 2019-06-24 16:29:02 -04:00
Kyle Spearrin
88b8a192b5 no listview selection type on non-light theme 2019-06-24 16:16:17 -04:00
Kyle Spearrin
94fbf627ba no options during selection mode 2019-06-24 15:22:46 -04:00
Kyle Spearrin
45fbdb8411 ios theming 2019-06-24 15:13:33 -04:00
Kyle Spearrin
d9c947ccd0 black theme for ios 2019-06-24 14:49:47 -04:00
Kyle Spearrin
2b670a5ae1 ios themeing 2019-06-24 14:29:23 -04:00
Kyle Spearrin
1af0178b50 set theme properly on app launch for ios 2019-06-24 12:23:00 -04:00
Kyle Spearrin
3ec5d894b3 spacing for ios on options page 2019-06-24 12:05:01 -04:00
Kyle Spearrin
d81585ccc3 search bar for ios 2019-06-24 11:53:19 -04:00
Kyle Spearrin
38f91bce1c notes separator for ios 2019-06-24 11:22:34 -04:00
Kyle Spearrin
2d41dd6ae0 switch styling on iOS 2019-06-22 09:51:04 -04:00
Kyle Spearrin
1705a21f68 slider styling 2019-06-22 09:45:54 -04:00
Kyle Spearrin
164d79898a button styling 2019-06-22 09:15:37 -04:00
Kyle Spearrin
50f809d290 undo busy when syncing complete 2019-06-21 16:53:17 -04:00
Kyle Spearrin
39284b475d bottom border on picker and no padding on editor 2019-06-21 16:36:23 -04:00
Kyle Spearrin
d44950d46c bottom border for ios entry 2019-06-21 16:09:20 -04:00
Kyle Spearrin
e9b55bc207 fix tag issue on settings page 2019-06-21 10:01:35 -04:00
Kyle Spearrin
5470f08fee list-row-header-container bg color 2019-06-21 09:59:22 -04:00
Kyle Spearrin
f9a3bbd7fa remove green background 2019-06-21 09:47:10 -04:00
Kyle Spearrin
9d3165dc65 New grid layout structure for cipher view cell 2019-06-21 09:46:46 -04:00
Kyle Spearrin
3475d39f37 use bold colored headers 2019-06-20 17:26:42 -04:00
Kyle Spearrin
44782b1ddf header upper on iOS 2019-06-20 17:05:28 -04:00
Kyle Spearrin
dd8d5fd84c icon sizes for ios 2019-06-20 16:49:27 -04:00
Kyle Spearrin
e8f2d9d0dd list section border colors 2019-06-20 16:40:13 -04:00
Kyle Spearrin
a2de3b5d80 remove binding context from header viewcell 2019-06-20 16:34:17 -04:00
Kyle Spearrin
a2960c45bc accessible font sizes 2019-06-20 16:32:22 -04:00
Kyle Spearrin
dc91624597 some listview styling for iOS 2019-06-20 16:02:39 -04:00
Kyle Spearrin
223ec180fc disable spell check & prediction on certain fields 2019-06-19 16:03:55 -04:00
Kyle Spearrin
0116572fec show nested collections in groupings pages 2019-06-17 10:21:05 -04:00
Kyle Spearrin
5350e5385c version bump 2019-06-16 06:57:25 -04:00
Kyle Spearrin
8f18c4fd45 cleartextTrafficPermitted 2019-06-16 06:54:58 -04:00
Kyle Spearrin
8538fbabe5 dont link core lib 2019-06-15 22:50:54 -04:00
Kyle Spearrin
9367b34bbe more linking 2019-06-15 21:58:43 -04:00
Kyle Spearrin
a766044cb4 bump version 2019-06-15 21:13:12 -04:00
Kyle Spearrin
0eb385e49f revert com.android.settings from blacklist 2019-06-15 21:02:38 -04:00
Kyle Spearrin
e30136dace just check if !HasCiphers 2019-06-15 20:44:36 -04:00
Kyle Spearrin
c50dee479a android http client handler 2019-06-15 18:44:08 -04:00
Kyle Spearrin
58ef292fa7 null checks 2019-06-15 00:14:32 -04:00
Kyle Spearrin
61b728fea7 x86 builds as well 2019-06-14 23:32:58 -04:00
Kyle Spearrin
b782eeb839 fixes to 2fa page 2019-06-14 18:08:08 -04:00
Kyle Spearrin
77314d4b8d cleanup search page for ios 2019-06-14 17:40:21 -04:00
Kyle Spearrin
c79d1d24b3 add and more toolbar buttons for ios 2019-06-14 17:31:06 -04:00
Kyle Spearrin
5dbea8ca09 more options on generator and history page 2019-06-14 17:21:17 -04:00
Kyle Spearrin
09a1c17fb4 null checks 2019-06-14 16:53:01 -04:00
Kyle Spearrin
a0632bcac2 null checks 2019-06-14 16:22:56 -04:00
Kyle Spearrin
07d57ebe8c bump version 2019-06-14 08:46:04 -04:00
Kyle Spearrin
325c88018c more menu for ios 2019-06-14 08:45:28 -04:00
Kyle Spearrin
dcb1102746 crash fixes 2019-06-14 08:05:28 -04:00
Kyle Spearrin
636d3c02c4 catch errors 2019-06-13 20:41:24 -04:00
Kyle Spearrin
5b119ded17 x64 builds as well 2019-06-13 16:25:13 -04:00
Kyle Spearrin
f25ae870c5 hebrew fix 2019-06-13 16:07:08 -04:00
Kyle Spearrin
49673262e4 bump version and fix readme 2019-06-13 15:05:31 -04:00
vargbeaumont
3ed814c1f7 Update styles.xml (#537)
Fix black navigation bar on none Google ROMs.
2019-06-13 15:03:00 -04:00
Kyle Spearrin
8b858e5407 new hi-res icon for store 2019-06-13 14:47:05 -04:00
Kyle Spearrin
30145894b6 bump version 2019-06-13 14:11:12 -04:00
Kyle Spearrin
8df4c27203 handle some loading race conditions 2019-06-13 14:08:21 -04:00
Kyle Spearrin
28166f79a1 ACCESS_NETWORK_STATE permission 2019-06-13 12:02:36 -04:00
Kyle Spearrin
2fe67137c5 more fdroid build cleanup of google services 2019-06-13 10:06:21 -04:00
Kyle Spearrin
a6ea2de691 bump version 2019-06-13 10:06:21 -04:00
Kyle Spearrin
7ffcde002e small delay before calling LoadAsync 2019-06-13 10:06:21 -04:00
Kyle Spearrin
a3f66b8ab1 chmod keystore correct path 2019-06-13 10:06:21 -04:00
Kyle Spearrin
43cee53dc8 make sure totp copy isn't available if not premium 2019-06-13 10:06:21 -04:00
1194 changed files with 177516 additions and 91059 deletions

12
.config/dotnet-tools.json Normal file
View File

@@ -0,0 +1,12 @@
{
"version": 1,
"isRoot": true,
"tools": {
"dotnet-format": {
"version": "5.1.250801",
"commands": [
"dotnet-format"
]
}
}
}

View File

@@ -1,3 +1,113 @@
# EditorConfig is awesome: http://EditorConfig.org
# top-most EditorConfig file
root = true
# Don't use tabs for indentation.
[*]
indent_style = space
end_of_line = lf
# (Please don't specify an indent_size here; that has too many unintended consequences.)
# Code files
[*.{cs,csx,vb,vbx}]
indent_size = 4
insert_final_newline = true
charset = utf-8-bom
# 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
# 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_members
dotnet_naming_rule.private_members_with_underscore.style = underscore_prefix
dotnet_naming_rule.private_members_with_underscore.severity = suggestion
dotnet_naming_symbols.private_members.applicable_kinds = field
dotnet_naming_symbols.private_members.applicable_accessibilities = private
dotnet_naming_symbols.private_members.required_modifiers = readonly
dotnet_naming_style.underscore_prefix.capitalization = camel_case
dotnet_naming_style.underscore_prefix.required_prefix = _
dotnet_naming_style.underscore_prefix.required_suffix =
dotnet_naming_style.underscore_prefix.word_separator =
# 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 =
# 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
# All files
[*]
guidelines = 120
guidelines = 120

2
.git-blame-ignore-revs Normal file
View File

@@ -0,0 +1,2 @@
# .NET format https://github.com/bitwarden/mobile/pull/1738
04539af2a66668b6e85476d5cf318c9150ec4357

2
.gitattributes vendored
View File

@@ -1,7 +1,7 @@
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
* text=auto eol=lf
###############################################################################
# Set default behavior for command prompt diff.

81
.github/ISSUE_TEMPLATE/bug.yml vendored Normal file
View File

@@ -0,0 +1,81 @@
name: Bug Report
description: File a bug report
labels: [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: dropdown
id: os
attributes:
label: Operating System
description: What operating system are you seeing the problem on?
multiple: true
options:
- Android
- iOS
validations:
required: true
- type: input
id: os-version
attributes:
label: Operating System Version
description: What version of the operating system(s) are you seeing the problem on?
- type: input
id: device
attributes:
label: Device
description: Which device are you seeing the problem on?
placeholder: iPhone 12, Samsung Galaxy S10
- type: input
id: version
attributes:
label: Build Version
description: What version of our software are you running? (go to "Settings" → "About" in the app)
validations:
required: true
- type: checkboxes
id: beta
attributes:
label: Beta
options:
- label: Using a pre-release version of the application.

17
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,17 @@
blank_issues_enabled: false
contact_links:
- name: Report mobile autofill failure
url: https://docs.google.com/forms/d/e/1FAIpQLScMopHyN7KGJs8hW562VTzbIGL4KcFnx0wJcsW0GYE1BnPiGA/viewform
about: We are aware of some situations where the Bitwarden mobile app will not autofill information correctly. This is something the Bitwarden team is actively working on but need your help as a community and active Bitwarden users!
- 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.
- name: Bitwarden Community Forums
url: https://community.bitwarden.com
about: Please visit the community forums for general community discussion, support and the development roadmap.
- name: Customer Support
url: https://bitwarden.com/contact/
about: Please contact our customer support for account issues and general customer support.
- name: Security Issues
url: https://hackerone.com/bitwarden
about: We use HackerOne to manage security disclosures.

28
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,28 @@
## Type of change
- [ ] Bug fix
- [ ] New feature development
- [ ] Tech debt (refactoring, code cleanup, dependency upgrades, etc)
- [ ] Build/deploy pipeline (DevOps)
- [ ] Other
## Objective
<!--Describe what the purpose of this PR is. For example: what bug you're fixing or what new feature you're adding-->
## Code changes
<!--Explain the changes you've made to each file or major component. This should help the reviewer understand your changes-->
<!--Also refer to any related changes or PRs in other repositories-->
* **file.ext:** Description of what was changed and why
## Screenshots
<!--Required for any UI changes. Delete if not applicable-->
## Before you submit
- [ ] I have checked for formatting errors (`dotnet tool run dotnet-format --check`) (required)
- [ ] I have added **unit tests** where it makes sense to do so (encouraged but not required)
- [ ] This change requires a **documentation update** (notify the documentation team)
- [ ] This change has particular **deployment requirements** (notify the DevOps team)

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>method</key>
<string>ad-hoc</string>
<key>provisioningProfiles</key>
<dict>
<key>com.8bit.bitwarden</key>
<string>Ad hoc: Bitwarden 2021</string>
<key>com.8bit.bitwarden.autofill</key>
<string>Ad hoc: Autofill 2021</string>
<key>com.8bit.bitwarden.find-login-action-extension</key>
<string>Ad hoc: Extension 2021</string>
</dict>
</dict>
</plist>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>method</key>
<string>app-store</string>
<key>provisioningProfiles</key>
<dict>
<key>com.8bit.bitwarden</key>
<string>Dist: Bitwarden 2021</string>
<key>com.8bit.bitwarden.autofill</key>
<string>Dist: Autofill 2021</string>
<key>com.8bit.bitwarden.find-login-action-extension</key>
<string>Dist: Extension 2021</string>
<key>com.8bit.bitwarden.share-extension</key>
<string>Dist: Share Extension 2021</string>
</dict>
</dict>
</plist>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,3 @@
<EFBFBD>
 K<>Y#<23>(<28><><EFBFBD><EFBFBD>EI֐߄T?)l<><6C><EFBFBD><18><><10>"=<3D>|<7C>'e<><0E>m<EFBFBD>/~<7E><>' F<><46>><3E><><EFBFBD><EFBFBD>l<EFBFBD>b<EFBFBD>[<5B>+R<><52>iL<69><4C>"<22><><EFBFBD>~V:<3A><>p<EFBFBD>a<17>ڵel%8t<38><74><EFBFBD>y<<3C>n<EFBFBD><6E><EFBFBD>aU<61>w<16>JD<4A><44><1F><>We<57>9<EFBFBD><39><EFBFBD><EFBFBD><x8d<38>O<EFBFBD>j\<14>ד<EFBFBD><D793><EFBFBD>Vq<56><71>֋
Ǻ<EFBFBD>-<2D>#<23><><11><>]$<24>(<28>l,<2C>Br<42><02><>d<><64><EFBFBD>•a-<2D><><EFBFBD>:<3A><>:<3A><04>9b,!Em<02><19><>Qf<>D<EFBFBD>g<EFBFBD><06><0E>x(P<>ȡ~<7E>͹<EFBFBD><CDB9> <09><>[<06><>!:<3A>;f<><66>

Binary file not shown.

BIN
.github/secrets/play_creds.json.gpg vendored Normal file

Binary file not shown.

Binary file not shown.

670
.github/workflows/build.yml vendored Normal file
View File

@@ -0,0 +1,670 @@
---
name: Build
on:
push:
branches-ignore:
- 'l10n_master'
- 'gh-pages'
paths-ignore:
- '.github/workflows/**'
workflow_dispatch:
inputs: {}
jobs:
cloc:
name: CLOC
runs-on: ubuntu-20.04
steps:
- name: Checkout repo
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
- name: Set up CLOC
run: |
sudo apt-get update
sudo apt-get -y install cloc
- name: Print lines of code
run: cloc --vcs git --exclude-dir Resources,store,test,Properties --include-lang C#,XAML
setup:
name: Setup
runs-on: ubuntu-20.04
outputs:
rc_branch_exists: ${{ steps.branch-check.outputs.rc_branch_exists }}
hotfix_branch_exists: ${{ steps.branch-check.outputs.hotfix_branch_exists }}
steps:
- name: Checkout repo
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
- name: Check if special branches exist
id: branch-check
run: |
if [[ $(git ls-remote --heads origin rc) ]]; then
echo "::set-output name=rc_branch_exists::1"
else
echo "::set-output name=rc_branch_exists::0"
fi
if [[ $(git ls-remote --heads origin hotfix-rc) ]]; then
echo "::set-output name=hotfix_branch_exists::1"
else
echo "::set-output name=hotfix_branch_exists::0"
fi
shell: bash
android:
name: Android
runs-on: windows-2019
needs: setup
steps:
- name: Setup NuGet
uses: nuget/setup-nuget@b2bc17b761a1d88cab755a776c7922eb26eefbfa # v1.0.6
with:
nuget-version: 5.9.0
- name: Set up MSBuild
uses: microsoft/setup-msbuild@ab534842b4bdf384b8aaf93765dc6f721d9f5fab
- name: Print environment
run: |
nuget help | grep Version
msbuild -version
dotnet --info
echo "GitHub ref: $GITHUB_REF"
echo "GitHub event: $GITHUB_EVENT"
- name: Checkout repo
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
- name: Decrypt secrets
env:
DECRYPT_FILE_PASSWORD: ${{ secrets.DECRYPT_FILE_PASSWORD }}
run: |
mkdir -p ~/secrets
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output ./src/Android/app_play-keystore.jks ./.github/secrets/app_play-keystore.jks.gpg
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output ./src/Android/app_upload-keystore.jks ./.github/secrets/app_upload-keystore.jks.gpg
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output ./src/Android/google-services.json ./.github/secrets/google-services.json.gpg
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output $HOME/secrets/play_creds.json ./.github/secrets/play_creds.json.gpg
shell: bash
- name: Increment version
run: |
BUILD_NUMBER=$((3000 + $GITHUB_RUN_NUMBER))
echo "########################################"
echo "##### Setting Version Code $BUILD_NUMBER"
echo "########################################"
sed -i "s/android:versionCode=\"1\"/android:versionCode=\"$BUILD_NUMBER\"/" \
./src/Android/Properties/AndroidManifest.xml
shell: bash
- name: Restore packages
run: nuget restore
- name: Restore tools
run: dotnet tool restore
shell: pwsh
- name: Verify Format
run: dotnet tool run dotnet-format --check
shell: pwsh
- name: Run Core tests
run: dotnet test test/Core.Test/Core.Test.csproj
- name: Build Play Store publisher
run: dotnet build ./store/google/Publisher/Publisher.csproj -p:Configuration=Release
- name: Build for Play Store
run: |
$configuration = "Release";
Write-Output "########################################"
Write-Output "##### Build $configuration Configuration"
Write-Output "########################################"
msbuild "$($env:GITHUB_WORKSPACE + "/src/Android/Android.csproj")" "/p:Configuration=$configuration"
shell: pwsh
- name: Sign for Play Store
env:
PLAY_KEYSTORE_PASSWORD: ${{ secrets.PLAY_KEYSTORE_PASSWORD }}
UPLOAD_KEYSTORE_PASSWORD: ${{ secrets.UPLOAD_KEYSTORE_PASSWORD }}
run: |
$androidPath = $($env:GITHUB_WORKSPACE + "/src/Android/Android.csproj");
Write-Output "########################################"
Write-Output "##### Sign Google Play Bundle Release Configuration"
Write-Output "########################################"
msbuild "$($androidPath)" "/t:SignAndroidPackage" "/p:Configuration=Release" "/p:AndroidKeyStore=true" `
"/p:AndroidSigningKeyAlias=upload" "/p:AndroidSigningKeyPass=$($env:UPLOAD_KEYSTORE_PASSWORD)" `
"/p:AndroidSigningKeyStore=$("app_upload-keystore.jks")" `
"/p:AndroidSigningStorePass=$($env:UPLOAD_KEYSTORE_PASSWORD)" "/p:AndroidPackageFormat=aab" "/v:quiet"
Write-Output "########################################"
Write-Output "##### Copy Google Play Bundle to project root"
Write-Output "########################################"
$signedAabPath = $($env:GITHUB_WORKSPACE + "/src/Android/bin/Release/com.x8bit.bitwarden-Signed.aab");
$signedAabDestPath = $($env:GITHUB_WORKSPACE + "/com.x8bit.bitwarden.aab");
Copy-Item $signedAabPath $signedAabDestPath
Write-Output "########################################"
Write-Output "##### Sign APK Release Configuration"
Write-Output "########################################"
msbuild "$($androidPath)" "/t:SignAndroidPackage" "/p:Configuration=Release" "/p:AndroidKeyStore=true" `
"/p:AndroidSigningKeyAlias=bitwarden" "/p:AndroidSigningKeyPass=$($env:PLAY_KEYSTORE_PASSWORD)" `
"/p:AndroidSigningKeyStore=$("app_play-keystore.jks")" `
"/p:AndroidSigningStorePass=$($env:PLAY_KEYSTORE_PASSWORD)" "/v:quiet"
Write-Output "########################################"
Write-Output "##### Copy Release APK to project root"
Write-Output "########################################"
$signedApkPath = $($env:GITHUB_WORKSPACE + "/src/Android/bin/Release/com.x8bit.bitwarden-Signed.apk");
$signedApkDestPath = $($env:GITHUB_WORKSPACE + "/com.x8bit.bitwarden.apk");
Copy-Item $signedApkPath $signedApkDestPath
shell: pwsh
- name: Upload Play Store .aab artifact
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
with:
name: com.x8bit.bitwarden.aab
path: ./com.x8bit.bitwarden.aab
if-no-files-found: error
- name: Upload Play Store .apk artifact
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
with:
name: com.x8bit.bitwarden.apk
path: ./com.x8bit.bitwarden.apk
if-no-files-found: error
- name: Deploy to Play Store
if: |
(github.ref == 'refs/heads/master'
&& needs.setup.outputs.rc_branch_exists == 0
&& needs.setup.outputs.hotfix_branch_exists == 0)
|| (github.ref == 'refs/heads/rc' && needs.setup.outputs.hotfix_branch_exists == 0)
|| github.ref == 'refs/heads/hotfix-rc'
run: |
PUBLISHER_PATH="$GITHUB_WORKSPACE/store/google/Publisher/bin/Release/netcoreapp3.1/Publisher.dll"
CREDS_PATH="$HOME/secrets/play_creds.json"
AAB_PATH="$GITHUB_WORKSPACE/com.x8bit.bitwarden.aab"
TRACK="internal"
dotnet $PUBLISHER_PATH $CREDS_PATH $AAB_PATH $TRACK
shell: bash
f-droid:
name: F-Droid Build
runs-on: windows-2019
steps:
- name: Setup NuGet
uses: nuget/setup-nuget@b2bc17b761a1d88cab755a776c7922eb26eefbfa # v1.0.6
with:
nuget-version: 5.9.0
- name: Set up MSBuild
uses: microsoft/setup-msbuild@ab534842b4bdf384b8aaf93765dc6f721d9f5fab
- name: Print environment
run: |
nuget help | grep Version
msbuild -version
dotnet --info
echo "GitHub ref: $GITHUB_REF"
echo "GitHub event: $GITHUB_EVENT"
- name: Checkout repo
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
- name: Decrypt secrets
env:
DECRYPT_FILE_PASSWORD: ${{ secrets.DECRYPT_FILE_PASSWORD }}
run: |
mkdir -p ~/secrets
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output ./src/Android/app_fdroid-keystore.jks ./.github/secrets/app_fdroid-keystore.jks.gpg
shell: bash
- name: Increment version
run: |
BUILD_NUMBER=$((3000 + $GITHUB_RUN_NUMBER))
echo "########################################"
echo "##### Setting Version Code $BUILD_NUMBER"
echo "########################################"
sed -i "s/android:versionCode=\"1\"/android:versionCode=\"$BUILD_NUMBER\"/" \
./src/Android/Properties/AndroidManifest.xml
shell: bash
- name: Clean for F-Droid
run: |
$androidPath = $($env:GITHUB_WORKSPACE + "/src/Android/Android.csproj");
$appPath = $($env:GITHUB_WORKSPACE + "/src/App/App.csproj");
$corePath = $($env:GITHUB_WORKSPACE + "/src/Core/Core.csproj");
$androidManifest = $($env:GITHUB_WORKSPACE + "/src/Android/Properties/AndroidManifest.xml");
Write-Output "########################################"
Write-Output "##### Clean Android and App"
Write-Output "########################################"
msbuild "$($androidPath)" "/t:Clean" "/p:Configuration=FDroid"
msbuild "$($appPath)" "/t:Clean" "/p:Configuration=FDroid"
Write-Output "########################################"
Write-Output "##### Backup project files"
Write-Output "########################################"
Copy-Item $androidManifest $($androidManifest + ".original");
Copy-Item $androidPath $($androidPath + ".original");
Copy-Item $appPath $($appPath + ".original");
Write-Output "########################################"
Write-Output "##### Cleanup Android Manifest"
Write-Output "########################################"
$xml=New-Object XML;
$xml.Load($androidManifest);
$nsAndroid=New-Object System.Xml.XmlNamespaceManager($xml.NameTable);
$nsAndroid.AddNamespace("android", "http://schemas.android.com/apk/res/android");
$xml.Save($androidManifest);
Write-Output "########################################"
Write-Output "##### Uninstall from Android.csproj"
Write-Output "########################################"
$xml=New-Object XML;
$xml.Load($androidPath);
$ns=New-Object System.Xml.XmlNamespaceManager($xml.NameTable);
$ns.AddNamespace("ns", $xml.DocumentElement.NamespaceURI);
$firebaseNode=$xml.SelectSingleNode(`
"/ns:Project/ns:ItemGroup/ns:PackageReference[@Include='Xamarin.Firebase.Messaging']", $ns);
$firebaseNode.ParentNode.RemoveChild($firebaseNode);
$daggerNode=$xml.SelectSingleNode(`
"/ns:Project/ns:ItemGroup/ns:PackageReference[@Include='Xamarin.Google.Dagger']", $ns);
$daggerNode.ParentNode.RemoveChild($daggerNode);
$safetyNetNode=$xml.SelectSingleNode(`
"/ns:Project/ns:ItemGroup/ns:PackageReference[@Include='Xamarin.GooglePlayServices.SafetyNet']", $ns);
$safetyNetNode.ParentNode.RemoveChild($safetyNetNode);
$xml.Save($androidPath);
Write-Output "########################################"
Write-Output "##### Uninstall from Core.csproj"
Write-Output "########################################"
$xml=New-Object XML;
$xml.Load($corePath);
$appCenterNode=$xml.SelectSingleNode("/Project/ItemGroup/PackageReference[@Include='Microsoft.AppCenter.Crashes']");
$appCenterNode.ParentNode.RemoveChild($appCenterNode);
$xml.Save($corePath);
shell: pwsh
- name: Restore packages
run: nuget restore
- name: Build for F-Droid
run: |
$configuration = "FDroid";
Write-Output "########################################"
Write-Output "##### Build $configuration Configuration"
Write-Output "########################################"
msbuild "$($env:GITHUB_WORKSPACE + "/src/Android/Android.csproj")" "/p:Configuration=$configuration"
shell: pwsh
- name: Sign for F-Droid
env:
FDROID_KEYSTORE_PASSWORD: ${{ secrets.FDROID_KEYSTORE_PASSWORD }}
run: |
Write-Output "########################################"
Write-Output "##### Sign FDroid Configuration"
Write-Output "########################################"
msbuild "$($env:GITHUB_WORKSPACE + "/src/Android/Android.csproj")" `
"/t:SignAndroidPackage" "/p:Configuration=FDroid" "/p:AndroidKeyStore=true" `
"/p:AndroidSigningKeyAlias=bitwarden" "/p:AndroidSigningKeyPass=$($env:FDROID_KEYSTORE_PASSWORD)" `
"/p:AndroidSigningKeyStore=$("app_fdroid-keystore.jks")" `
"/p:AndroidSigningStorePass=$($env:FDROID_KEYSTORE_PASSWORD)" "/v:quiet"
Write-Output "########################################"
Write-Output "##### Copy FDroid apk to project root"
Write-Output "########################################"
$signedApkPath = $($env:GITHUB_WORKSPACE + "/src/Android/bin/FDroid/com.x8bit.bitwarden-Signed.apk");
$signedApkDestPath = $($env:GITHUB_WORKSPACE + "/com.x8bit.bitwarden-fdroid.apk");
Copy-Item $signedApkPath $signedApkDestPath
shell: pwsh
- name: Upload F-Droid .apk artifact
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
with:
name: com.x8bit.bitwarden-fdroid.apk
path: ./com.x8bit.bitwarden-fdroid.apk
if-no-files-found: error
ios:
name: Apple iOS
runs-on: macos-11
needs: setup
steps:
- name: Setup NuGet
uses: nuget/setup-nuget@b2bc17b761a1d88cab755a776c7922eb26eefbfa # v1.0.6
with:
nuget-version: 5.9.0
- name: Print environment
run: |
nuget help | grep Version
msbuild -version
dotnet --info
echo "GitHub ref: $GITHUB_REF"
echo "GitHub event: $GITHUB_EVENT"
- name: Checkout repo
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
- name: Login to Azure - Prod Subscription
uses: Azure/login@1f63701bf3e6892515f1b7ce2d2bf1708b46beaf
with:
creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }}
- name: Retrieve secrets
id: retrieve-secrets
uses: Azure/get-keyvault-secrets@b5c723b9ac7870c022b8c35befe620b7009b336f
with:
keyvault: "bitwarden-prod-kv"
secrets: "appcenter-ios-token"
- name: Decrypt secrets
env:
DECRYPT_FILE_PASSWORD: ${{ secrets.DECRYPT_FILE_PASSWORD }}
run: |
mkdir -p ~/secrets
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output $HOME/secrets/bitwarden-mobile-key.p12 ./.github/secrets/bitwarden-mobile-key.p12.gpg
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output $HOME/secrets/iphone-distribution-cert.p12 ./.github/secrets/iphone-distribution-cert.p12.gpg
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output $HOME/secrets/dist_autofill.mobileprovision ./.github/secrets/dist_autofill.mobileprovision.gpg
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output $HOME/secrets/dist_bitwarden.mobileprovision ./.github/secrets/dist_bitwarden.mobileprovision.gpg
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output $HOME/secrets/dist_extension.mobileprovision ./.github/secrets/dist_extension.mobileprovision.gpg
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output $HOME/secrets/dist_share_extension.mobileprovision \
./.github/secrets/dist_share_extension.mobileprovision.gpg
shell: bash
- name: Increment version
run: |
BUILD_NUMBER=$((100 + $GITHUB_RUN_NUMBER))
echo "########################################"
echo "##### Setting CFBundleVersion $BUILD_NUMBER"
echo "########################################"
perl -0777 -pi.bak -e 's/<key>CFBundleVersion<\/key>\s*<string>1<\/string>/<key>CFBundleVersion<\/key>\n\t<string>'"$BUILD_NUMBER"'<\/string>/' ./src/iOS/Info.plist
perl -0777 -pi.bak -e 's/<key>CFBundleVersion<\/key>\s*<string>1<\/string>/<key>CFBundleVersion<\/key>\n\t<string>'"$BUILD_NUMBER"'<\/string>/' ./src/iOS.Extension/Info.plist
perl -0777 -pi.bak -e 's/<key>CFBundleVersion<\/key>\s*<string>1<\/string>/<key>CFBundleVersion<\/key>\n\t<string>'"$BUILD_NUMBER"'<\/string>/' ./src/iOS.Autofill/Info.plist
perl -0777 -pi.bak -e 's/<key>CFBundleVersion<\/key>\s*<string>1<\/string>/<key>CFBundleVersion<\/key>\n\t<string>'"$BUILD_NUMBER"'<\/string>/' ./src/iOS.ShareExtension/Info.plist
shell: bash
- name: Update Entitlements
run: |
echo "########################################"
echo "##### Updating Entitlements"
echo "########################################"
perl -0777 -pi.bak -e 's/<key>aps-environment<\/key>\s*<string>development<\/string>/<key>aps-environment<\/key>\n\t<string>production<\/string>/' ./src/iOS/Entitlements.plist
shell: bash
- name: Set up Keychain
env:
KEYCHAIN_PASSWORD: ${{ secrets.IOS_KEYCHAIN_PASSWORD }}
MOBILE_KEY_PASSWORD: ${{ secrets.IOS_KEY_PASSWORD }}
DIST_CERT_PASSWORD: ${{ secrets.IOS_DIST_CERT_PASSWORD }}
run: |
security create-keychain -p $KEYCHAIN_PASSWORD build.keychain
security default-keychain -s build.keychain
security unlock-keychain -p $KEYCHAIN_PASSWORD build.keychain
security set-keychain-settings -lut 1200 build.keychain
security import ~/secrets/bitwarden-mobile-key.p12 -k build.keychain -P $MOBILE_KEY_PASSWORD \
-T /usr/bin/codesign -T /usr/bin/security
security import ~/secrets/iphone-distribution-cert.p12 -k build.keychain -P $DIST_CERT_PASSWORD \
-T /usr/bin/codesign -T /usr/bin/security
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k $KEYCHAIN_PASSWORD build.keychain
shell: bash
- name: Set up provisioning profiles
run: |
AUTOFILL_PROFILE_PATH=$HOME/secrets/dist_autofill.mobileprovision
BITWARDEN_PROFILE_PATH=$HOME/secrets/dist_bitwarden.mobileprovision
EXTENSION_PROFILE_PATH=$HOME/secrets/dist_extension.mobileprovision
SHARE_EXTENSION_PROFILE_PATH=$HOME/secrets/dist_share_extension.mobileprovision
PROFILES_DIR_PATH=$HOME/Library/MobileDevice/Provisioning\ Profiles
mkdir -p "$PROFILES_DIR_PATH"
AUTOFILL_UUID=$(grep UUID -A1 -a $AUTOFILL_PROFILE_PATH | grep -io "[-A-F0-9]\{36\}")
cp $AUTOFILL_PROFILE_PATH "$PROFILES_DIR_PATH/$AUTOFILL_UUID.mobileprovision"
BITWARDEN_UUID=$(grep UUID -A1 -a $BITWARDEN_PROFILE_PATH | grep -io "[-A-F0-9]\{36\}")
cp $BITWARDEN_PROFILE_PATH "$PROFILES_DIR_PATH/$BITWARDEN_UUID.mobileprovision"
EXTENSION_UUID=$(grep UUID -A1 -a $EXTENSION_PROFILE_PATH | grep -io "[-A-F0-9]\{36\}")
cp $EXTENSION_PROFILE_PATH "$PROFILES_DIR_PATH/$EXTENSION_UUID.mobileprovision"
SHARE_EXTENSION_UUID=$(grep UUID -A1 -a $SHARE_EXTENSION_PROFILE_PATH | grep -io "[-A-F0-9]\{36\}")
cp $SHARE_EXTENSION_PROFILE_PATH "$PROFILES_DIR_PATH/$SHARE_EXTENSION_UUID.mobileprovision"
shell: bash
- name: Restore packages
run: nuget restore
- name: Archive Build for App Store
run: |
$configuration = "AppStore";
$platform = "iPhone";
Write-Output "########################################"
Write-Output "##### Archive $configuration Configuration for $platform Platform"
Write-Output "########################################"
msbuild "$($env:GITHUB_WORKSPACE + "/src/iOS/iOS.csproj")" "/p:Platform=$platform" `
"/p:Configuration=$configuration" "/p:ArchiveOnBuild=true" "/t:`"Build`""
Write-Output "########################################"
Write-Output "##### Done"
Write-Output "########################################"
ls ~/Library/Developer/Xcode/Archives
shell: pwsh
- name: Export .ipa for App Store
run: |
EXPORT_OPTIONS_PATH="./.github/resources/export-options-app-store.plist"
ARCHIVE_PATH="$HOME/Library/Developer/Xcode/Archives/*/*.xcarchive"
EXPORT_PATH="./bitwarden-export"
xcodebuild -exportArchive -archivePath $ARCHIVE_PATH -exportPath $EXPORT_PATH \
-exportOptionsPlist $EXPORT_OPTIONS_PATH
shell: bash
- name: Copy all dSYMs files to upload
run: |
ARCHIVE_DSYMS_PATH="$HOME/Library/Developer/Xcode/Archives/*/*.xcarchive/dSYMs"
EXPORT_PATH="./bitwarden-export"
cp -r $ARCHIVE_DSYMS_PATH $EXPORT_PATH
shell: bash
- name: Upload App Store .ipa & dSYMs artifacts
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
with:
name: Bitwarden iOS
path: |
./bitwarden-export/Bitwarden.ipa
./bitwarden-export/dSYMs/*.*
if-no-files-found: error
- name: Install AppCenter CLI
if: |
(github.ref == 'refs/heads/master'
&& needs.setup.outputs.rc_branch_exists == 0
&& needs.setup.outputs.hotfix_branch_exists == 0)
|| (github.ref == 'refs/heads/rc' && needs.setup.outputs.hotfix_branch_exists == 0)
|| github.ref == 'refs/heads/hotfix-rc'
run: npm install -g appcenter-cli
- name: Upload dSYMs to App Center
if: |
(github.ref == 'refs/heads/master'
&& needs.setup.outputs.rc_branch_exists == 0
&& needs.setup.outputs.hotfix_branch_exists == 0)
|| (github.ref == 'refs/heads/rc' && needs.setup.outputs.hotfix_branch_exists == 0)
|| github.ref == 'refs/heads/hotfix-rc'
env:
APPCENTER_IOS_TOKEN: ${{ steps.retrieve-secrets.outputs.appcenter-ios-token }}
run: appcenter crashes upload-symbols -a bitwarden/bitwarden -s "./bitwarden-export/dSYMs" --token $APPCENTER_IOS_TOKEN
shell: bash
- name: Deploy to App Store
if: |
(github.ref == 'refs/heads/master'
&& needs.setup.outputs.rc_branch_exists == 0
&& needs.setup.outputs.hotfix_branch_exists == 0)
|| (github.ref == 'refs/heads/rc' && needs.setup.outputs.hotfix_branch_exists == 0)
|| github.ref == 'refs/heads/hotfix-rc'
env:
APPLE_ID_USERNAME: ${{ secrets.APPLE_ID_USERNAME }}
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
run: |
xcrun altool --upload-app --type ios --file "./bitwarden-export/Bitwarden.ipa" \
--username "$APPLE_ID_USERNAME" --password "$APPLE_ID_PASSWORD"
shell: bash
crowdin-push:
name: Crowdin Push
if: github.ref == 'refs/heads/master'
needs:
- android
- f-droid
- ios
runs-on: ubuntu-20.04
env:
_CROWDIN_PROJECT_ID: "269690"
steps:
- name: Checkout repo
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
- name: Login to Azure
uses: Azure/login@1f63701bf3e6892515f1b7ce2d2bf1708b46beaf
with:
creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }}
- name: Retrieve secrets
id: retrieve-secrets
uses: Azure/get-keyvault-secrets@b5c723b9ac7870c022b8c35befe620b7009b336f
with:
keyvault: "bitwarden-prod-kv"
secrets: "crowdin-api-token"
- name: Upload Sources
uses: crowdin/github-action@9237b4cb361788dfce63feb2e2f15c09e2fe7415
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }}
with:
config: crowdin.yml
crowdin_branch_name: master
upload_sources: true
upload_translations: false
check-failures:
name: Check for failures
if: always()
runs-on: ubuntu-20.04
needs:
- cloc
- android
- f-droid
- ios
- crowdin-push
steps:
- name: Check if any job failed
if: |
(github.ref == 'refs/heads/master')
|| (github.ref == 'refs/heads/rc')
|| (github.ref == 'refs/heads/hotfix-rc')
env:
CLOC_STATUS: ${{ needs.cloc.result }}
ANDROID_STATUS: ${{ needs.android.result }}
F_DROID_STATUS: ${{ needs.f-droid.result }}
IOS_STATUS: ${{ needs.ios.result }}
CROWDIN_PUSH_STATUS: ${{ needs.crowdin-push.result }}
run: |
if [ "$CLOC_STATUS" = "failure" ]; then
exit 1
elif [ "$ANDROID_STATUS" = "failure" ]; then
exit 1
elif [ "$F_DROID_STATUS" = "failure" ]; then
exit 1
elif [ "$IOS_STATUS" = "failure" ]; then
exit 1
elif [ "$CROWDIN_PUSH_STATUS" = "failure" ]; then
exit 1
fi
- name: Login to Azure - Prod Subscription
uses: Azure/login@1f63701bf3e6892515f1b7ce2d2bf1708b46beaf
if: failure()
with:
creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }}
- name: Retrieve secrets
id: retrieve-secrets
uses: Azure/get-keyvault-secrets@b5c723b9ac7870c022b8c35befe620b7009b336f
if: failure()
with:
keyvault: "bitwarden-prod-kv"
secrets: "devops-alerts-slack-webhook-url"
- name: Notify Slack on failure
uses: act10ns/slack@da3191ebe2e67f49b46880b4633f5591a96d1d33
if: failure()
env:
SLACK_WEBHOOK_URL: ${{ steps.retrieve-secrets.outputs.devops-alerts-slack-webhook-url }}
with:
status: ${{ job.status }}

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

@@ -0,0 +1,49 @@
---
name: Crowdin Sync
on:
workflow_dispatch:
inputs: {}
schedule:
- cron: '0 0 * * 5'
jobs:
crowdin-sync:
name: Autosync
runs-on: ubuntu-20.04
env:
_CROWDIN_PROJECT_ID: "269690"
steps:
- name: Checkout repo
uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
- name: Login to Azure
uses: Azure/login@77f1b2e3fb80c0e8645114159d17008b8a2e475a
with:
creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }}
- name: Retrieve secrets
id: retrieve-secrets
uses: Azure/get-keyvault-secrets@80ccd3fafe5662407cc2e55f202ee34bfff8c403
with:
keyvault: "bitwarden-prod-kv"
secrets: "crowdin-api-token"
- name: Download translations
uses: crowdin/github-action@e39093fd75daae7859c68eded4b43d42ec78d8ea
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }}
with:
config: crowdin.yml
crowdin_branch_name: master
upload_sources: false
upload_translations: false
download_translations: true
github_user_name: "github-actions"
github_user_email: "<>"
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"

16
.github/workflows/enforce-labels.yml vendored Normal file
View File

@@ -0,0 +1,16 @@
---
name: Enforce PR labels
on:
pull_request:
types: [labeled, unlabeled, opened, edited, synchronize]
jobs:
enforce-label:
name: EnforceLabel
runs-on: ubuntu-20.04
steps:
- name: Enforce Label
uses: yogevbd/enforce-label-action@8d1e1709b1011e6d90400a0e6cf7c0b77aa5efeb
with:
BANNED_LABELS: "hold"
BANNED_LABELS_DESCRIPTION: "PRs on hold cannot be merged"

159
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,159 @@
---
name: Release
on:
workflow_dispatch:
inputs:
release_type:
description: 'Release Options'
required: true
default: 'Initial Release'
type: choice
options:
- Initial Release
- Redeploy
- Dry Run
jobs:
release:
name: Create Release
runs-on: ubuntu-20.04
outputs:
branch-name: ${{ steps.branch.outputs.branch-name }}
steps:
- name: Branch check
if: github.event.inputs.release_type != 'Dry Run'
run: |
if [[ "$GITHUB_REF" != "refs/heads/rc" ]] && [[ "$GITHUB_REF" != "refs/heads/hotfix-rc" ]]; then
echo "==================================="
echo "[!] Can only release from the 'rc' or 'hotfix-rc' branches"
echo "==================================="
exit 1
fi
- name: Checkout repo
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 # v2.4.0
- name: Check Release Version
id: version
uses: bitwarden/gh-actions/release-version-check@8f055ef543c7433c967a1b9b04a0f230923233bb
with:
release-type: ${{ github.event.inputs.release_type }}
project-type: xamarin
file: src/Android/Properties/AndroidManifest.xml
- name: Get branch name
id: branch
run: |
BRANCH_NAME=$(basename ${{ github.ref }})
echo "::set-output name=branch-name::$BRANCH_NAME"
- name: Download all artifacts
uses: dawidd6/action-download-artifact@575b1e4167df67acf7e692af784566618b23c71e # v2.17.10
with:
workflow: build.yml
workflow_conclusion: success
branch: ${{ steps.branch.outputs.branch-name }}
- name: Prep Bitwarden iOS release asset
run: zip -r Bitwarden\ iOS.zip Bitwarden\ iOS
- name: Create release
if: github.event.inputs.release_type != 'Dry Run'
uses: ncipollo/release-action@40bb172bd05f266cf9ba4ff965cb61e9ee5f6d01 # v1.9.0
with:
artifacts: "./com.x8bit.bitwarden.aab/com.x8bit.bitwarden.aab,
./com.x8bit.bitwarden.apk/com.x8bit.bitwarden.apk,
./com.x8bit.bitwarden-fdroid.apk/com.x8bit.bitwarden-fdroid.apk,
./Bitwarden iOS.zip"
commit: ${{ github.sha }}
tag: v${{ steps.version.outputs.version }}
name: Version ${{ steps.version.outputs.version }}
body: "<insert release notes here>"
token: ${{ secrets.GITHUB_TOKEN }}
draft: true
f-droid:
name: F-Droid Release
runs-on: ubuntu-20.04
needs: release
steps:
- name: Checkout repo
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 # v2.4.0
- name: Download F-Droid .apk artifact
uses: dawidd6/action-download-artifact@575b1e4167df67acf7e692af784566618b23c71e # v2.17.10
with:
workflow: build.yml
workflow_conclusion: success
branch: ${{ needs.release.outputs.branch-name }}
name: com.x8bit.bitwarden-fdroid.apk
- name: Set up Node
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561 # v2.5.1
with:
node-version: '10.x'
- name: Set up F-Droid server
run: |
sudo apt-get -qq update
sudo apt-get -qqy install --no-install-recommends fdroidserver wget
- name: Set up Git credentials
env:
ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
run: |
git config --global credential.helper store
echo "https://${ACCESS_TOKEN}:x-oauth-basic@github.com" >> ~/.git-credentials
git config --global user.email "ci@bitwarden.com"
git config --global user.name "Bitwarden CI"
- name: Print environment
run: |
node --version
npm --version
git --version
echo "GitHub ref: $GITHUB_REF"
echo "GitHub event: $GITHUB_EVENT"
- name: Install Node dependencies
run: npm install
- name: Decrypt secrets
env:
DECRYPT_FILE_PASSWORD: ${{ secrets.DECRYPT_FILE_PASSWORD }}
run: |
mkdir -p ~/secrets
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output ./store/fdroid/keystore.jks ./.github/secrets/store_fdroid-keystore.jks.gpg
- name: Compile for F-Droid Store
env:
FDROID_STORE_KEYSTORE_PASSWORD: ${{ secrets.FDROID_STORE_KEYSTORE_PASSWORD }}
run: |
cd $GITHUB_WORKSPACE
mkdir dist
cp CNAME ./dist
cd store
chmod 600 fdroid/config.py fdroid/keystore.jks
mkdir -p temp/fdroid
TEMP_DIR="$GITHUB_WORKSPACE/store/temp/fdroid"
cd fdroid
echo "keypass=\"$FDROID_STORE_KEYSTORE_PASSWORD\"" >>config.py
echo "keystorepass=\"$FDROID_STORE_KEYSTORE_PASSWORD\"" >>config.py
echo "local_copy_dir=\"$TEMP_DIR\"" >>config.py
mkdir -p repo
mv $GITHUB_WORKSPACE/com.x8bit.bitwarden-fdroid.apk ./repo/
fdroid update
fdroid server update
cd ..
rm -rf temp/fdroid/archive
mv -v temp/fdroid ../dist
cd fdroid
cp index.html btn.png qr.png ../../dist/fdroid
cd $GITHUB_WORKSPACE
- name: Deploy to gh-pages
if: github.event.inputs.release_type != 'Dry Run'
run: npm run deploy

89
.github/workflows/version-bump.yml vendored Normal file
View File

@@ -0,0 +1,89 @@
---
name: Version Bump
on:
workflow_dispatch:
inputs:
version_number:
description: "New Version"
required: true
jobs:
bump_version:
name: "Create version_bump_${{ github.event.inputs.version_number }} branch"
runs-on: ubuntu-20.04
steps:
- name: Checkout Branch
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Create Version Branch
run: |
git switch -c version_bump_${{ github.event.inputs.version_number }}
git push -u origin version_bump_${{ github.event.inputs.version_number }}
- name: Checkout Version Branch
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
with:
ref: version_bump_${{ github.event.inputs.version_number }}
- name: Bump Version - Android XML
uses: bitwarden/gh-actions/version-bump@03ad9a873c39cdc95dd8d77dbbda67f84db43945
with:
version: ${{ github.event.inputs.version_number }}
file_path: "./src/Android/Properties/AndroidManifest.xml"
- name: Bump Version - iOS.Autofill
uses: bitwarden/gh-actions/version-bump@03ad9a873c39cdc95dd8d77dbbda67f84db43945
with:
version: ${{ github.event.inputs.version_number }}
file_path: "./src/iOS.Autofill/Info.plist"
- name: Bump Version - iOS.Extension
uses: bitwarden/gh-actions/version-bump@03ad9a873c39cdc95dd8d77dbbda67f84db43945
with:
version: ${{ github.event.inputs.version_number }}
file_path: "./src/iOS.Extension/Info.plist"
- name: Bump Version - iOS.ShareExtension
uses: bitwarden/gh-actions/version-bump@03ad9a873c39cdc95dd8d77dbbda67f84db43945
with:
version: ${{ github.event.inputs.version_number }}
file_path: "./src/iOS.ShareExtension/Info.plist"
- name: Bump Version - iOS
uses: bitwarden/gh-actions/version-bump@03ad9a873c39cdc95dd8d77dbbda67f84db43945
with:
version: ${{ github.event.inputs.version_number }}
file_path: "./src/iOS/Info.plist"
- name: Commit files
run: |
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
git commit -m "Bumped version to ${{ github.event.inputs.version_number }}" -a
- name: Push changes
run: git push -u origin version_bump_${{ github.event.inputs.version_number }}
- name: Create Version PR
env:
PR_BRANCH: "version_bump_${{ github.event.inputs.version_number }}"
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
BASE_BRANCH: master
TITLE: "Bump version to ${{ github.event.inputs.version_number }}"
run: |
gh pr create --title "$TITLE" \
--base "$BASE" \
--head "$PR_BRANCH" \
--label "version update" \
--label "automated pr" \
--body "
## Type of change
- [ ] Bug fix
- [ ] New feature development
- [ ] Tech debt (refactoring, code cleanup, dependency upgrades, etc)
- [ ] Build/deploy pipeline (DevOps)
- [X] Other
## Objective
Automated version bump to ${{ github.event.inputs.version_number }}"

11
.github/workflows/workflow-linter.yml vendored Normal file
View File

@@ -0,0 +1,11 @@
---
name: Workflow Linter
on:
pull_request:
paths:
- .github/workflows/**
jobs:
call-workflow:
uses: bitwarden/gh-actions/.github/workflows/workflow-linter.yml@master

20
.gitignore vendored
View File

@@ -1,15 +1,28 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# Visual Studio (>=2015) project-specific, machine local files
.vs/
# JetBrains Rider project-specific, machine local files
.idea
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# ignore Xamarin.Android Resource.Designer.cs files
**/*.Droid/**/[Rr]esource.[Dd]esigner.cs
**/*.Android/**/[Rr]esource.[Dd]esigner.cs
**/Android/**/[Rr]esource.[Dd]esigner.cs
**/Droid/**/[Rr]esource.[Dd]esigner.cs
# Xamarin Components
Components/
# Build results
[Dd]ebug/
[Dd]ebugPublic/
@@ -22,9 +35,6 @@ bld/
[Bb]in/
[Oo]bj/
# Visual Studo 2015 cache/options directory
.vs/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*

View File

@@ -1,4 +1,31 @@
Code contributions are welcome! Please commit any pull requests against the `master` branch.
# How to Contribute
Contributions of all kinds are welcome!
Please visit our [Community Forums](https://community.bitwarden.com/) for general community discussion and the development roadmap.
Here is how you can get involved:
* **Request a new feature:** Go to the [Feature Requests category](https://community.bitwarden.com/c/feature-requests/) of the Community Forums. Please search existing feature requests before making a new one
* **Write code for a new feature:** Make a new post in the [Github Contributions category](https://community.bitwarden.com/c/github-contributions/) of the Community Forums. Include a description of your proposed contribution, screeshots, and links to any relevant feature requests. This helps get feedback from the community and Bitwarden team members before you start writing code
* **Report a bug or submit a bugfix:** Use Github issues and pull requests
* **Write documentation:** Submit a pull request to the [Bitwarden help repository](https://github.com/bitwarden/help)
* **Help other users:** Go to the [Ask the Bitwarden Community category](https://community.bitwarden.com/c/support/) on the Community Forums
* **Translate:** See the localization (i10n) section below
## Contributor Agreement
Please sign the [Contributor Agreement](https://cla-assistant.io/bitwarden/mobile) if you intend on contributing to any Github repository. Pull requests cannot be accepted and merged unless the author has signed the Contributor Agreement.
## Pull Request Guidelines
* commit any pull requests against the `master` branch
* include a link to your Community Forums post
# Localization (l10n)
@@ -8,6 +35,6 @@ We use a translation tool called [Crowdin](https://crowdin.com) to help manage o
If you are interested in helping translate the Bitwarden mobile app into another language (or make a translation correction), please register an account at Crowdin and join our project here: https://crowdin.com/project/bitwarden-mobile
If the language that you are interested in translating is not already listed, create a new account on Crowdin, join the project, and contact the project owner (https://crowdin.com/profile/kspearrin).
If the language that you are interested in translating is not already listed, create a new account on Crowdin, join the project, and contact the project owner (https://crowdin.com/profile/dwbit).
You can read Crowdin's getting started guide for translators here: https://support.crowdin.com/crowdin-intro/

View File

@@ -1,5 +0,0 @@
<!--
Please do not submit feature requests. The [Community Forums][1] has a
section for submitting, voting for, and discussing product feature requests.
[1]: https://community.bitwarden.com
-->

View File

@@ -1,4 +1,4 @@
[![appveyor build](https://ci.appveyor.com/api/projects/status/github/bitwarden/mobile?branch=master&svg=true)](https://ci.appveyor.com/project/bitwarden/mobile)
[![Github Workflow build on master](https://github.com/bitwarden/mobile/actions/workflows/build.yml/badge.svg?branch=master)](https://github.com/bitwarden/mobile/actions/workflows/build.yml?query=branch:master)
[![Crowdin](https://d322cqt584bo4o.cloudfront.net/bitwarden-mobile/localized.svg)](https://crowdin.com/project/bitwarden-mobile)
[![Join the chat at https://gitter.im/bitwarden/Lobby](https://badges.gitter.im/bitwarden/Lobby.svg)](https://gitter.im/bitwarden/Lobby)
@@ -8,7 +8,7 @@
The Bitwarden mobile application is written in C# with Xamarin Android, Xamarin iOS, and Xamarin Forms.
<img src="https://raw.githubusercontent.com/bitwarden/brand/master/screenshots/mobile-android.png" alt="" width="300" height="533" /> <img src="https://raw.githubusercontent.com/bitwarden/brand/master/screenshots/mobile-ios.png" alt="" width="300" height="533" />
<img src="https://raw.githubusercontent.com/bitwarden/brand/master/screenshots/mobile-android-myvault.png" alt="" width="325" height="650" /> <img src="https://raw.githubusercontent.com/bitwarden/brand/master/screenshots/mobile-ios-myvault.png" alt="" width="300" height="650" />
# Build/Run
@@ -23,9 +23,33 @@ The Bitwarden mobile application is written in C# with Xamarin Android, Xamarin
- Restore the nuget packages.
- Build and run the app.
# We're Hiring!
Interested in contributing in a big way? Consider joining our team! We're hiring for many positions. Please take a look at our [Careers page](https://bitwarden.com/careers/) to see what opportunities are currently open as well as what it's like to work at Bitwarden.
# Contribute
Code contributions are welcome! Visual Studio with Xamarin is required to work on this project. Please commit any pull requests against the `master` branch.
Learn more about how to contribute by reading the [`CONTRIBUTING.md`](CONTRIBUTING.md) file.
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.
### Dotnet-format
We recently migrated to using dotnet-format as code formatter. All previous branches will need to updated to avoid large merge conflicts using the following steps:
1. Check out your local Branch
2. Run `git merge e0efcfbe45b2a27c73e9593bfd7a71fad2aa7a35`
3. Resolve any merge conflicts, commit.
4. Run `dotnet tool run dotnet-format`
5. Commit
6. Run `git merge -Xours 04539af2a66668b6e85476d5cf318c9150ec4357`
7. Push
#### Git blame
We also recommend that you configure git to ignore the prettier revision using:
```bash
git config blame.ignoreRevsFile .git-blame-ignore-revs
```

View File

@@ -1,39 +1,11 @@
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
notify us. 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).
# In-scope
- Security issues in any current release of Bitwarden. This includes the web vault, browser extension,
and mobile apps (iOS and Android). Product downloads are available at https://bitwarden.com. Source
code is available at https://github.com/bitwarden.
# Exclusions
The following bug classes are out-of scope:
- Bugs that are already reported on any of Bitwarden's issue trackers (https://github.com/bitwarden),
or that we already know of. Note that some of our issue tracking is private.
- Issues in an upstream software dependency (ex: Xamarin, ASP.NET) which are already reported to the
upstream maintainer.
- Attacks requiring physical access to a user's device.
- Self-XSS
- Issues related to software or protocols not under Bitwarden's control
- Vulnerabilities in outdated versions of Bitwarden
- Missing security best practices that do not directly lead to a vulnerability
- Issues that do not have any impact on the general public
- 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:
@@ -42,4 +14,8 @@ While researching, we'd like to ask you to refrain from:
- 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.
Thank you for helping keep Bitwarden and our users safe!

View File

@@ -1,143 +0,0 @@
image:
- Visual Studio 2017
- Ubuntu1804
branches:
except:
- l10n_master
- gh-pages
configuration: Release
stack: node 10
init:
- sh: |
if [ "${DEBUG_SSH}" == "true" ]
then
curl -sflL 'https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-ssh.sh' | bash -e -
fi
- ps: |
if($isWindows -and $env:DEBUG_RDP -eq "true") {
iex ((new-object net.webclient).DownloadString(`
'https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
}
- ps: |
if($env:APPVEYOR_REPO_TAG -eq "true") {
$tagName = $env:APPVEYOR_REPO_TAG_NAME.TrimStart("v")
$env:RELEASE_NAME = "Version ${tagName}"
}
install:
- sh: |
curl -sflL 'https://raw.githubusercontent.com/appveyor/secure-file/master/install.sh' | bash -e -
./appveyor-tools/secure-file -decrypt ./store/fdroid/keystore.jks.enc -secret $FDROID_KEYSTORE_ENC_PASSWORD
- sh: npm install
- sh: |
sudo apt-get -qq update
sudo apt-get -qqy install --no-install-recommends fdroidserver wget
- sh: |
if [ "${APPVEYOR_REPO_TAG}" == "true" -a "${GH_TOKEN}" != "" ]
then
git config --global credential.helper store
echo "https://${GH_TOKEN}:x-oauth-basic@github.com" >> ~/.git-credentials
git config --global user.email "ci@bitwarden.com"
git config --global user.name "Bitwarden CI"
fi
- cmd: choco install cloc --no-progress
- cmd: "cloc --vcs git --exclude-dir Resources,store,test,Properties --include-lang C#,XAML"
#- cmd: appveyor DownloadFile https://dist.nuget.org/win-x86-commandline/latest/nuget.exe
#- cmd: appveyor DownloadFile https://aka.ms/vs/15/release/vs_community.exe
#- cmd: vs_community.exe update --wait --quiet --norestart --installPath "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community"
#- cmd: ps: .\src\Android\update-android.ps1
before_build:
- ps: |
if($isWindows) {
nuget restore
if($env:KEYSTORE_DEC_SECRET -or $env:GOOGLE_SERVICES_DEC_SECRET -or $env:PLAY_DEC_SECRET) {
nuget install secure-file -ExcludeVersion
}
if($env:GOOGLE_SERVICES_DEC_SECRET) {
secure-file\tools\secure-file -decrypt src\Android\google-services.json.enc `
-secret $env:GOOGLE_SERVICES_DEC_SECRET
}
}
build_script:
- sh: |
if [ "${APPVEYOR_REPO_TAG}" == "true" ]
then
mkdir dist
cp CNAME ./dist
cd store
chmod 600 fdroid/config.py keystore.jks
mkdir -p temp/fdroid
TEMP_DIR="$APPVEYOR_BUILD_FOLDER/store/temp/fdroid"
cd fdroid
echo "keypass=\"$FDROID_KEYSTORE_PASSWORD\"" >>config.py
echo "keystorepass=\"$FDROID_KEYSTORE_PASSWORD\"" >>config.py
echo "local_copy_dir=\"$TEMP_DIR\"" >>config.py
mkdir -p repo
curl -Lo repo/com.x8bit.bitwarden-fdroid.apk \
https://github.com/bitwarden/mobile/releases/download/$APPVEYOR_REPO_TAG_NAME/com.x8bit.bitwarden-fdroid.apk
fdroid update
fdroid server update
cd ..
rm -rf temp/fdroid/archive
mv -v temp/fdroid ../dist
cd fdroid
cp index.html btn.png qr.png ../../dist/fdroid
cd $APPVEYOR_BUILD_FOLDER
fi
- ps: |
if($isWindows -and $env:KEYSTORE_DEC_SECRET) {
msbuild bitwarden-mobile.sln `
"/logger:C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" `
"/p:Configuration=Release"
.\src\Android\ci-build-apks.ps1
Push-AppveyorArtifact .\com.x8bit.bitwarden.apk
Push-AppveyorArtifact .\com.x8bit.bitwarden-fdroid.apk
}
on_success:
- sh: |
if [ "${APPVEYOR_REPO_TAG}" == "true" -a "${GH_TOKEN}" != "" ]
then
npm run deploy
fi
- ps: |
if($isWindows -and $env:PLAY_DEC_SECRET) {
secure-file\tools\secure-file -decrypt store\google\Publisher\play_creds.json.enc -secret $env:PLAY_DEC_SECRET
cd store\google\Publisher\bin\Release\netcoreapp2.0
dotnet Publisher.dll `
$env:APPVEYOR_BUILD_FOLDER\store\google\Publisher\play_creds.json `
$env:APPVEYOR_BUILD_FOLDER\com.x8bit.bitwarden.apk `
alpha
cd $env:APPVEYOR_BUILD_FOLDER
}
on_finish:
- sh: |
if [ "${DEBUG_SSH}" == "true" ]
then
export APPVEYOR_SSH_BLOCK=true
curl -sflL 'https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-ssh.sh' | bash -e -
fi
- ps: |
if($isWindows -and $env:DEBUG_RDP -eq "true") {
$blockRdp = $true
iex ((new-object net.webclient).DownloadString(`
'https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
}
deploy:
tag: $(APPVEYOR_REPO_TAG_NAME)
release: $(RELEASE_NAME)
provider: GitHub
auth_token: $(GH_TOKEN)
artifact: /.*/
force_update: true
on:
branch: master
APPVEYOR_REPO_TAG: true

View File

@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28307.539
# Visual Studio Version 16
VisualStudioVersion = 16.0.29009.5
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Android", "src\Android\Android.csproj", "{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}"
EndProject
@@ -21,8 +21,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "google", "google", "{2E3996
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{76690DFB-B7F4-4781-83E4-113FDC450AFE}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
.gitignore = .gitignore
appveyor.yml = appveyor.yml
.github\workflows\build.yml = .github\workflows\build.yml
CONTRIBUTING.md = CONTRIBUTING.md
crowdin.yml = crowdin.yml
README.md = README.md
@@ -35,6 +36,16 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.Core", "src\iOS.Core\iO
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS", "src\iOS\iOS.csproj", "{599E0201-420A-4C3E-A7BA-5349F72E0B15}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.Extension", "src\iOS.Extension\iOS.Extension.csproj", "{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common", "test\Common\Common.csproj", "{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core.Test", "test\Core.Test\Core.Test.csproj", "{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.ShareExtension", "src\iOS.ShareExtension\iOS.ShareExtension.csproj", "{F8C3F648-EA5A-4719-8005-85D1690B1655}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.Autofill", "src\iOS.Autofill\iOS.Autofill.csproj", "{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Ad-Hoc|Any CPU = Ad-Hoc|Any CPU
@@ -99,24 +110,24 @@ Global
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Release|iPhoneSimulator.Deploy.0 = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|Any CPU.Deploy.0 = Debug|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|iPhone.Deploy.0 = Debug|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|iPhoneSimulator.Deploy.0 = Debug|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|Any CPU.Deploy.0 = Debug|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|iPhone.Build.0 = Debug|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|iPhone.Deploy.0 = Debug|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|iPhoneSimulator.Deploy.0 = Debug|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|Any CPU.Deploy.0 = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|iPhone.Deploy.0 = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|iPhoneSimulator.Deploy.0 = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|Any CPU.Build.0 = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|Any CPU.Deploy.0 = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|iPhone.ActiveCfg = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|iPhone.Build.0 = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|iPhone.Deploy.0 = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|iPhoneSimulator.Deploy.0 = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
@@ -141,18 +152,18 @@ Global
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Release|iPhoneSimulator.Deploy.0 = Release|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.AppStore|iPhone.Build.0 = Debug|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.AppStore|Any CPU.Build.0 = Release|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.AppStore|iPhone.ActiveCfg = Release|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.AppStore|iPhone.Build.0 = Release|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Debug|iPhone.ActiveCfg = Debug|Any CPU
@@ -231,24 +242,24 @@ Global
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Release|iPhone.Build.0 = Release|Any CPU
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|Any CPU.ActiveCfg = FDroid|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|Any CPU.Build.0 = FDroid|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|iPhone.ActiveCfg = FDroid|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|iPhone.Build.0 = FDroid|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|iPhoneSimulator.ActiveCfg = FDroid|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|iPhoneSimulator.Build.0 = FDroid|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|Any CPU.ActiveCfg = FDroid|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|Any CPU.Build.0 = FDroid|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|iPhone.ActiveCfg = FDroid|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|iPhone.Build.0 = FDroid|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|iPhoneSimulator.ActiveCfg = FDroid|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|iPhoneSimulator.Build.0 = FDroid|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|Any CPU.Build.0 = Ad-Hoc|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|Any CPU.ActiveCfg = AppStore|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|Any CPU.Build.0 = AppStore|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|iPhone.ActiveCfg = AppStore|iPhone
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|iPhone.Build.0 = AppStore|iPhone
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|iPhone.Build.0 = Debug|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|iPhone.ActiveCfg = Debug|iPhone
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|iPhone.Build.0 = Debug|iPhone
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
{E71F3053-056C-4381-9638-048ED73BDFF6}.FDroid|Any CPU.ActiveCfg = FDroid|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.FDroid|Any CPU.Build.0 = FDroid|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.FDroid|iPhone.ActiveCfg = FDroid|Any CPU
@@ -274,6 +285,7 @@ Global
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Debug|Any CPU.ActiveCfg = Debug|iPhone
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Debug|iPhone.ActiveCfg = Debug|iPhone
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Debug|iPhone.Build.0 = Debug|iPhone
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Debug|iPhone.Deploy.0 = Debug|iPhone
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.FDroid|Any CPU.ActiveCfg = FDroid|iPhone
@@ -286,6 +298,154 @@ Global
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Release|iPhone.Build.0 = Release|iPhone
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhone
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Ad-Hoc|Any CPU.Build.0 = Ad-Hoc|iPhone
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.AppStore|Any CPU.ActiveCfg = AppStore|iPhone
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.AppStore|Any CPU.Build.0 = AppStore|iPhone
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.AppStore|iPhone.ActiveCfg = AppStore|iPhone
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.AppStore|iPhone.Build.0 = AppStore|iPhone
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Debug|Any CPU.ActiveCfg = Debug|iPhone
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Debug|iPhone.ActiveCfg = Debug|iPhone
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Debug|iPhone.Build.0 = Debug|iPhone
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Debug|iPhone.Deploy.0 = Debug|iPhone
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.FDroid|Any CPU.ActiveCfg = Release|iPhone
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.FDroid|Any CPU.Build.0 = Release|iPhone
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.FDroid|iPhone.ActiveCfg = Release|iPhone
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.FDroid|iPhone.Build.0 = Release|iPhone
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.FDroid|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.FDroid|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Release|Any CPU.ActiveCfg = Release|iPhone
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Release|iPhone.ActiveCfg = Release|iPhone
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Release|iPhone.Build.0 = Release|iPhone
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.AppStore|Any CPU.Build.0 = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.AppStore|iPhone.ActiveCfg = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.AppStore|iPhone.Build.0 = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Debug|iPhone.Build.0 = Debug|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.FDroid|Any CPU.ActiveCfg = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.FDroid|Any CPU.Build.0 = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.FDroid|iPhone.ActiveCfg = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.FDroid|iPhone.Build.0 = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.FDroid|iPhoneSimulator.ActiveCfg = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.FDroid|iPhoneSimulator.Build.0 = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Release|Any CPU.Build.0 = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Release|iPhone.ActiveCfg = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Release|iPhone.Build.0 = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.AppStore|Any CPU.Build.0 = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.AppStore|iPhone.ActiveCfg = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.AppStore|iPhone.Build.0 = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Debug|iPhone.Build.0 = Debug|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.FDroid|Any CPU.ActiveCfg = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.FDroid|Any CPU.Build.0 = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.FDroid|iPhone.ActiveCfg = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.FDroid|iPhone.Build.0 = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.FDroid|iPhoneSimulator.ActiveCfg = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.FDroid|iPhoneSimulator.Build.0 = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Release|Any CPU.Build.0 = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Release|iPhone.ActiveCfg = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Release|iPhone.Build.0 = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Ad-Hoc|Any CPU.ActiveCfg = Debug|iPhoneSimulator
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Ad-Hoc|Any CPU.Build.0 = Debug|iPhoneSimulator
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Ad-Hoc|iPhone.ActiveCfg = Release|iPhone
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Ad-Hoc|iPhone.Build.0 = Release|iPhone
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
{F8C3F648-EA5A-4719-8005-85D1690B1655}.AppStore|Any CPU.ActiveCfg = Debug|iPhoneSimulator
{F8C3F648-EA5A-4719-8005-85D1690B1655}.AppStore|Any CPU.Build.0 = Debug|iPhoneSimulator
{F8C3F648-EA5A-4719-8005-85D1690B1655}.AppStore|iPhone.ActiveCfg = Release|iPhone
{F8C3F648-EA5A-4719-8005-85D1690B1655}.AppStore|iPhone.Build.0 = Release|iPhone
{F8C3F648-EA5A-4719-8005-85D1690B1655}.AppStore|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
{F8C3F648-EA5A-4719-8005-85D1690B1655}.AppStore|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Debug|Any CPU.Build.0 = Debug|iPhoneSimulator
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Debug|iPhone.ActiveCfg = Debug|iPhone
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Debug|iPhone.Build.0 = Debug|iPhone
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
{F8C3F648-EA5A-4719-8005-85D1690B1655}.FDroid|Any CPU.ActiveCfg = Debug|iPhoneSimulator
{F8C3F648-EA5A-4719-8005-85D1690B1655}.FDroid|Any CPU.Build.0 = Debug|iPhoneSimulator
{F8C3F648-EA5A-4719-8005-85D1690B1655}.FDroid|iPhone.ActiveCfg = Release|iPhone
{F8C3F648-EA5A-4719-8005-85D1690B1655}.FDroid|iPhone.Build.0 = Release|iPhone
{F8C3F648-EA5A-4719-8005-85D1690B1655}.FDroid|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
{F8C3F648-EA5A-4719-8005-85D1690B1655}.FDroid|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Release|Any CPU.ActiveCfg = Release|iPhone
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Release|Any CPU.Build.0 = Release|iPhone
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Release|iPhone.ActiveCfg = Release|iPhone
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Release|iPhone.Build.0 = Release|iPhone
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Ad-Hoc|Any CPU.Build.0 = Ad-Hoc|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.AppStore|Any CPU.ActiveCfg = AppStore|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.AppStore|Any CPU.Build.0 = AppStore|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.AppStore|iPhone.ActiveCfg = AppStore|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.AppStore|iPhone.Build.0 = AppStore|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Debug|Any CPU.ActiveCfg = Debug|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Debug|iPhone.ActiveCfg = Debug|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Debug|iPhone.Build.0 = Debug|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Debug|iPhone.Deploy.0 = Debug|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.FDroid|Any CPU.ActiveCfg = Release|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.FDroid|Any CPU.Build.0 = Release|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.FDroid|iPhone.ActiveCfg = Release|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.FDroid|iPhone.Build.0 = Release|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.FDroid|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.FDroid|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Release|Any CPU.ActiveCfg = Release|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Release|iPhone.ActiveCfg = Release|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Release|iPhone.Build.0 = Release|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -299,6 +459,11 @@ Global
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D} = {2E399654-26A2-46F6-B9CA-1B496A3F370A}
{E71F3053-056C-4381-9638-048ED73BDFF6} = {D10CA4A9-F866-40E1-B658-F69051236C71}
{599E0201-420A-4C3E-A7BA-5349F72E0B15} = {D10CA4A9-F866-40E1-B658-F69051236C71}
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545} = {D10CA4A9-F866-40E1-B658-F69051236C71}
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39} = {8904C536-C67D-420F-9971-51B26574C3AA}
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0} = {8904C536-C67D-420F-9971-51B26574C3AA}
{F8C3F648-EA5A-4719-8005-85D1690B1655} = {D10CA4A9-F866-40E1-B658-F69051236C71}
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A} = {D10CA4A9-F866-40E1-B658-F69051236C71}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {7D436EA3-8B7E-45D2-8D14-0730BD2E0410}

View File

@@ -1,5 +1,9 @@
project_id_env: _CROWDIN_PROJECT_ID
api_token_env: CROWDIN_API_TOKEN
preserve_hierarchy: true
files:
- source: /src/App/Resources/AppResources.resx
dest: /src/App/Resources/%original_file_name%
translation: /src/App/Resources/AppResources.%two_letters_code%.resx
update_option: update_as_unapproved
languages_mapping:
@@ -9,7 +13,9 @@ files:
pt-PT: pt-PT
pt-BR: pt-BR
en-GB: en-GB
en-IN: en-IN
- source: /store/apple/en/copy.resx
dest: /store/apple/en/%original_file_name%
translation: /store/apple/%two_letters_code%/copy.resx
update_option: update_as_unapproved
languages_mapping:
@@ -19,7 +25,9 @@ files:
pt-PT: pt-PT
pt-BR: pt-BR
en-GB: en-GB
en-IN: en-IN
- source: /store/google/en/copy.resx
dest: /store/google/en/%original_file_name%
translation: /store/google/%two_letters_code%/copy.resx
update_option: update_as_unapproved
languages_mapping:
@@ -29,3 +37,4 @@ files:
pt-BR: pt-BR
pt-PT: pt-PT
en-GB: en-GB
en-IN: en-IN

712
package-lock.json generated
View File

@@ -1,8 +1,468 @@
{
"name": "bitwarden-fdroid",
"name": "bitwarden-mobile",
"version": "0.0.0",
"lockfileVersion": 1,
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "bitwarden-mobile",
"version": "0.0.0",
"devDependencies": {
"gh-pages": "^3.2.3"
}
},
"node_modules/array-union": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
"integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
"dev": true,
"dependencies": {
"array-uniq": "^1.0.1"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/array-uniq": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
"integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/async": {
"version": "2.6.3",
"resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
"integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
"dev": true,
"dependencies": {
"lodash": "^4.17.14"
}
},
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
},
"node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"node_modules/commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"dev": true
},
"node_modules/commondir": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
"integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
"dev": true
},
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
"dev": true
},
"node_modules/email-addresses": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-3.1.0.tgz",
"integrity": "sha512-k0/r7GrWVL32kZlGwfPNgB2Y/mMXVTq/decgLczm/j34whdaspNrZO8CnXPf1laaHxI6ptUlsnAxN+UAPw+fzg==",
"dev": true
},
"node_modules/escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"dev": true,
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/filename-reserved-regex": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz",
"integrity": "sha1-q/c9+rc10EVECr/qLZHzieu/oik=",
"dev": true,
"engines": {
"node": ">=4"
}
},
"node_modules/filenamify": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz",
"integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==",
"dev": true,
"dependencies": {
"filename-reserved-regex": "^2.0.0",
"strip-outer": "^1.0.1",
"trim-repeated": "^1.0.0"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/find-cache-dir": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz",
"integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==",
"dev": true,
"dependencies": {
"commondir": "^1.0.1",
"make-dir": "^3.0.2",
"pkg-dir": "^4.1.0"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/avajs/find-cache-dir?sponsor=1"
}
},
"node_modules/find-up": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
"dev": true,
"dependencies": {
"locate-path": "^5.0.0",
"path-exists": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/fs-extra": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
"dev": true,
"dependencies": {
"graceful-fs": "^4.2.0",
"jsonfile": "^4.0.0",
"universalify": "^0.1.0"
},
"engines": {
"node": ">=6 <7 || >=8"
}
},
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
"dev": true
},
"node_modules/gh-pages": {
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-3.2.3.tgz",
"integrity": "sha512-jA1PbapQ1jqzacECfjUaO9gV8uBgU6XNMV0oXLtfCX3haGLe5Atq8BxlrADhbD6/UdG9j6tZLWAkAybndOXTJg==",
"dev": true,
"dependencies": {
"async": "^2.6.1",
"commander": "^2.18.0",
"email-addresses": "^3.0.1",
"filenamify": "^4.3.0",
"find-cache-dir": "^3.3.1",
"fs-extra": "^8.1.0",
"globby": "^6.1.0"
},
"bin": {
"gh-pages": "bin/gh-pages.js",
"gh-pages-clean": "bin/gh-pages-clean.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/glob": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
"dev": true,
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
},
"engines": {
"node": "*"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/globby": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
"integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=",
"dev": true,
"dependencies": {
"array-union": "^1.0.1",
"glob": "^7.0.3",
"object-assign": "^4.0.1",
"pify": "^2.0.0",
"pinkie-promise": "^2.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/graceful-fs": {
"version": "4.2.8",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz",
"integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==",
"dev": true
},
"node_modules/inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"dev": true,
"dependencies": {
"once": "^1.3.0",
"wrappy": "1"
}
},
"node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"dev": true
},
"node_modules/jsonfile": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
"dev": true,
"optionalDependencies": {
"graceful-fs": "^4.1.6"
}
},
"node_modules/locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
"dev": true,
"dependencies": {
"p-locate": "^4.1.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"dev": true
},
"node_modules/make-dir": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
"integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
"dev": true,
"dependencies": {
"semver": "^6.0.0"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dev": true,
"dependencies": {
"brace-expansion": "^1.1.7"
},
"engines": {
"node": "*"
}
},
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dev": true,
"dependencies": {
"wrappy": "1"
}
},
"node_modules/p-limit": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"dev": true,
"dependencies": {
"p-try": "^2.0.0"
},
"engines": {
"node": ">=6"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/p-locate": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
"dev": true,
"dependencies": {
"p-limit": "^2.2.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/p-try": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
"dev": true,
"engines": {
"node": ">=6"
}
},
"node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"dev": true,
"engines": {
"node": ">=8"
}
},
"node_modules/path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/pify": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/pinkie": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
"integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/pinkie-promise": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
"integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
"dev": true,
"dependencies": {
"pinkie": "^2.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/pkg-dir": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
"integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
"dev": true,
"dependencies": {
"find-up": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/strip-outer": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz",
"integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==",
"dev": true,
"dependencies": {
"escape-string-regexp": "^1.0.2"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/trim-repeated": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz",
"integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=",
"dev": true,
"dependencies": {
"escape-string-regexp": "^1.0.2"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/universalify": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
"dev": true,
"engines": {
"node": ">= 4.0.0"
}
},
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
"dev": true
}
},
"dependencies": {
"array-union": {
"version": "1.0.2",
@@ -20,18 +480,18 @@
"dev": true
},
"async": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz",
"integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==",
"version": "2.6.3",
"resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
"integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
"dev": true,
"requires": {
"lodash": "^4.17.10"
"lodash": "^4.17.14"
}
},
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
},
"brace-expansion": {
@@ -45,9 +505,15 @@
}
},
"commander": {
"version": "2.15.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz",
"integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==",
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"dev": true
},
"commondir": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
"integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
"dev": true
},
"concat-map": {
@@ -56,6 +522,12 @@
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
"dev": true
},
"email-addresses": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-3.1.0.tgz",
"integrity": "sha512-k0/r7GrWVL32kZlGwfPNgB2Y/mMXVTq/decgLczm/j34whdaspNrZO8CnXPf1laaHxI6ptUlsnAxN+UAPw+fzg==",
"dev": true
},
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
@@ -63,39 +535,50 @@
"dev": true
},
"filename-reserved-regex": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-1.0.0.tgz",
"integrity": "sha1-5hz4BfDeHJhFZ9A4bcXfUO5a9+Q=",
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz",
"integrity": "sha1-q/c9+rc10EVECr/qLZHzieu/oik=",
"dev": true
},
"filenamify": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/filenamify/-/filenamify-1.2.1.tgz",
"integrity": "sha1-qfL/0RxQO+0wABUCknI3jx8TZaU=",
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz",
"integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==",
"dev": true,
"requires": {
"filename-reserved-regex": "^1.0.0",
"strip-outer": "^1.0.0",
"filename-reserved-regex": "^2.0.0",
"strip-outer": "^1.0.1",
"trim-repeated": "^1.0.0"
}
},
"filenamify-url": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/filenamify-url/-/filenamify-url-1.0.0.tgz",
"integrity": "sha1-syvYExnvWGO3MHi+1Q9GpPeXX1A=",
"find-cache-dir": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz",
"integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==",
"dev": true,
"requires": {
"filenamify": "^1.0.0",
"humanize-url": "^1.0.0"
"commondir": "^1.0.1",
"make-dir": "^3.0.2",
"pkg-dir": "^4.1.0"
}
},
"find-up": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
"dev": true,
"requires": {
"locate-path": "^5.0.0",
"path-exists": "^4.0.0"
}
},
"fs-extra": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz",
"integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==",
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
"dev": true,
"requires": {
"graceful-fs": "^4.1.2",
"graceful-fs": "^4.2.0",
"jsonfile": "^4.0.0",
"universalify": "^0.1.0"
}
@@ -107,24 +590,24 @@
"dev": true
},
"gh-pages": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-1.2.0.tgz",
"integrity": "sha512-cGLYAvxtlQ1iTwAS4g7FreZPXoE/g62Fsxln2mmR19mgs4zZI+XJ+wVVUhBFCF/0+Nmvbq+abyTWue1m1BSnmg==",
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-3.2.3.tgz",
"integrity": "sha512-jA1PbapQ1jqzacECfjUaO9gV8uBgU6XNMV0oXLtfCX3haGLe5Atq8BxlrADhbD6/UdG9j6tZLWAkAybndOXTJg==",
"dev": true,
"requires": {
"async": "2.6.1",
"commander": "2.15.1",
"filenamify-url": "^1.0.0",
"fs-extra": "^5.0.0",
"globby": "^6.1.0",
"graceful-fs": "4.1.11",
"rimraf": "^2.6.2"
"async": "^2.6.1",
"commander": "^2.18.0",
"email-addresses": "^3.0.1",
"filenamify": "^4.3.0",
"find-cache-dir": "^3.3.1",
"fs-extra": "^8.1.0",
"globby": "^6.1.0"
}
},
"glob": {
"version": "7.1.4",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
"integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
"dev": true,
"requires": {
"fs.realpath": "^1.0.0",
@@ -149,21 +632,11 @@
}
},
"graceful-fs": {
"version": "4.1.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
"integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
"version": "4.2.8",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz",
"integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==",
"dev": true
},
"humanize-url": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/humanize-url/-/humanize-url-1.0.1.tgz",
"integrity": "sha1-9KuZ4NKIF0yk4eUEB8VfuuRk7/8=",
"dev": true,
"requires": {
"normalize-url": "^1.0.0",
"strip-url-auth": "^1.0.0"
}
},
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
@@ -175,15 +648,9 @@
}
},
"inherits": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
"dev": true
},
"is-plain-obj": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
"integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"dev": true
},
"jsonfile": {
@@ -195,12 +662,30 @@
"graceful-fs": "^4.1.6"
}
},
"locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
"dev": true,
"requires": {
"p-locate": "^4.1.0"
}
},
"lodash": {
"version": "4.17.11",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"dev": true
},
"make-dir": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
"integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
"dev": true,
"requires": {
"semver": "^6.0.0"
}
},
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
@@ -210,18 +695,6 @@
"brace-expansion": "^1.1.7"
}
},
"normalize-url": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz",
"integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=",
"dev": true,
"requires": {
"object-assign": "^4.0.1",
"prepend-http": "^1.0.0",
"query-string": "^4.1.0",
"sort-keys": "^1.0.0"
}
},
"object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -237,6 +710,36 @@
"wrappy": "1"
}
},
"p-limit": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"dev": true,
"requires": {
"p-try": "^2.0.0"
}
},
"p-locate": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
"dev": true,
"requires": {
"p-limit": "^2.2.0"
}
},
"p-try": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
"dev": true
},
"path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"dev": true
},
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
@@ -264,44 +767,19 @@
"pinkie": "^2.0.0"
}
},
"prepend-http": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
"integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=",
"dev": true
},
"query-string": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz",
"integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=",
"pkg-dir": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
"integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
"dev": true,
"requires": {
"object-assign": "^4.1.0",
"strict-uri-encode": "^1.0.0"
"find-up": "^4.0.0"
}
},
"rimraf": {
"version": "2.6.3",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
"integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
"dev": true,
"requires": {
"glob": "^7.1.3"
}
},
"sort-keys": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz",
"integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=",
"dev": true,
"requires": {
"is-plain-obj": "^1.0.0"
}
},
"strict-uri-encode": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
"integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true
},
"strip-outer": {
@@ -313,12 +791,6 @@
"escape-string-regexp": "^1.0.2"
}
},
"strip-url-auth": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/strip-url-auth/-/strip-url-auth-1.0.1.tgz",
"integrity": "sha1-IrD6OkE4WzO+PzMVUbu4N/oM164=",
"dev": true
},
"trim-repeated": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz",

View File

@@ -6,6 +6,6 @@
"clean:l10n": "git push origin --delete l10n_master"
},
"devDependencies": {
"gh-pages": "^1.2.0"
"gh-pages": "^3.2.3"
}
}

View File

@@ -4,10 +4,13 @@ using Android.OS;
using Android.Runtime;
using Android.Views;
using System;
using Bit.Core.Abstractions;
using Bit.Core.Utilities;
using Bit.Droid.Utilities;
namespace Bit.Droid.Accessibility
{
[Activity(Theme = "@style/LightTheme.Splash", WindowSoftInputMode = SoftInput.StateHidden)]
[Activity(Theme = "@style/BaseTheme", WindowSoftInputMode = SoftInput.StateHidden)]
public class AccessibilityActivity : Activity
{
private DateTime? _lastLaunch = null;
@@ -15,14 +18,15 @@ namespace Bit.Droid.Accessibility
protected override void OnCreate(Bundle bundle)
{
Intent?.Validate();
base.OnCreate(bundle);
LaunchMainActivity(Intent, 932473);
HandleIntent(Intent, 932473);
}
protected override void OnNewIntent(Intent intent)
{
base.OnNewIntent(intent);
LaunchMainActivity(intent, 489729);
HandleIntent(intent, 489729);
}
protected override void OnDestroy()
@@ -33,7 +37,7 @@ namespace Bit.Droid.Accessibility
protected override void OnResume()
{
base.OnResume();
if(!Intent.HasExtra("uri"))
if (!Intent.HasExtra("uri"))
{
Finish();
return;
@@ -44,7 +48,7 @@ namespace Bit.Droid.Accessibility
protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
if(data == null)
if (data == null)
{
AccessibilityHelpers.LastCredentials = null;
}
@@ -52,7 +56,7 @@ namespace Bit.Droid.Accessibility
{
try
{
if(data.GetStringExtra("canceled") != null)
if (data.GetStringExtra("canceled") != null)
{
AccessibilityHelpers.LastCredentials = null;
}
@@ -78,23 +82,38 @@ namespace Bit.Droid.Accessibility
Finish();
}
private void HandleIntent(Intent callingIntent, int requestCode)
{
if (callingIntent?.GetBooleanExtra("autofillTileClicked", false) ?? false)
{
Intent.RemoveExtra("autofillTileClicked");
var messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
messagingService.Send("OnAutofillTileClick");
Finish();
}
else
{
LaunchMainActivity(callingIntent, requestCode);
}
}
private void LaunchMainActivity(Intent callingIntent, int requestCode)
{
_lastQueriedUri = callingIntent?.GetStringExtra("uri");
if(_lastQueriedUri == null)
if (_lastQueriedUri == null)
{
Finish();
return;
}
var now = DateTime.UtcNow;
if(_lastLaunch.HasValue && (now - _lastLaunch.Value) <= TimeSpan.FromSeconds(2))
if (_lastLaunch.HasValue && (now - _lastLaunch.Value) <= TimeSpan.FromSeconds(2))
{
return;
}
_lastLaunch = now;
var intent = new Intent(this, typeof(MainActivity));
if(!callingIntent.Flags.HasFlag(ActivityFlags.LaunchedFromHistory))
if (!callingIntent.Flags.HasFlag(ActivityFlags.LaunchedFromHistory))
{
intent.PutExtra("uri", _lastQueriedUri);
}

View File

@@ -1,8 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Android.App;
using Android.Content;
using Android.Graphics;
using Android.OS;
using Android.Provider;
using Android.Runtime;
using Android.Views;
using Android.Views.Accessibility;
using Android.Widget;
using Bit.App.Resources;
using Bit.Core;
namespace Bit.Droid.Accessibility
@@ -12,55 +20,122 @@ namespace Bit.Droid.Accessibility
public static Credentials LastCredentials = null;
public static string SystemUiPackage = "com.android.systemui";
public static string BitwardenTag = "bw_access";
public static bool IsAutofillTileAdded = false;
public static bool IsAccessibilityBroadcastReady = false;
// Be sure to keep these two sections sorted alphabetically
public static Dictionary<string, Browser> SupportedBrowsers => new List<Browser>
{
new Browser("com.android.chrome", "url_bar"),
new Browser("com.chrome.beta", "url_bar"),
new Browser("org.chromium.chrome", "url_bar"),
// [Section A] Entries also present in the list of Autofill Framework
//
// So keep them in sync with:
// - AutofillHelpers.{TrustedBrowsers,CompatBrowsers}
// - Resources/xml/autofillservice.xml
new Browser("alook.browser", "search_fragment_input_view"),
new Browser("alook.browser.google", "search_fragment_input_view"),
new Browser("com.amazon.cloud9", "url"),
new Browser("com.android.browser", "url"),
new Browser("com.android.chrome", "url_bar"),
// Rem. for "com.android.htmlviewer": doesn't have a URL bar, therefore not present here.
new Browser("com.avast.android.secure.browser", "editor"),
new Browser("com.avg.android.secure.browser", "editor"),
new Browser("com.brave.browser", "url_bar"),
new Browser("com.brave.browser_beta", "url_bar"),
new Browser("com.brave.browser_default", "url_bar"),
new Browser("com.brave.browser_dev", "url_bar"),
new Browser("com.brave.browser_nightly", "url_bar"),
new Browser("com.chrome.beta", "url_bar"),
new Browser("com.chrome.canary", "url_bar"),
new Browser("com.chrome.dev", "url_bar"),
new Browser("com.cookiegames.smartcookie", "search"),
new Browser("com.cookiejarapps.android.smartcookieweb", "mozac_browser_toolbar_url_view"),
new Browser("com.duckduckgo.mobile.android", "omnibarTextInput"),
new Browser("com.ecosia.android", "url_bar"),
new Browser("com.google.android.apps.chrome", "url_bar"),
new Browser("com.google.android.apps.chrome_dev", "url_bar"),
// Rem. for "com.google.android.captiveportallogin": URL displayed in ActionBar subtitle without viewId.
new Browser("com.jamal2367.styx", "search"),
new Browser("com.kiwibrowser.browser", "url_bar"),
new Browser("com.kiwibrowser.browser.dev", "url_bar"),
new Browser("com.microsoft.emmx", "url_bar"),
new Browser("com.microsoft.emmx.beta", "url_bar"),
new Browser("com.microsoft.emmx.canary", "url_bar"),
new Browser("com.microsoft.emmx.dev", "url_bar"),
new Browser("com.mmbox.browser", "search_box"),
new Browser("com.mmbox.xbrowser", "search_box"),
new Browser("com.mycompany.app.soulbrowser", "edit_text"),
new Browser("com.naver.whale", "url_bar"),
new Browser("com.opera.browser", "url_field"),
new Browser("com.opera.browser.beta", "url_field"),
new Browser("com.opera.mini.native", "url_field"),
new Browser("com.opera.mini.native.beta", "url_field"),
new Browser("com.opera.touch", "addressbarEdit"),
new Browser("com.chrome.dev", "url_bar"),
new Browser("com.chrome.canary", "url_bar"),
new Browser("com.google.android.apps.chrome", "url_bar"),
new Browser("com.google.android.apps.chrome_dev", "url_bar"),
new Browser("org.codeaurora.swe.browser", "url_bar"),
new Browser("org.iron.srware", "url_bar"),
new Browser("com.qflair.browserq", "url"),
new Browser("com.qwant.liberty", "mozac_browser_toolbar_url_view,url_bar_title"), // 2nd = Legacy (before v4)
new Browser("com.sec.android.app.sbrowser", "location_bar_edit_text"),
new Browser("com.sec.android.app.sbrowser.beta", "location_bar_edit_text"),
new Browser("com.yandex.browser", "bro_omnibar_address_title_text",
new Browser("com.stoutner.privacybrowser.free", "url_edittext"),
new Browser("com.stoutner.privacybrowser.standard", "url_edittext"),
new Browser("com.vivaldi.browser", "url_bar"),
new Browser("com.vivaldi.browser.snapshot", "url_bar"),
new Browser("com.vivaldi.browser.sopranos", "url_bar"),
new Browser("com.yandex.browser", "bro_omnibar_address_title_text,bro_omnibox_collapsed_title",
(s) => s.Split(new char[]{' ', ' '}).FirstOrDefault()), // 0 = Regular Space, 1 = No-break space (00A0)
new Browser("org.mozilla.firefox", "url_bar_title"),
new Browser("org.mozilla.firefox_beta", "url_bar_title"),
new Browser("org.mozilla.fennec_aurora", "url_bar_title"),
new Browser("org.mozilla.focus", "display_url"),
new Browser("org.mozilla.klar", "display_url"),
new Browser("com.z28j.feel", "g2"),
new Browser("idm.internet.download.manager", "search"),
new Browser("idm.internet.download.manager.adm.lite", "search"),
new Browser("idm.internet.download.manager.plus", "search"),
new Browser("io.github.forkmaintainers.iceraven", "mozac_browser_toolbar_url_view"),
new Browser("mark.via", "am,an"),
new Browser("mark.via.gp", "as"),
new Browser("net.slions.fulguris.full.download", "search"),
new Browser("net.slions.fulguris.full.download.debug", "search"),
new Browser("net.slions.fulguris.full.playstore", "search"),
new Browser("net.slions.fulguris.full.playstore.debug", "search"),
new Browser("org.adblockplus.browser", "url_bar,url_bar_title"), // 2nd = Legacy (before v2)
new Browser("org.adblockplus.browser.beta", "url_bar,url_bar_title"), // 2nd = Legacy (before v2)
new Browser("org.bromite.bromite", "url_bar"),
new Browser("org.bromite.chromium", "url_bar"),
new Browser("org.chromium.chrome", "url_bar"),
new Browser("org.codeaurora.swe.browser", "url_bar"),
new Browser("org.gnu.icecat", "url_bar_title,mozac_browser_toolbar_url_view"), // 2nd = Anticipation
new Browser("org.mozilla.fenix", "mozac_browser_toolbar_url_view"),
new Browser("org.mozilla.fenix.nightly", "mozac_browser_toolbar_url_view"), // [DEPRECATED ENTRY]
new Browser("org.mozilla.fennec_aurora", "mozac_browser_toolbar_url_view,url_bar_title"), // [DEPRECATED ENTRY]
new Browser("org.mozilla.fennec_fdroid", "mozac_browser_toolbar_url_view,url_bar_title"), // 2nd = Legacy
new Browser("org.mozilla.firefox", "mozac_browser_toolbar_url_view,url_bar_title"), // 2nd = Legacy
new Browser("org.mozilla.firefox_beta", "mozac_browser_toolbar_url_view,url_bar_title"), // 2nd = Legacy
new Browser("org.mozilla.focus", "mozac_browser_toolbar_url_view,display_url"), // 2nd = Legacy
new Browser("org.mozilla.focus.beta", "mozac_browser_toolbar_url_view,display_url"), // 2nd = Legacy
new Browser("org.mozilla.focus.nightly", "mozac_browser_toolbar_url_view,display_url"), // 2nd = Legacy
new Browser("org.mozilla.klar", "mozac_browser_toolbar_url_view,display_url"), // 2nd = Legacy
new Browser("org.mozilla.reference.browser", "mozac_browser_toolbar_url_view"),
new Browser("org.mozilla.rocket", "display_url"),
new Browser("org.torproject.torbrowser", "mozac_browser_toolbar_url_view,url_bar_title"), // 2nd = Legacy (before v10.0.3)
new Browser("org.torproject.torbrowser_alpha", "mozac_browser_toolbar_url_view,url_bar_title"), // 2nd = Legacy (before v10.0a8)
new Browser("org.ungoogled.chromium.extensions.stable", "url_bar"),
new Browser("org.ungoogled.chromium.stable", "url_bar"),
new Browser("us.spotco.fennec_dos", "mozac_browser_toolbar_url_view,url_bar_title"), // 2nd = Legacy
// [Section B] Entries only present here
//
// FIXME: Test the compatibility of these with Autofill Framework
new Browser("acr.browser.barebones", "search"),
new Browser("acr.browser.lightning", "search"),
new Browser("com.feedback.browser.wjbrowser", "addressbar_url"),
new Browser("com.ghostery.android.ghostery", "search_field"),
new Browser("org.adblockplus.browser", "url_bar_title"),
new Browser("com.htc.sense.browser", "title"),
new Browser("com.amazon.cloud9", "url"),
new Browser("mobi.mgeek.TunnyBrowser", "title"),
new Browser("com.nubelacorp.javelin", "enterUrl"),
new Browser("com.jerky.browser2", "enterUrl"),
new Browser("com.ksmobile.cb", "address_bar_edit_text"),
new Browser("com.linkbubble.playstore", "url_text"),
new Browser("com.mx.browser", "address_editor_with_progress"),
new Browser("com.mx.browser.tablet", "address_editor_with_progress"),
new Browser("com.linkbubble.playstore", "url_text"),
new Browser("com.ksmobile.cb", "address_bar_edit_text"),
new Browser("acr.browser.lightning", "search"),
new Browser("acr.browser.barebones", "search"),
new Browser("com.microsoft.emmx", "url_bar"),
new Browser("com.duckduckgo.mobile.android", "omnibarTextInput"),
new Browser("mark.via.gp", "aw"),
new Browser("org.bromite.bromite", "url_bar"),
new Browser("com.kiwibrowser.browser", "url_bar"),
new Browser("com.ecosia.android", "url_bar"),
new Browser("com.qwant.liberty", "url_bar_title"),
new Browser("com.nubelacorp.javelin", "enterUrl"),
new Browser("jp.co.fenrir.android.sleipnir", "url_text"),
new Browser("jp.co.fenrir.android.sleipnir_black", "url_text"),
new Browser("jp.co.fenrir.android.sleipnir_test", "url_text"),
new Browser("mobi.mgeek.TunnyBrowser", "title"),
new Browser("org.iron.srware", "url_bar"),
}.ToDictionary(n => n.PackageName);
// Known packages to skip
@@ -80,61 +155,271 @@ namespace Bit.Droid.Accessibility
"com.teslacoilsw.launcher.prime",
"is.shortcut",
"me.craftsapp.nlauncher",
"com.ss.squarehome2"
"com.ss.squarehome2",
"com.treydev.pns"
};
// Be sure to keep these sections sorted alphabetically
public static Dictionary<string, KnownUsernameField> KnownUsernameFields => new List<KnownUsernameField>
{
/**************************************************************************************
* SECTION A ——— World-renowned web sites/applications
*************************************************************************************/
// REM.: For this type of web sites/applications, the Top 100 (SimilarWeb, 2019)
// and the Top 50 (Alexa Internet, 2020) are covered. National variants
// have been added when available. Mobile and desktop versions supported.
//
// A few other popular web sites/applications have also been added.
//
// Could not be added, however:
// web sites/applications that don't use an "id" attribute for their login field.
// NOTE: The case of OAuth compatible web sites/applications that also provide
// a "user ID only" login page in this situation
// was taken into account in the tests as well.
/*
* A
*/
// Amazon ——— ap_email_login = mobile / ap_email = desktop (amazon.co.jp currently uses ap_email in both cases, as of July 2020).
new KnownUsernameField("amazon.ae", new (string, string)[] { ("contains:/ap/signin", "ap_email_login,ap_email") }),
new KnownUsernameField("amazon.ca", new (string, string)[] { ("contains:/ap/signin", "ap_email_login,ap_email") }),
new KnownUsernameField("amazon.cn", new (string, string)[] { ("contains:/ap/signin", "ap_email_login,ap_email") }),
new KnownUsernameField("amazon.co.jp", new (string, string)[] { ("contains:/ap/signin", "ap_email_login,ap_email") }),
new KnownUsernameField("amazon.co.uk", new (string, string)[] { ("contains:/ap/signin", "ap_email_login,ap_email") }),
new KnownUsernameField("amazon.com", new (string, string)[] { ("contains:/ap/signin", "ap_email_login,ap_email") }),
new KnownUsernameField("amazon.com.au", new (string, string)[] { ("contains:/ap/signin", "ap_email_login,ap_email") }),
new KnownUsernameField("amazon.com.br", new (string, string)[] { ("contains:/ap/signin", "ap_email_login,ap_email") }),
new KnownUsernameField("amazon.com.mx", new (string, string)[] { ("contains:/ap/signin", "ap_email_login,ap_email") }),
new KnownUsernameField("amazon.com.tr", new (string, string)[] { ("contains:/ap/signin", "ap_email_login,ap_email") }),
new KnownUsernameField("amazon.de", new (string, string)[] { ("contains:/ap/signin", "ap_email_login,ap_email") }),
new KnownUsernameField("amazon.es", new (string, string)[] { ("contains:/ap/signin", "ap_email_login,ap_email") }),
new KnownUsernameField("amazon.fr", new (string, string)[] { ("contains:/ap/signin", "ap_email_login,ap_email") }),
new KnownUsernameField("amazon.in", new (string, string)[] { ("contains:/ap/signin", "ap_email_login,ap_email") }),
new KnownUsernameField("amazon.it", new (string, string)[] { ("contains:/ap/signin", "ap_email_login,ap_email") }),
new KnownUsernameField("amazon.nl", new (string, string)[] { ("contains:/ap/signin", "ap_email_login,ap_email") }),
new KnownUsernameField("amazon.pl", new (string, string)[] { ("contains:/ap/signin", "ap_email_login,ap_email") }),
new KnownUsernameField("amazon.sa", new (string, string)[] { ("contains:/ap/signin", "ap_email_login,ap_email") }),
new KnownUsernameField("amazon.se", new (string, string)[] { ("contains:/ap/signin", "ap_email_login,ap_email") }),
new KnownUsernameField("amazon.sg", new (string, string)[] { ("contains:/ap/signin", "ap_email_login,ap_email") }),
// Amazon Web Services
new KnownUsernameField("signin.aws.amazon.com", new (string, string)[] { ("signin", "resolving_input") }),
// Atlassian
new KnownUsernameField("id.atlassian.com", new (string, string)[] { ("login", "username") }),
/*
* B
*/
// Bitly ——— enterprise users.
new KnownUsernameField("bitly.com", new (string, string)[] { ("/sso/url_slug", "url_slug") }),
/*
* E
*/
// eBay ——— 1st = traditional access / 2nd = direct access (i.e. https://signin.ebay.tld/).
new KnownUsernameField("signin.befr.ebay.be", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.benl.ebay.be", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.cafr.ebay.ca", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.ebay.at", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.ebay.be", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.ebay.ca", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.ebay.ch", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.ebay.co.uk", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.ebay.com", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.ebay.com.au", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.ebay.com.hk", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.ebay.com.my", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.ebay.com.sg", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.ebay.de", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.ebay.es", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.ebay.fr", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.ebay.ie", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.ebay.in", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.ebay.it", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.ebay.nl", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.ebay.ph", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.ebay.pl", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
/*
* G
*/
// Google ——— 1st = used in most cases (v2) / 2nd = used in some cases (v1).
new KnownUsernameField("accounts.google.com", new (string, string)[] { ("identifier", "identifierId"), ("ServiceLogin", "Email") }),
/*
* P
*/
// PayPal ——— 1st = traditional access / 2nd = access using OAuth.
new KnownUsernameField("paypal.com", new (string, string)[] { ("signin", "email"), ("contains:/connect/", "email") }),
/*
* T
*/
// Tumblr ——— despite "signup" in its ID, it's the login field (the website offers registration if the account doesn't exist).
new KnownUsernameField("tumblr.com", new (string, string)[] { ("login", "signup_determine_email") }),
/*
* Y
*/
// Yandex
new KnownUsernameField("passport.yandex.az", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.by", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.co.il", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.com", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.com.am", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.com.ge", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.com.tr", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.ee", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.fi", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.fr", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.kg", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.kz", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.lt", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.lv", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.md", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.pl", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.ru", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.tj", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.tm", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.ua", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.uz", new (string, string)[] { ("auth", "passp-field-login") }),
/**************************************************************************************
* SECTION B ——— Top 100 worldwide
*************************************************************************************/
// As of July 2020, all entries that needed to be added from
// Top 100 (SimilarWeb, 2019) and Top 50 (Alexa Internet, 2020)
// matched section A.
//
// Therefore, no entry currently.
/**************************************************************************************
* SECTION C ——— Top 20 for selected countries
*************************************************************************************/
// REM.: For these selected countries, the Top 20 (SimilarWeb, 2020)
// and the Top 20 (Alexa Internet, 2020) are covered.
// Mobile and desktop versions supported.
//
// Could not be added, however:
// web sites/applications that don't use an "id" attribute for their login field.
/*
* Japan
*/
// NTT DOCOMO ——— mainly used for "My docomo".
new KnownUsernameField("cfg.smt.docomo.ne.jp", new (string, string)[] { ("contains:/auth/", "Di_Uid") }),
new KnownUsernameField("id.smt.docomo.ne.jp", new (string, string)[] { ("contains:/cgi7/", "Di_Uid") }),
/**************************************************************************************
* SECTION D ——— Miscellaneous
*************************************************************************************/
/*
* Various entries ——— Following user requests, etc.
*/
// No entry, currently.
/**************************************************************************************
* SECTION Z ——— Special forms
*
* Despite "user ID + password" fields both visible, detection rules required.
*************************************************************************************/
/*
* Main
*/
// No entry, currently.
/*
* Test/example purposes only
*/
// GitHub ——— VERY special case (signup form, just to test the proper functioning of special forms).
new KnownUsernameField("github.com", new (string, string)[] { ("", "user[login]-footer") }),
}.ToDictionary(n => n.UriAuthority);
public static void PrintTestData(AccessibilityNodeInfo root, AccessibilityEvent e)
{
var testNodes = GetWindowNodes(root, e, n => n.ViewIdResourceName != null && n.Text != null, false);
var testNodesData = testNodes.Select(n => new { id = n.ViewIdResourceName, text = n.Text });
foreach (var node in testNodesData)
{
System.Diagnostics.Debug.WriteLine("Node: {0} = {1}", node.id, node.text);
}
}
public static string GetUri(AccessibilityNodeInfo root)
{
var uri = string.Concat(Constants.AndroidAppProtocol, root.PackageName);
if(SupportedBrowsers.ContainsKey(root.PackageName))
if (SupportedBrowsers.ContainsKey(root.PackageName))
{
var browser = SupportedBrowsers[root.PackageName];
var addressNode = root.FindAccessibilityNodeInfosByViewId(
$"{root.PackageName}:id/{browser.UriViewId}").FirstOrDefault();
if(addressNode != null)
AccessibilityNodeInfo addressNode = null;
foreach (var uriViewId in browser.UriViewId.Split(","))
{
addressNode = root.FindAccessibilityNodeInfosByViewId(
$"{root.PackageName}:id/{uriViewId}").FirstOrDefault();
if (addressNode != null)
{
break;
}
}
if (addressNode != null)
{
uri = ExtractUri(uri, addressNode, browser);
addressNode.Dispose();
addressNode.Recycle();
}
else
{
// Return null to prevent overwriting notification pendingIntent uri with browser packageName
// (we login to pages, not browsers)
return null;
}
}
return uri;
}
public static string ExtractUri(string uri, AccessibilityNodeInfo addressNode, Browser browser)
private static string ExtractUri(string uri, AccessibilityNodeInfo addressNode, Browser browser)
{
if(addressNode?.Text == null)
if (addressNode?.Text == null)
{
return uri;
}
if(addressNode.Text == null)
if (addressNode.Text == null)
{
return uri;
}
uri = browser.GetUriFunction(addressNode.Text)?.Trim();
if(uri != null && uri.Contains("."))
if (uri != null && uri.Contains("."))
{
if(!uri.Contains("://") && !uri.Contains(" "))
var hasHttpProtocol = uri.StartsWith("http://") || uri.StartsWith("https://");
if (!hasHttpProtocol && uri.Contains("."))
{
uri = string.Concat("http://", uri);
}
else if(Build.VERSION.SdkInt <= BuildVersionCodes.KitkatWatch)
{
var parts = uri.Split(new string[] { ". " }, StringSplitOptions.None);
if(parts.Length > 1)
if (Uri.TryCreate("https://" + uri, UriKind.Absolute, out var _))
{
var urlPart = parts.FirstOrDefault(p => p.StartsWith("http"));
if(urlPart != null)
{
uri = urlPart.Trim();
}
return string.Concat("https://", uri);
}
}
if (Uri.TryCreate(uri, UriKind.Absolute, out var _))
{
return uri;
}
}
return uri;
}
@@ -144,11 +429,11 @@ namespace Bit.Droid.Accessibility
/// </summary>
public static bool NeedToAutofill(Credentials credentials, string currentUriString)
{
if(credentials == null)
if (credentials == null)
{
return false;
}
if(Uri.TryCreate(credentials.LastUri, UriKind.Absolute, out Uri lastUri) &&
if (Uri.TryCreate(credentials.LastUri, UriKind.Absolute, out Uri lastUri) &&
Uri.TryCreate(currentUriString, UriKind.Absolute, out Uri currentUri))
{
return lastUri.Host == currentUri.Host;
@@ -161,12 +446,11 @@ namespace Bit.Droid.Accessibility
return n?.ClassName?.Contains("EditText") ?? false;
}
public static void FillCredentials(AccessibilityNodeInfo usernameNode,
IEnumerable<AccessibilityNodeInfo> passwordNodes)
{
FillEditText(usernameNode, LastCredentials?.Username);
foreach(var n in passwordNodes)
foreach (var n in passwordNodes)
{
FillEditText(n, LastCredentials?.Password);
}
@@ -174,7 +458,7 @@ namespace Bit.Droid.Accessibility
public static void FillEditText(AccessibilityNodeInfo editTextNode, string value)
{
if(editTextNode == null || value == null)
if (editTextNode == null || value == null)
{
return;
}
@@ -187,31 +471,35 @@ namespace Bit.Droid.Accessibility
Func<AccessibilityNodeInfo, bool> condition, bool disposeIfUnused, NodeList nodes = null,
int recursionDepth = 0)
{
if(nodes == null)
if (nodes == null)
{
nodes = new NodeList();
}
var dispose = disposeIfUnused;
if(n != null && recursionDepth < 50)
if (n != null && recursionDepth < 100)
{
var add = n.WindowId == e.WindowId &&
!(n.ViewIdResourceName?.StartsWith(SystemUiPackage) ?? false) &&
condition(n);
if(add)
if (add)
{
dispose = false;
nodes.Add(n);
}
for(var i = 0; i < n.ChildCount; i++)
for (var i = 0; i < n.ChildCount; i++)
{
var childNode = n.GetChild(i);
if(i > 100)
if (childNode == null)
{
continue;
}
else if (i > 100)
{
Android.Util.Log.Info(BitwardenTag, "Too many child iterations.");
break;
}
else if(childNode.GetHashCode() == n.GetHashCode())
else if (childNode.GetHashCode() == n.GetHashCode())
{
Android.Util.Log.Info(BitwardenTag, "Child node is the same as parent for some reason.");
}
@@ -221,26 +509,401 @@ namespace Bit.Droid.Accessibility
}
}
}
if(dispose)
if (dispose)
{
n?.Recycle();
n?.Dispose();
}
return nodes;
}
public static void GetNodesAndFill(AccessibilityNodeInfo root, AccessibilityEvent e,
IEnumerable<AccessibilityNodeInfo> passwordNodes)
public static AccessibilityNodeInfo GetUsernameEditText(string uriString,
IEnumerable<AccessibilityNodeInfo> allEditTexts)
{
var allEditTexts = GetWindowNodes(root, e, n => EditText(n), false);
var usernameEditText = GetUsernameEditText(allEditTexts);
FillCredentials(usernameEditText, passwordNodes);
allEditTexts.Dispose();
usernameEditText = null;
string uriAuthority = null;
string uriKey = null;
string uriLocalPath = null;
if (Uri.TryCreate(uriString, UriKind.Absolute, out var uri))
{
uriAuthority = uri.Authority;
uriKey = uriAuthority.StartsWith("www.", StringComparison.Ordinal) ? uriAuthority.Substring(4) : uriAuthority;
uriLocalPath = uri.LocalPath;
}
if (!string.IsNullOrEmpty(uriKey))
{
// Uncomment this to log values necessary for username field discovery
// foreach (var editText in allEditTexts)
// {
// System.Diagnostics.Debug.WriteLine(">>> uriKey: {0}, uriLocalPath: {1}, viewId: {2}", uriKey,
// uriLocalPath, editText.ViewIdResourceName);
// }
if (KnownUsernameFields.ContainsKey(uriKey))
{
var usernameField = KnownUsernameFields[uriKey];
(string UriPathWanted, string UsernameViewId)[] accessOptions = usernameField.AccessOptions;
for (int i = 0; i < accessOptions.Length; i++)
{
string curUriPathWanted = accessOptions[i].UriPathWanted;
string curUsernameViewId = accessOptions[i].UsernameViewId;
bool uriLocalPathMatches = false;
// Case-sensitive comparison
if (curUriPathWanted.StartsWith("startswith:", StringComparison.Ordinal))
{
curUriPathWanted = curUriPathWanted.Substring(11);
uriLocalPathMatches = uriLocalPath.StartsWith(curUriPathWanted, StringComparison.Ordinal);
}
else if (curUriPathWanted.StartsWith("contains:", StringComparison.Ordinal))
{
curUriPathWanted = curUriPathWanted.Substring(9);
uriLocalPathMatches = uriLocalPath.Contains(curUriPathWanted, StringComparison.Ordinal);
}
else if (curUriPathWanted.StartsWith("endswith:", StringComparison.Ordinal))
{
curUriPathWanted = curUriPathWanted.Substring(9);
uriLocalPathMatches = uriLocalPath.EndsWith(curUriPathWanted, StringComparison.Ordinal);
}
// Case-insensitive comparison
else if (curUriPathWanted.StartsWith("istartswith:", StringComparison.Ordinal))
{
curUriPathWanted = curUriPathWanted.Substring(12);
uriLocalPathMatches = uriLocalPath.StartsWith(curUriPathWanted, StringComparison.OrdinalIgnoreCase);
}
else if (curUriPathWanted.StartsWith("icontains:", StringComparison.Ordinal))
{
curUriPathWanted = curUriPathWanted.Substring(10);
uriLocalPathMatches = uriLocalPath.Contains(curUriPathWanted, StringComparison.OrdinalIgnoreCase);
}
else if (curUriPathWanted.StartsWith("iendswith:", StringComparison.Ordinal))
{
curUriPathWanted = curUriPathWanted.Substring(10);
uriLocalPathMatches = uriLocalPath.EndsWith(curUriPathWanted, StringComparison.OrdinalIgnoreCase);
}
// Default type of comparison
else
{
uriLocalPathMatches = uriLocalPath.EndsWith(curUriPathWanted, StringComparison.Ordinal);
}
if (uriLocalPathMatches)
{
foreach (var editText in allEditTexts)
{
foreach (var usernameViewId in curUsernameViewId.Split(","))
{
if (usernameViewId == editText.ViewIdResourceName)
{
return editText;
}
}
}
}
}
}
}
// no match found, attempt to establish username field based on password field
return GetUsernameEditTextIfPasswordExists(allEditTexts);
}
private static AccessibilityNodeInfo GetUsernameEditTextIfPasswordExists(
IEnumerable<AccessibilityNodeInfo> allEditTexts)
{
AccessibilityNodeInfo previousEditText = null;
foreach (var editText in allEditTexts)
{
if (editText.Password)
{
return previousEditText;
}
previousEditText = editText;
}
return null;
}
public static AccessibilityNodeInfo GetUsernameEditText(IEnumerable<AccessibilityNodeInfo> allEditTexts)
public static bool IsUsernameEditText(AccessibilityNodeInfo root, AccessibilityEvent e)
{
return allEditTexts.TakeWhile(n => !n.Password).LastOrDefault();
var allEditTexts = GetWindowNodes(root, e, n => EditText(n), false);
var uriString = GetUri(root);
var usernameEditText = GetUsernameEditText(uriString, allEditTexts);
var isUsernameEditText = false;
if (usernameEditText != null)
{
isUsernameEditText = IsSameNode(usernameEditText, e.Source);
}
allEditTexts.Dispose();
return isUsernameEditText;
}
public static bool IsSameNode(AccessibilityNodeInfo node1, AccessibilityNodeInfo node2)
{
if (node1 != null && node2 != null)
{
return node1.Equals(node2) || node1.GetHashCode() == node2.GetHashCode();
}
return false;
}
public static bool OverlayPermitted()
{
if (Build.VERSION.SdkInt >= BuildVersionCodes.M)
{
if (Settings.CanDrawOverlays(Application.Context))
{
return true;
}
var appOpsMgr = (AppOpsManager)Application.Context.GetSystemService(Context.AppOpsService);
var mode = appOpsMgr.CheckOpNoThrow("android:system_alert_window", Process.MyUid(),
Application.Context.PackageName);
if (mode == AppOpsManagerMode.Allowed || mode == AppOpsManagerMode.Ignored)
{
return true;
}
try
{
var wm = Application.Context.GetSystemService(Context.WindowService)
.JavaCast<IWindowManager>();
if (wm == null)
{
return false;
}
var testView = new View(Application.Context);
var layoutParams = GetOverlayLayoutParams();
wm.AddView(testView, layoutParams);
wm.RemoveView(testView);
return true;
}
catch { }
return false;
}
// older android versions are always true
return true;
}
public static LinearLayout GetOverlayView(Context context)
{
var inflater = (LayoutInflater)context.GetSystemService(Context.LayoutInflaterService);
var view = (LinearLayout)inflater.Inflate(Resource.Layout.autofill_listitem, null);
var text1 = (TextView)view.FindViewById(Resource.Id.text1);
var text2 = (TextView)view.FindViewById(Resource.Id.text2);
var icon = (ImageView)view.FindViewById(Resource.Id.icon);
text1.Text = AppResources.AutofillWithBitwarden;
text2.Text = AppResources.GoToMyVault;
icon.SetImageResource(Resource.Drawable.shield);
return view;
}
public static WindowManagerLayoutParams GetOverlayLayoutParams()
{
WindowManagerTypes windowManagerType;
if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
{
windowManagerType = WindowManagerTypes.ApplicationOverlay;
}
else
{
windowManagerType = WindowManagerTypes.Phone;
}
var layoutParams = new WindowManagerLayoutParams(
ViewGroup.LayoutParams.WrapContent,
ViewGroup.LayoutParams.WrapContent,
windowManagerType,
WindowManagerFlags.NotFocusable | WindowManagerFlags.NotTouchModal,
Format.Transparent);
layoutParams.Gravity = GravityFlags.Top | GravityFlags.Left;
return layoutParams;
}
public static Point GetOverlayAnchorPosition(AccessibilityService service, AccessibilityNodeInfo anchorView,
int overlayViewHeight, bool isOverlayAboveAnchor)
{
var anchorViewRect = new Rect();
anchorView.GetBoundsInScreen(anchorViewRect);
var anchorViewX = anchorViewRect.Left;
var anchorViewY = isOverlayAboveAnchor ? anchorViewRect.Top : anchorViewRect.Bottom;
anchorViewRect.Dispose();
if (isOverlayAboveAnchor)
{
anchorViewY -= overlayViewHeight;
}
anchorViewY -= GetStatusBarHeight(service);
return new Point(anchorViewX, anchorViewY);
}
public static Point GetOverlayAnchorPosition(AccessibilityService service, AccessibilityNodeInfo anchorNode,
AccessibilityNodeInfo root, IEnumerable<AccessibilityWindowInfo> windows, int overlayViewHeight,
bool isOverlayAboveAnchor)
{
Point point = null;
if (anchorNode != null)
{
// Update node's info since this is still a reference from an older event
anchorNode.Refresh();
if (!anchorNode.VisibleToUser)
{
return new Point(-1, -1);
}
if (!anchorNode.Focused)
{
return null;
}
// node.VisibleToUser doesn't always give us exactly what we want, so attempt to tighten up the range
// of visibility
var inputMethodHeight = 0;
if (windows != null)
{
if (IsStatusBarExpanded(windows))
{
return new Point(-1, -1);
}
inputMethodHeight = GetInputMethodHeight(windows);
}
var minY = 0;
var rootNodeHeight = GetNodeHeight(root);
if (rootNodeHeight == -1)
{
return null;
}
var maxY = rootNodeHeight - GetNavigationBarHeight(service) - GetStatusBarHeight(service) -
inputMethodHeight;
point = GetOverlayAnchorPosition(service, anchorNode, overlayViewHeight, isOverlayAboveAnchor);
if (point.Y < minY)
{
if (isOverlayAboveAnchor)
{
// view nearing bounds, anchor to bottom
point.X = -1;
point.Y = 0;
}
else
{
// view out of bounds, hide overlay
point.X = -1;
point.Y = -1;
}
}
else if (point.Y > (maxY - overlayViewHeight))
{
if (isOverlayAboveAnchor)
{
// view out of bounds, hide overlay
point.X = -1;
point.Y = -1;
}
else
{
// view nearing bounds, anchor to top
point.X = 0;
point.Y = -1;
}
}
else if (isOverlayAboveAnchor && point.Y < (maxY - (overlayViewHeight * 2) - GetNodeHeight(anchorNode)))
{
// This else block forces the overlay to return to bottom alignment as soon as space is available
// below the anchor view. Removing this will change the behavior to wait until there isn't enough
// space above the anchor view before returning to bottom alignment.
point.X = -1;
point.Y = 0;
}
}
return point;
}
public static bool IsStatusBarExpanded(IEnumerable<AccessibilityWindowInfo> windows)
{
if (windows != null && windows.Any())
{
var isSystemWindowsOnly = true;
foreach (var window in windows)
{
if (window.Type != AccessibilityWindowType.System)
{
isSystemWindowsOnly = false;
break;
}
}
return isSystemWindowsOnly;
}
return false;
}
public static int GetInputMethodHeight(IEnumerable<AccessibilityWindowInfo> windows)
{
var inputMethodWindowHeight = 0;
if (windows != null)
{
foreach (var window in windows)
{
if (window.Type == AccessibilityWindowType.InputMethod)
{
var windowRect = new Rect();
window.GetBoundsInScreen(windowRect);
inputMethodWindowHeight = windowRect.Height();
break;
}
}
}
return inputMethodWindowHeight;
}
public static bool IsAutofillServicePromptVisible(IEnumerable<AccessibilityWindowInfo> windows)
{
// Autofill framework not available until API 26
if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
{
return windows?.Any(w => w.Title?.ToLower().Contains("autofill") ?? false) ?? false;
}
return false;
}
public static int GetNodeHeight(AccessibilityNodeInfo node)
{
if (node == null)
{
return -1;
}
var nodeRect = new Rect();
node.GetBoundsInScreen(nodeRect);
var nodeRectHeight = nodeRect.Height();
nodeRect.Dispose();
return nodeRectHeight;
}
private static int GetStatusBarHeight(AccessibilityService service)
{
return GetSystemResourceDimenPx(service, "status_bar_height");
}
private static int GetNavigationBarHeight(AccessibilityService service)
{
return GetSystemResourceDimenPx(service, "navigation_bar_height");
}
private static int GetSystemResourceDimenPx(AccessibilityService service, string resName)
{
var resourceId = service.Resources.GetIdentifier(resName, "dimen", "android");
if (resourceId > 0)
{
return service.Resources.GetDimensionPixelSize(resourceId);
}
return 0;
}
}
}
}

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
@@ -6,9 +6,10 @@ using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Views.Accessibility;
using Android.Widget;
using Bit.App.Resources;
using Bit.Core;
using Bit.Core.Abstractions;
using Bit.Core.Utilities;
@@ -20,149 +21,142 @@ namespace Bit.Droid.Accessibility
[Register("com.x8bit.bitwarden.Accessibility.AccessibilityService")]
public class AccessibilityService : Android.AccessibilityServices.AccessibilityService
{
private NotificationChannel _notificationChannel;
private const int AutoFillNotificationId = 34573;
private const string BitwardenPackage = "com.x8bit.bitwarden";
private const string BitwardenWebsite = "vault.bitwarden.com";
private IStorageService _storageService;
private bool _settingAutofillPasswordField;
private bool _settingAutofillPersistNotification;
private IStateService _stateService;
private IBroadcasterService _broadcasterService;
private DateTime? _lastSettingsReload = null;
private TimeSpan _settingsReloadSpan = TimeSpan.FromMinutes(1);
private long _lastNotificationTime = 0;
private string _lastNotificationUri = null;
private HashSet<string> _blacklistedUris;
private AccessibilityNodeInfo _anchorNode = null;
private int _lastAnchorX = 0;
private int _lastAnchorY = 0;
private bool _isOverlayAboveAnchor = false;
private static bool _overlayAnchorObserverRunning = false;
private IWindowManager _windowManager = null;
private LinearLayout _overlayView = null;
private int _overlayViewHeight = 0;
private long _lastAutoFillTime = 0;
private Java.Lang.Runnable _overlayAnchorObserverRunnable = null;
private Handler _handler = new Handler(Looper.MainLooper);
private HashSet<string> _launcherPackageNames = null;
private DateTime? _lastLauncherSetBuilt = null;
private TimeSpan _rebuildLauncherSpan = TimeSpan.FromHours(1);
public override void OnCreate()
{
base.OnCreate();
LoadServices();
var settingsTask = LoadSettingsAsync();
_broadcasterService.Subscribe(nameof(AccessibilityService), (message) =>
{
if (message.Command == "OnAutofillTileClick")
{
var runnable = new Java.Lang.Runnable(OnAutofillTileClick);
_handler.PostDelayed(runnable, 250);
}
});
AccessibilityHelpers.IsAccessibilityBroadcastReady = true;
}
public override void OnDestroy()
{
AccessibilityHelpers.IsAccessibilityBroadcastReady = false;
_broadcasterService.Unsubscribe(nameof(AccessibilityService));
}
public override void OnAccessibilityEvent(AccessibilityEvent e)
{
try
{
var powerManager = GetSystemService(PowerService) as PowerManager;
if(Build.VERSION.SdkInt > BuildVersionCodes.KitkatWatch && !powerManager.IsInteractive)
if (Build.VERSION.SdkInt > BuildVersionCodes.KitkatWatch && !powerManager.IsInteractive)
{
return;
}
else if(Build.VERSION.SdkInt < BuildVersionCodes.Lollipop && !powerManager.IsScreenOn)
else if (Build.VERSION.SdkInt < BuildVersionCodes.Lollipop && !powerManager.IsScreenOn)
{
return;
}
if(SkipPackage(e?.PackageName))
if (SkipPackage(e?.PackageName))
{
if (e?.PackageName != "com.android.systemui")
{
CancelOverlayPrompt();
}
return;
}
var root = RootInActiveWindow;
if(root == null || root.PackageName != e.PackageName)
{
return;
}
// AccessibilityHelpers.PrintTestData(RootInActiveWindow, e);
// AccessibilityHelpers.PrintTestData(root, e);
LoadServices();
var settingsTask = LoadSettingsAsync();
AccessibilityNodeInfo root = null;
var notificationManager = GetSystemService(NotificationService) as NotificationManager;
var cancelNotification = true;
switch(e.EventType)
switch (e.EventType)
{
case EventTypes.ViewFocused:
if(e.Source == null || !e.Source.Password || !_settingAutofillPasswordField)
case EventTypes.ViewClicked:
if (e.Source == null || e.PackageName == BitwardenPackage)
{
CancelOverlayPrompt();
break;
}
root = RootInActiveWindow;
if (root == null || root.PackageName != e.PackageName)
{
break;
}
if(e.PackageName == BitwardenPackage)
if (!(e.Source?.Password ?? false) && !AccessibilityHelpers.IsUsernameEditText(root, e))
{
CancelNotification(notificationManager);
CancelOverlayPrompt();
break;
}
if(ScanAndAutofill(root, e, notificationManager, cancelNotification))
if (ScanAndAutofill(root, e))
{
CancelNotification(notificationManager);
CancelOverlayPrompt();
}
else
{
OverlayPromptToAutofill(root, e);
}
break;
case EventTypes.WindowContentChanged:
case EventTypes.WindowStateChanged:
if(_settingAutofillPasswordField && e.Source.Password)
if (AccessibilityHelpers.LastCredentials == null)
{
break;
}
else if(_settingAutofillPasswordField && AccessibilityHelpers.LastCredentials == null)
if (e.PackageName == BitwardenPackage)
{
if(string.IsNullOrWhiteSpace(_lastNotificationUri))
{
CancelNotification(notificationManager);
break;
}
var uri = AccessibilityHelpers.GetUri(root);
if(uri != _lastNotificationUri)
{
CancelNotification(notificationManager);
}
else if(uri.StartsWith(Constants.AndroidAppProtocol))
{
CancelNotification(notificationManager, 30000);
}
CancelOverlayPrompt();
break;
}
if(e.PackageName == BitwardenPackage)
root = RootInActiveWindow;
if (root == null || root.PackageName != e.PackageName)
{
CancelNotification(notificationManager);
break;
}
if(_settingAutofillPersistNotification)
if (ScanAndAutofill(root, e))
{
var uri = AccessibilityHelpers.GetUri(root);
if(uri != null && !uri.Contains(BitwardenWebsite))
{
var needToFill = AccessibilityHelpers.NeedToAutofill(
AccessibilityHelpers.LastCredentials, uri);
if(needToFill)
{
var passwordNodes = AccessibilityHelpers.GetWindowNodes(root, e,
n => n.Password, false);
needToFill = passwordNodes.Any();
if(needToFill)
{
AccessibilityHelpers.GetNodesAndFill(root, e, passwordNodes);
}
passwordNodes.Dispose();
}
if(!needToFill)
{
NotifyToAutofill(uri, notificationManager);
cancelNotification = false;
}
}
AccessibilityHelpers.LastCredentials = null;
}
else
{
cancelNotification = ScanAndAutofill(root, e, notificationManager, cancelNotification);
}
if(cancelNotification)
{
CancelNotification(notificationManager);
CancelOverlayPrompt();
}
break;
default:
break;
}
notificationManager?.Dispose();
root.Dispose();
e.Dispose();
}
// Suppress exceptions so that service doesn't crash.
catch { }
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(">>> {0}: {1}", ex.GetType(), ex.StackTrace);
}
}
public override void OnInterrupt()
@@ -170,28 +164,27 @@ namespace Bit.Droid.Accessibility
// Do nothing.
}
public bool ScanAndAutofill(AccessibilityNodeInfo root, AccessibilityEvent e,
NotificationManager notificationManager, bool cancelNotification)
public bool ScanAndAutofill(AccessibilityNodeInfo root, AccessibilityEvent e)
{
var passwordNodes = AccessibilityHelpers.GetWindowNodes(root, e, n => n.Password, false);
if(passwordNodes.Count > 0)
var filled = false;
var uri = AccessibilityHelpers.GetUri(root);
if (uri != null && !uri.Contains(BitwardenWebsite) &&
AccessibilityHelpers.NeedToAutofill(AccessibilityHelpers.LastCredentials, uri))
{
var uri = AccessibilityHelpers.GetUri(root);
if(uri != null && !uri.Contains(BitwardenWebsite))
var allEditTexts = AccessibilityHelpers.GetWindowNodes(root, e, n => AccessibilityHelpers.EditText(n), false);
var usernameEditText = AccessibilityHelpers.GetUsernameEditText(uri, allEditTexts);
var passwordNodes = AccessibilityHelpers.GetWindowNodes(root, e, n => n.Password, false);
if (usernameEditText != null || passwordNodes.Count > 0)
{
if(AccessibilityHelpers.NeedToAutofill(AccessibilityHelpers.LastCredentials, uri))
{
AccessibilityHelpers.GetNodesAndFill(root, e, passwordNodes);
}
else
{
NotifyToAutofill(uri, notificationManager);
cancelNotification = false;
}
AccessibilityHelpers.FillCredentials(usernameEditText, passwordNodes);
filled = true;
_lastAutoFillTime = Java.Lang.JavaSystem.CurrentTimeMillis();
AccessibilityHelpers.LastCredentials = null;
}
AccessibilityHelpers.LastCredentials = null;
allEditTexts.Dispose();
passwordNodes.Dispose();
}
else if(AccessibilityHelpers.LastCredentials != null)
if (AccessibilityHelpers.LastCredentials != null)
{
Task.Run(async () =>
{
@@ -199,81 +192,243 @@ namespace Bit.Droid.Accessibility
AccessibilityHelpers.LastCredentials = null;
});
}
passwordNodes.Dispose();
return cancelNotification;
return filled;
}
private void OnAutofillTileClick()
{
CancelOverlayPrompt();
var root = RootInActiveWindow;
if (root != null && root.PackageName != BitwardenPackage &&
root.PackageName != AccessibilityHelpers.SystemUiPackage &&
!SkipPackage(root.PackageName))
{
var uri = AccessibilityHelpers.GetUri(root);
if (!string.IsNullOrWhiteSpace(uri))
{
var intent = new Intent(this, typeof(AccessibilityActivity));
intent.PutExtra("uri", uri);
intent.SetFlags(ActivityFlags.NewTask | ActivityFlags.SingleTop | ActivityFlags.ClearTop);
StartActivity(intent);
return;
}
}
Toast.MakeText(this, AppResources.AutofillTileUriNotFound, ToastLength.Long).Show();
}
public void CancelNotification(NotificationManager notificationManager, long limit = 250)
private void CancelOverlayPrompt()
{
if(Java.Lang.JavaSystem.CurrentTimeMillis() - _lastNotificationTime < limit)
_overlayAnchorObserverRunning = false;
if (_windowManager != null && _overlayView != null)
{
try
{
_windowManager.RemoveViewImmediate(_overlayView);
System.Diagnostics.Debug.WriteLine(">>> Accessibility Overlay View Removed");
}
catch { }
}
_overlayView = null;
_lastAnchorX = 0;
_lastAnchorY = 0;
_isOverlayAboveAnchor = false;
if (_anchorNode != null)
{
_anchorNode.Recycle();
_anchorNode = null;
}
}
private void OverlayPromptToAutofill(AccessibilityNodeInfo root, AccessibilityEvent e)
{
if (Java.Lang.JavaSystem.CurrentTimeMillis() - _lastAutoFillTime < 1000 ||
AccessibilityHelpers.IsAutofillServicePromptVisible(Windows))
{
return;
}
_lastNotificationUri = null;
notificationManager?.Cancel(AutoFillNotificationId);
}
if (!AccessibilityHelpers.OverlayPermitted())
{
if (Build.VERSION.SdkInt <= BuildVersionCodes.M)
{
// The user has the option of only using the autofill tile and leaving the overlay permission
// disabled, so only show this toast if they're using accessibility without overlay permission on
// a version of Android without quick-action tile support
System.Diagnostics.Debug.WriteLine(">>> Overlay Permission not granted");
Toast.MakeText(this, AppResources.AccessibilityDrawOverPermissionAlert, ToastLength.Long).Show();
}
return;
}
private void NotifyToAutofill(string uri, NotificationManager notificationManager)
{
if(notificationManager == null || string.IsNullOrWhiteSpace(uri))
if (_overlayView != null || _anchorNode != null || _overlayAnchorObserverRunning)
{
CancelOverlayPrompt();
}
var uri = AccessibilityHelpers.GetUri(root);
var fillable = !string.IsNullOrWhiteSpace(uri);
if (fillable)
{
if (_blacklistedUris != null && _blacklistedUris.Any())
{
if (Uri.TryCreate(uri, UriKind.Absolute, out var parsedUri) && parsedUri.Scheme.StartsWith("http"))
{
fillable = !_blacklistedUris.Contains(
string.Format("{0}://{1}", parsedUri.Scheme, parsedUri.Host));
}
else
{
fillable = !_blacklistedUris.Contains(uri);
}
}
}
if (!fillable)
{
return;
}
var now = Java.Lang.JavaSystem.CurrentTimeMillis();
var intent = new Intent(this, typeof(AccessibilityActivity));
intent.PutExtra("uri", uri);
intent.SetFlags(ActivityFlags.NewTask | ActivityFlags.SingleTop | ActivityFlags.ClearTop);
var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.UpdateCurrent);
var notificationContent = Build.VERSION.SdkInt > BuildVersionCodes.KitkatWatch ?
AppResources.BitwardenAutofillServiceNotificationContent :
AppResources.BitwardenAutofillServiceNotificationContentOld;
var builder = new Notification.Builder(this);
builder.SetSmallIcon(Resource.Drawable.shield)
.SetContentTitle(AppResources.BitwardenAutofillService)
.SetContentText(notificationContent)
.SetTicker(notificationContent)
.SetWhen(now)
.SetContentIntent(pendingIntent);
if(Build.VERSION.SdkInt > BuildVersionCodes.KitkatWatch)
_overlayView = AccessibilityHelpers.GetOverlayView(this);
_overlayView.Measure(View.MeasureSpec.MakeMeasureSpec(0, 0),
View.MeasureSpec.MakeMeasureSpec(0, 0));
_overlayViewHeight = _overlayView.MeasuredHeight;
_overlayView.Click += (sender, eventArgs) =>
{
builder.SetVisibility(NotificationVisibility.Secret)
.SetColor(Android.Support.V4.Content.ContextCompat.GetColor(ApplicationContext,
Resource.Color.primary));
CancelOverlayPrompt();
StartActivity(intent);
};
var layoutParams = AccessibilityHelpers.GetOverlayLayoutParams();
var anchorPosition = AccessibilityHelpers.GetOverlayAnchorPosition(this, e.Source,
_overlayViewHeight, _isOverlayAboveAnchor);
layoutParams.X = anchorPosition.X;
layoutParams.Y = anchorPosition.Y;
if (_windowManager == null)
{
_windowManager = GetSystemService(WindowService).JavaCast<IWindowManager>();
}
if(Build.VERSION.SdkInt >= BuildVersionCodes.O)
_anchorNode = e.Source;
_lastAnchorX = anchorPosition.X;
_lastAnchorY = anchorPosition.Y;
_windowManager.AddView(_overlayView, layoutParams);
System.Diagnostics.Debug.WriteLine(">>> Accessibility Overlay View Added at X:{0} Y:{1}",
layoutParams.X, layoutParams.Y);
StartOverlayAnchorObserver();
}
private void StartOverlayAnchorObserver()
{
if (_overlayAnchorObserverRunning)
{
if(_notificationChannel == null)
return;
}
_overlayAnchorObserverRunning = true;
_overlayAnchorObserverRunnable = new Java.Lang.Runnable(() =>
{
if (_overlayAnchorObserverRunning)
{
_notificationChannel = new NotificationChannel("bitwarden_autofill_service",
AppResources.AutofillService, NotificationImportance.Low);
notificationManager.CreateNotificationChannel(_notificationChannel);
AdjustOverlayForScroll();
_handler.PostDelayed(_overlayAnchorObserverRunnable, 250);
}
builder.SetChannelId(_notificationChannel.Id);
}
if(/*Build.VERSION.SdkInt <= BuildVersionCodes.N && */_settingAutofillPersistNotification)
});
_handler.PostDelayed(_overlayAnchorObserverRunnable, 250);
}
private void AdjustOverlayForScroll()
{
if (_overlayView == null || _anchorNode == null ||
AccessibilityHelpers.IsAutofillServicePromptVisible(Windows))
{
builder.SetPriority(-2);
CancelOverlayPrompt();
return;
}
_lastNotificationTime = now;
_lastNotificationUri = uri;
notificationManager.Notify(AutoFillNotificationId, builder.Build());
builder.Dispose();
var root = RootInActiveWindow;
IEnumerable<AccessibilityWindowInfo> windows = null;
if (Build.VERSION.SdkInt > BuildVersionCodes.Kitkat)
{
windows = Windows;
}
var anchorPosition = AccessibilityHelpers.GetOverlayAnchorPosition(this, _anchorNode, root,
windows, _overlayViewHeight, _isOverlayAboveAnchor);
if (anchorPosition == null)
{
CancelOverlayPrompt();
return;
}
else if (anchorPosition.X == -1 && anchorPosition.Y == -1)
{
if (_overlayView.Visibility != ViewStates.Gone)
{
_overlayView.Visibility = ViewStates.Gone;
System.Diagnostics.Debug.WriteLine(">>> Accessibility Overlay View Hidden");
}
return;
}
else if (anchorPosition.X == -1)
{
_isOverlayAboveAnchor = false;
System.Diagnostics.Debug.WriteLine(">>> Accessibility Overlay View Below Anchor");
return;
}
else if (anchorPosition.Y == -1)
{
_isOverlayAboveAnchor = true;
System.Diagnostics.Debug.WriteLine(">>> Accessibility Overlay View Above Anchor");
return;
}
else if (anchorPosition.X == _lastAnchorX && anchorPosition.Y == _lastAnchorY)
{
if (_overlayView.Visibility != ViewStates.Visible)
{
_overlayView.Visibility = ViewStates.Visible;
}
return;
}
var layoutParams = AccessibilityHelpers.GetOverlayLayoutParams();
layoutParams.X = anchorPosition.X;
layoutParams.Y = anchorPosition.Y;
_lastAnchorX = anchorPosition.X;
_lastAnchorY = anchorPosition.Y;
_windowManager.UpdateViewLayout(_overlayView, layoutParams);
if (_overlayView.Visibility != ViewStates.Visible)
{
_overlayView.Visibility = ViewStates.Visible;
}
System.Diagnostics.Debug.WriteLine(">>> Accessibility Overlay View Updated to X:{0} Y:{1}",
layoutParams.X, layoutParams.Y);
}
private bool SkipPackage(string eventPackageName)
{
if(string.IsNullOrWhiteSpace(eventPackageName) ||
if (string.IsNullOrWhiteSpace(eventPackageName) ||
AccessibilityHelpers.FilteredPackageNames.Contains(eventPackageName) ||
eventPackageName.Contains("launcher"))
{
return true;
}
if(_launcherPackageNames == null || _lastLauncherSetBuilt == null ||
if (_launcherPackageNames == null || _lastLauncherSetBuilt == null ||
(DateTime.Now - _lastLauncherSetBuilt.Value) > _rebuildLauncherSpan)
{
// refresh launcher list every now and then
@@ -288,22 +443,29 @@ namespace Bit.Droid.Accessibility
private void LoadServices()
{
if(_storageService == null)
if (_stateService == null)
{
_storageService = ServiceContainer.Resolve<IStorageService>("storageService");
_stateService = ServiceContainer.Resolve<IStateService>("stateService");
}
if (_broadcasterService == null)
{
_broadcasterService = ServiceContainer.Resolve<IBroadcasterService>("broadcasterService");
}
}
private async Task LoadSettingsAsync()
{
var now = DateTime.UtcNow;
if(_lastSettingsReload == null || (now - _lastSettingsReload.Value) > _settingsReloadSpan)
if (_lastSettingsReload == null || (now - _lastSettingsReload.Value) > _settingsReloadSpan)
{
_lastSettingsReload = now;
_settingAutofillPasswordField = await _storageService.GetAsync<bool>(
Constants.AccessibilityAutofillPasswordFieldKey);
_settingAutofillPersistNotification = await _storageService.GetAsync<bool>(
Constants.AccessibilityAutofillPersistNotificationKey);
var uris = await _stateService.GetAutofillBlacklistedUrisAsync();
if (uris != null)
{
_blacklistedUris = new HashSet<string>(uris);
}
var isAutoFillTileAdded = await _stateService.GetAutofillTileAddedAsync();
AccessibilityHelpers.IsAutofillTileAdded = isAutoFillTileAdded.GetValueOrDefault();
}
}
}

View File

@@ -0,0 +1,14 @@
namespace Bit.Droid.Accessibility
{
public class KnownUsernameField
{
public KnownUsernameField(string uriAuthority, (string UriPathWanted, string UsernameViewId)[] accessOptions)
{
UriAuthority = uriAuthority;
AccessOptions = accessOptions;
}
public string UriAuthority { get; set; }
public (string UriPathWanted, string UsernameViewId)[] AccessOptions { get; set; }
}
}

View File

@@ -8,10 +8,11 @@ namespace Bit.Droid.Accessibility
{
public void Dispose()
{
foreach(var item in this)
foreach (var item in this)
{
item.Recycle();
item.Dispose();
}
}
}
}
}

View File

@@ -15,8 +15,7 @@
<AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest>
<MonoAndroidResourcePrefix>Resources</MonoAndroidResourcePrefix>
<MonoAndroidAssetsPrefix>Assets</MonoAndroidAssetsPrefix>
<AndroidUseLatestPlatformSdk>false</AndroidUseLatestPlatformSdk>
<TargetFrameworkVersion>v9.0</TargetFrameworkVersion>
<TargetFrameworkVersion>v11.0</TargetFrameworkVersion>
<AndroidHttpClientHandlerType>Xamarin.Android.Net.AndroidClientHandler</AndroidHttpClientHandlerType>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
@@ -29,14 +28,11 @@
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>3</WarningLevel>
<AndroidLinkMode>None</AndroidLinkMode>
<AndroidEnableMultiDex>true</AndroidEnableMultiDex>
<AndroidSupportedAbis />
<JavaMaximumHeapSize>1G</JavaMaximumHeapSize>
<AndroidLinkSkip>Xamarin.GooglePlayServices.Base;Xamarin.GooglePlayServices.Basement;Xamarin.GooglePlayServices.Measurement;Xamarin.GooglePlayServices.Gcm;BitwardenAndroid;BitwardenApp;Xamarin.Android.Net</AndroidLinkSkip>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugSymbols>false</DebugSymbols>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
@@ -44,13 +40,13 @@
<WarningLevel>4</WarningLevel>
<AndroidManagedSymbols>true</AndroidManagedSymbols>
<AndroidUseSharedRuntime>false</AndroidUseSharedRuntime>
<AndroidSupportedAbis />
<AndroidSupportedAbis>armeabi-v7a;x86;x86_64;arm64-v8a</AndroidSupportedAbis>
<JavaMaximumHeapSize>1G</JavaMaximumHeapSize>
<AndroidEnableMultiDex>true</AndroidEnableMultiDex>
<AndroidLinkSkip>Xamarin.GooglePlayServices.Base;Xamarin.GooglePlayServices.Basement;Xamarin.GooglePlayServices.Measurement;Xamarin.GooglePlayServices.Gcm;BitwardenAndroid;BitwardenApp;Xamarin.Android.Net</AndroidLinkSkip>
<EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk>
<AndroidEnableProfiledAot>true</AndroidEnableProfiledAot>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'FDroid|AnyCPU'">
<DebugSymbols>true</DebugSymbols>
<DebugSymbols>false</DebugSymbols>
<OutputPath>bin\FDroid\</OutputPath>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
@@ -59,12 +55,11 @@
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<DefineConstants>FDROID</DefineConstants>
<AndroidSupportedAbis />
<AndroidSupportedAbis>armeabi-v7a;x86;x86_64;arm64-v8a</AndroidSupportedAbis>
<JavaMaximumHeapSize>1G</JavaMaximumHeapSize>
<AndroidEnableMultiDex>true</AndroidEnableMultiDex>
<AndroidUseSharedRuntime>false</AndroidUseSharedRuntime>
<EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk>
<AndroidLinkSkip>Xamarin.GooglePlayServices.Base;Xamarin.GooglePlayServices.Basement;Xamarin.GooglePlayServices.Measurement;Xamarin.GooglePlayServices.Gcm;BitwardenAndroid;BitwardenApp;Xamarin.Android.Net</AndroidLinkSkip>
<AndroidEnableProfiledAot>true</AndroidEnableProfiledAot>
</PropertyGroup>
<ItemGroup>
<Reference Include="Mono.Android" />
@@ -73,27 +68,31 @@
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Xml" />
<Reference Include="System.Net.Http" Condition="'$(Configuration)'=='FDroid'" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Plugin.CurrentActivity">
<Version>2.1.0.4</Version>
</PackageReference>
<PackageReference Include="Portable.BouncyCastle">
<Version>1.8.5</Version>
<Version>1.8.10</Version>
</PackageReference>
<PackageReference Include="Xamarin.AndroidX.AppCompat" Version="1.3.1.3" />
<PackageReference Include="Xamarin.AndroidX.AutoFill" Version="1.1.0.9" />
<PackageReference Include="Xamarin.AndroidX.CardView" Version="1.0.0.11" />
<PackageReference Include="Xamarin.AndroidX.Legacy.Support.V4" Version="1.0.0.10" />
<PackageReference Include="Xamarin.AndroidX.MediaRouter" Version="1.2.5.2" />
<PackageReference Include="Xamarin.AndroidX.Migration" Version="1.0.8" />
<PackageReference Include="Xamarin.Essentials">
<Version>1.1.0</Version>
<Version>1.7.3</Version>
</PackageReference>
<PackageReference Include="Xamarin.Firebase.Messaging">
<Version>60.1142.1</Version>
<Version>122.0.0</Version>
</PackageReference>
<PackageReference Include="Xamarin.Android.Support.Design" Version="28.0.0.1" />
<PackageReference Include="Xamarin.Android.Support.v7.AppCompat" Version="28.0.0.1" />
<PackageReference Include="Xamarin.Android.Support.v4" Version="28.0.0.1" />
<PackageReference Include="Xamarin.Android.Support.v7.CardView" Version="28.0.0.1" />
<PackageReference Include="Xamarin.Android.Support.v7.MediaRouter" Version="28.0.0.1" />
<PackageReference Include="Xamarin.Google.Android.Material" Version="1.4.0.4" />
<PackageReference Include="Xamarin.Google.Dagger" Version="2.37.0" />
<PackageReference Include="Xamarin.GooglePlayServices.SafetyNet">
<Version>60.1142.1</Version>
<Version>117.0.1</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>
@@ -103,6 +102,7 @@
<Compile Include="Accessibility\AccessibilityService.cs" />
<Compile Include="Accessibility\Browser.cs" />
<Compile Include="Accessibility\NodeList.cs" />
<Compile Include="Accessibility\KnownUsernameField.cs" />
<Compile Include="Autofill\AutofillHelpers.cs" />
<Compile Include="Autofill\AutofillService.cs" />
<Compile Include="Autofill\Field.cs" />
@@ -110,22 +110,26 @@
<Compile Include="Autofill\FilledItem.cs" />
<Compile Include="Autofill\Parser.cs" />
<Compile Include="Autofill\SavedItem.cs" />
<Compile Include="Effects\FabShadowEffect.cs" />
<Compile Include="Effects\FixedSizeEffect.cs" />
<Compile Include="Effects\SelectableLabelEffect.cs" />
<Compile Include="Effects\TabBarEffect.cs" />
<Compile Include="Migration\AndroidKeyStoreStorageService.cs" />
<Compile Include="Push\FirebaseInstanceIdService.cs" />
<Compile Include="Push\FirebaseMessagingService.cs" />
<Compile Include="Receivers\ClearClipboardAlarmReceiver.cs" />
<Compile Include="Receivers\LockAlarmReceiver.cs" />
<Compile Include="Receivers\RestrictionsChangedReceiver.cs" />
<Compile Include="Receivers\EventUploadReceiver.cs" />
<Compile Include="Receivers\PackageReplacedReceiver.cs" />
<Compile Include="Renderers\CipherViewCellRenderer.cs" />
<Compile Include="Renderers\ExtendedGridRenderer.cs" />
<Compile Include="Renderers\ExtendedDatePickerRenderer.cs" />
<Compile Include="Renderers\CustomTabbedRenderer.cs" />
<Compile Include="Renderers\ExtendedStackLayoutRenderer.cs" />
<Compile Include="Renderers\ExtendedStepperRenderer.cs" />
<Compile Include="Renderers\CustomSwitchRenderer.cs" />
<Compile Include="Renderers\ExtendedTimePickerRenderer.cs" />
<Compile Include="Renderers\ExtendedSliderRenderer.cs" />
<Compile Include="Renderers\CustomEditorRenderer.cs" />
<Compile Include="Renderers\CustomPickerRenderer.cs" />
<Compile Include="Renderers\CustomEntryRenderer.cs" />
<Compile Include="Renderers\CustomSearchBarRenderer.cs" />
<Compile Include="Renderers\ExtendedListViewRenderer.cs" />
<Compile Include="Renderers\HybridWebViewRenderer.cs" />
<Compile Include="Services\AndroidPushNotificationService.cs" />
<Compile Include="Services\AndroidLogService.cs" />
@@ -133,37 +137,88 @@
<Compile Include="MainActivity.cs" />
<Compile Include="Resources\Resource.designer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Services\BiometricService.cs" />
<Compile Include="Services\CryptoPrimitiveService.cs" />
<Compile Include="Services\DeviceActionService.cs" />
<Compile Include="Services\LocalizeService.cs" />
<Compile Include="Tiles\AutofillTileService.cs" />
<Compile Include="Tiles\GeneratorTileService.cs" />
<Compile Include="Tiles\MyVaultTileService.cs" />
<Compile Include="Utilities\AndroidHelpers.cs" />
<Compile Include="Utilities\CustomFingerprintDialogFragment.cs" />
<Compile Include="Utilities\HockeyAppCrashManagerListener.cs" />
<Compile Include="Utilities\ThemeHelpers.cs" />
<Compile Include="WebAuthCallbackActivity.cs" />
<Compile Include="Renderers\SelectableLabelRenderer.cs" />
<Compile Include="Services\ClipboardService.cs" />
<Compile Include="Utilities\IntentExtensions.cs" />
<Compile Include="Renderers\CustomPageRenderer.cs" />
</ItemGroup>
<ItemGroup>
<AndroidAsset Include="Assets\FontAwesome.ttf" />
<AndroidAsset Include="Assets\bwi-font.ttf" />
<AndroidAsset Include="Assets\RobotoMono_Regular.ttf" />
<AndroidAsset Include="Assets\MaterialIcons_Regular.ttf" />
<None Include="8bit.keystore.enc" />
<None Include="ci-build-apks.ps1" />
<GoogleServicesJson Include="google-services.json" />
<GoogleServicesJson Include="google-services.json.enc" />
<None Include="fdroid-keystore.jks.enc" />
<None Include="Properties\AndroidManifest.xml" />
<None Include="upload-keystore.jks.enc" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-hdpi\logo_legacy.png" />
<AndroidResource Include="Resources\drawable-hdpi\logo_white_legacy.png" />
<AndroidResource Include="Resources\drawable-xhdpi\logo_legacy.png" />
<AndroidResource Include="Resources\drawable-xhdpi\logo_white_legacy.png" />
<AndroidResource Include="Resources\drawable-xxhdpi\logo_legacy.png" />
<AndroidResource Include="Resources\drawable-xxhdpi\logo_white_legacy.png" />
<AndroidResource Include="Resources\drawable\card.xml" />
<AndroidResource Include="Resources\drawable\cog_environment.xml" />
<AndroidResource Include="Resources\drawable\cog_settings.xml" />
<AndroidResource Include="Resources\drawable\icon.xml" />
<AndroidResource Include="Resources\drawable\ic_launcher_foreground.xml" />
<AndroidResource Include="Resources\drawable\ic_warning.xml" />
<AndroidResource Include="Resources\drawable\id.xml" />
<AndroidResource Include="Resources\drawable\info.xml" />
<AndroidResource Include="Resources\drawable\list_item_bg.xml" />
<AndroidResource Include="Resources\drawable\lock.xml" />
<AndroidResource Include="Resources\drawable\login.xml" />
<AndroidResource Include="Resources\drawable\logo.xml" />
<AndroidResource Include="Resources\drawable\logo_white.xml" />
<AndroidResource Include="Resources\drawable\send.xml" />
<AndroidResource Include="Resources\drawable\pencil.xml" />
<AndroidResource Include="Resources\drawable\plus.xml" />
<AndroidResource Include="Resources\drawable\generate.xml" />
<AndroidResource Include="Resources\drawable\search.xml" />
<AndroidResource Include="Resources\drawable\shield.xml" />
<AndroidResource Include="Resources\drawable-v23\splash_screen.xml" />
<AndroidResource Include="Resources\drawable-v23\splash_screen_dark.xml" />
<AndroidResource Include="Resources\drawable\switch_thumb.xml" />
<AndroidResource Include="Resources\layout\progress_dialog_layout.xml" />
<AndroidResource Include="Resources\layout\Tabbar.axml" />
<AndroidResource Include="Resources\layout\Toolbar.axml" />
<AndroidResource Include="Resources\mipmap-anydpi-v26\ic_launcher.xml" />
<AndroidResource Include="Resources\mipmap-anydpi-v26\ic_launcher_round.xml" />
<AndroidResource Include="Resources\mipmap-hdpi\ic_launcher.png" />
<AndroidResource Include="Resources\mipmap-hdpi\ic_launcher_round.png" />
<AndroidResource Include="Resources\mipmap-mdpi\ic_launcher.png" />
<AndroidResource Include="Resources\mipmap-mdpi\ic_launcher_round.png" />
<AndroidResource Include="Resources\mipmap-xhdpi\ic_launcher.png" />
<AndroidResource Include="Resources\mipmap-xhdpi\ic_launcher_round.png" />
<AndroidResource Include="Resources\mipmap-xxhdpi\ic_launcher.png" />
<AndroidResource Include="Resources\mipmap-xxhdpi\ic_launcher_round.png" />
<AndroidResource Include="Resources\mipmap-xxxhdpi\ic_launcher.png" />
<AndroidResource Include="Resources\mipmap-xxxhdpi\ic_launcher_round.png" />
<AndroidResource Include="Resources\values-night\styles.xml" />
<AndroidResource Include="Resources\values\styles.xml" />
<AndroidResource Include="Resources\values\colors.xml" />
<AndroidResource Include="Resources\values\manifest.xml" />
<AndroidResource Include="Resources\values-v30\manifest.xml" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\splash_screen.xml" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\App\App.csproj">
<Project>{9F1742A7-7D03-4BB3-8FCD-41BC3002B00A}</Project>
<Project>{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}</Project>
<Name>App</Name>
</ProjectReference>
<ProjectReference Include="..\Core\Core.csproj">
@@ -189,279 +244,18 @@
<ItemGroup>
<AndroidResource Include="Resources\values\ic_launcher_background.xml" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\mipmap-xxxhdpi\ic_launcher.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\mipmap-xxxhdpi\ic_launcher_foreground.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\mipmap-xxxhdpi\ic_launcher_round.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\mipmap-anydpi-v26\ic_launcher.xml" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\mipmap-anydpi-v26\ic_launcher_round.xml" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\mipmap-hdpi\ic_launcher.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\mipmap-hdpi\ic_launcher_foreground.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\mipmap-hdpi\ic_launcher_round.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\mipmap-mdpi\ic_launcher.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\mipmap-mdpi\ic_launcher_foreground.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\mipmap-mdpi\ic_launcher_round.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\mipmap-xhdpi\ic_launcher.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\mipmap-xhdpi\ic_launcher_foreground.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\mipmap-xhdpi\ic_launcher_round.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\mipmap-xxhdpi\ic_launcher.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\mipmap-xxhdpi\ic_launcher_foreground.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\mipmap-xxhdpi\ic_launcher_round.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\layout\autofill_listitem.xml" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\login.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-hdpi\login.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xhdpi\login.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxhdpi\login.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxxhdpi\login.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\logo.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\values-v21\styles.xml" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\refresh.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\lock.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-hdpi\logo.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-hdpi\yubikey.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\yubikey.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\shield.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\autofill_use.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\accessibility_notification.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\accessibility_notification_icon.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\accessibility_step1.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\accessibility_step2.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\autofill_enable.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-hdpi\autofill_use.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-hdpi\accessibility_notification.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-hdpi\accessibility_notification_icon.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-hdpi\accessibility_step1.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-hdpi\accessibility_step2.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-hdpi\autofill_enable.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xhdpi\yubikey.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xhdpi\accessibility_notification.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xhdpi\accessibility_notification_icon.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xhdpi\accessibility_step1.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xhdpi\accessibility_step2.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xhdpi\autofill_enable.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xhdpi\autofill_use.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxhdpi\autofill_use.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxhdpi\logo.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxhdpi\yubikey.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxhdpi\accessibility_notification.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxhdpi\accessibility_notification_icon.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxhdpi\accessibility_step1.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxhdpi\accessibility_step2.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxhdpi\autofill_enable.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-hdpi\lock.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-hdpi\refresh.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xhdpi\refresh.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xhdpi\lock.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxhdpi\lock.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxhdpi\refresh.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxxhdpi\lock.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxxhdpi\refresh.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\id.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\card.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-hdpi\id.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-hdpi\card.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xhdpi\id.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xhdpi\card.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxhdpi\id.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxhdpi\card.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxxhdpi\card.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxxhdpi\id.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\icon.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-hdpi\icon.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xhdpi\icon.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxhdpi\icon.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxxhdpi\icon.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\pencil.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\plus.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-hdpi\pencil.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-hdpi\plus.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xhdpi\pencil.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xhdpi\plus.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxhdpi\pencil.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxhdpi\plus.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxxhdpi\plus.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxxhdpi\pencil.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\slider_thumb.xml" />
</ItemGroup>
@@ -471,45 +265,6 @@
<SubType>Designer</SubType>
</AndroidResource>
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\logo_white.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-hdpi\logo_white.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxhdpi\logo_white.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\search.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-hdpi\search.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xhdpi\search.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxhdpi\search.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxxhdpi\search.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\cog.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-hdpi\cog.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xhdpi\cog.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxhdpi\cog.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxxhdpi\cog.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\values\dimens.xml">
<Generator>MSBuild:UpdateGeneratedFiles</Generator>
@@ -517,37 +272,13 @@
</AndroidResource>
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-hdpi\shield.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xhdpi\shield.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxhdpi\shield.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxxhdpi\shield.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\refresh_sm.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-hdpi\refresh_sm.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xhdpi\refresh_sm.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxhdpi\refresh_sm.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxxhdpi\refresh_sm.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\layout\CipherViewCell.axml">
<AndroidResource Include="Resources\xml\app_restrictions.xml">
<Generator>MSBuild:UpdateGeneratedFiles</Generator>
<SubType>Designer</SubType>
</AndroidResource>
</ItemGroup>
<ItemGroup>
<Folder Include="Resources\values-v30\" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
</Project>

Binary file not shown.

Binary file not shown.

View File

@@ -1,14 +1,24 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using Android.Content;
using Android.Service.Autofill;
using Android.Widget;
using System.Linq;
using Android.App;
using System.Threading.Tasks;
using Android.App.Slices;
using Android.Graphics;
using Android.Graphics.Drawables;
using Android.OS;
using Android.Runtime;
using Android.Widget.Inline;
using Bit.App.Resources;
using Bit.Core.Enums;
using Android.Views.Autofill;
using AndroidX.AutoFill.Inline;
using AndroidX.AutoFill.Inline.V1;
using Bit.Core.Abstractions;
using SaveFlags = Android.Service.Autofill.SaveFlags;
namespace Bit.Droid.Autofill
{
@@ -16,124 +26,240 @@ namespace Bit.Droid.Autofill
{
private static int _pendingIntentId = 0;
// These browser work natively with the autofill framework
// These browsers work natively with the Autofill Framework
//
// Be sure:
// - to keep these entries sorted alphabetically and
//
// - ... to keep this list in sync with values in AccessibilityHelpers.SupportedBrowsers [Section A], too.
public static HashSet<string> TrustedBrowsers = new HashSet<string>
{
"org.mozilla.focus",
"org.mozilla.klar",
"com.duckduckgo.mobile.android",
"com.google.android.googlequicksearchbox",
"org.mozilla.focus",
"org.mozilla.focus.beta",
"org.mozilla.focus.nightly",
"org.mozilla.klar",
};
// These browsers work using the compatibility shim for the autofill framework
// These browsers work using the compatibility shim for the Autofill Framework
//
// Be sure:
// - to keep these entries sorted alphabetically,
// - to keep this list in sync with values in Resources/xml/autofillservice.xml, and
//
// - ... to keep this list in sync with values in AccessibilityHelpers.SupportedBrowsers [Section A], too.
public static HashSet<string> CompatBrowsers = new HashSet<string>
{
"org.mozilla.firefox",
"org.mozilla.firefox_beta",
"com.microsoft.emmx",
"com.android.chrome",
"com.chrome.beta",
"alook.browser",
"alook.browser.google",
"com.amazon.cloud9",
"com.android.browser",
"com.android.chrome",
"com.android.htmlviewer",
"com.avast.android.secure.browser",
"com.avg.android.secure.browser",
"com.brave.browser",
"com.brave.browser_beta",
"com.brave.browser_default",
"com.brave.browser_dev",
"com.brave.browser_nightly",
"com.chrome.beta",
"com.chrome.canary",
"com.chrome.dev",
"com.cookiegames.smartcookie",
"com.cookiejarapps.android.smartcookieweb",
"com.ecosia.android",
"com.google.android.apps.chrome",
"com.google.android.apps.chrome_dev",
"com.google.android.captiveportallogin",
"com.jamal2367.styx",
"com.kiwibrowser.browser",
"com.kiwibrowser.browser.dev",
"com.microsoft.emmx",
"com.microsoft.emmx.beta",
"com.microsoft.emmx.canary",
"com.microsoft.emmx.dev",
"com.mmbox.browser",
"com.mmbox.xbrowser",
"com.mycompany.app.soulbrowser",
"com.naver.whale",
"com.opera.browser",
"com.opera.browser.beta",
"com.opera.mini.native",
"com.chrome.dev",
"com.chrome.canary",
"com.google.android.apps.chrome",
"com.google.android.apps.chrome_dev",
"com.yandex.browser",
"com.opera.mini.native.beta",
"com.opera.touch",
"com.qflair.browserq",
"com.qwant.liberty",
"com.sec.android.app.sbrowser",
"com.sec.android.app.sbrowser.beta",
"org.codeaurora.swe.browser",
"com.amazon.cloud9",
"com.stoutner.privacybrowser.free",
"com.stoutner.privacybrowser.standard",
"com.vivaldi.browser",
"com.vivaldi.browser.snapshot",
"com.vivaldi.browser.sopranos",
"com.yandex.browser",
"com.z28j.feel",
"idm.internet.download.manager",
"idm.internet.download.manager.adm.lite",
"idm.internet.download.manager.plus",
"io.github.forkmaintainers.iceraven",
"mark.via",
"mark.via.gp",
"net.slions.fulguris.full.download",
"net.slions.fulguris.full.download.debug",
"net.slions.fulguris.full.playstore",
"net.slions.fulguris.full.playstore.debug",
"org.adblockplus.browser",
"org.adblockplus.browser.beta",
"org.bromite.bromite",
"org.bromite.chromium",
"org.chromium.chrome",
"com.kiwibrowser.browser",
"com.ecosia.android",
"com.opera.mini.native.beta",
"org.mozilla.fennec_aurora",
"com.qwant.liberty",
"com.opera.touch",
"org.codeaurora.swe.browser",
"org.gnu.icecat",
"org.mozilla.fenix",
"org.mozilla.fenix.nightly",
"org.mozilla.fennec_aurora",
"org.mozilla.fennec_fdroid",
"org.mozilla.firefox",
"org.mozilla.firefox_beta",
"org.mozilla.reference.browser",
"org.mozilla.rocket",
"org.torproject.torbrowser",
"org.torproject.torbrowser_alpha",
"org.ungoogled.chromium.extensions.stable",
"org.ungoogled.chromium.stable",
"us.spotco.fennec_dos",
};
// The URLs are blacklisted from autofilling
public static HashSet<string> BlacklistedUris = new HashSet<string>
{
"androidapp://android",
"androidapp://com.android.settings",
"androidapp://com.x8bit.bitwarden",
"androidapp://com.oneplus.applocker",
"androidapp://com.android.settings",
};
public static async Task<List<FilledItem>> GetFillItemsAsync(Parser parser, ICipherService cipherService)
{
if(parser.FieldCollection.FillableForLogin)
if (parser.FieldCollection.FillableForLogin)
{
var ciphers = await cipherService.GetAllDecryptedByUrlAsync(parser.Uri);
if(ciphers.Item1.Any() || ciphers.Item2.Any())
if (ciphers.Item1.Any() || ciphers.Item2.Any())
{
var allCiphers = ciphers.Item1.ToList();
allCiphers.AddRange(ciphers.Item2.ToList());
return allCiphers.Select(c => new FilledItem(c)).ToList();
var nonPromptCiphers = allCiphers.Where(cipher => cipher.Reprompt == CipherRepromptType.None);
return nonPromptCiphers.Select(c => new FilledItem(c)).ToList();
}
}
else if(parser.FieldCollection.FillableForCard)
else if (parser.FieldCollection.FillableForCard)
{
var ciphers = await cipherService.GetAllDecryptedAsync();
return ciphers.Where(c => c.Type == CipherType.Card).Select(c => new FilledItem(c)).ToList();
return ciphers.Where(c => c.Type == CipherType.Card && c.Reprompt == CipherRepromptType.None).Select(c => new FilledItem(c)).ToList();
}
return new List<FilledItem>();
}
public static FillResponse BuildFillResponse(Parser parser, List<FilledItem> items, bool locked)
public static FillResponse.Builder CreateFillResponse(Parser parser, List<FilledItem> items, bool locked,
bool inlineAutofillEnabled, FillRequest fillRequest = null)
{
var responseBuilder = new FillResponse.Builder();
if(items != null && items.Count > 0)
// Acquire inline presentation specs on Android 11+
IList<InlinePresentationSpec> inlinePresentationSpecs = null;
var inlinePresentationSpecsCount = 0;
var inlineMaxSuggestedCount = 0;
if (inlineAutofillEnabled && fillRequest != null && (int)Build.VERSION.SdkInt >= 30)
{
foreach(var item in items)
var inlineSuggestionsRequest = fillRequest.InlineSuggestionsRequest;
inlineMaxSuggestedCount = inlineSuggestionsRequest?.MaxSuggestionCount ?? 0;
inlinePresentationSpecs = inlineSuggestionsRequest?.InlinePresentationSpecs;
inlinePresentationSpecsCount = inlinePresentationSpecs?.Count ?? 0;
}
// Build response
var responseBuilder = new FillResponse.Builder();
if (items != null && items.Count > 0)
{
var maxItems = items.Count;
if (inlineMaxSuggestedCount > 0)
{
var dataset = BuildDataset(parser.ApplicationContext, parser.FieldCollection, item);
if(dataset != null)
// -1 to adjust for 'open vault' option
maxItems = Math.Min(maxItems, inlineMaxSuggestedCount - 1);
}
for (int i = 0; i < maxItems; i++)
{
InlinePresentationSpec inlinePresentationSpec = null;
if (inlinePresentationSpecs != null)
{
if (i < inlinePresentationSpecsCount)
{
inlinePresentationSpec = inlinePresentationSpecs[i];
}
else
{
// If the max suggestion count is larger than the number of specs in the list, then
// the last spec is used for the remainder of the suggestions
inlinePresentationSpec = inlinePresentationSpecs[inlinePresentationSpecsCount - 1];
}
}
var dataset = BuildDataset(parser.ApplicationContext, parser.FieldCollection, items[i],
inlinePresentationSpec);
if (dataset != null)
{
responseBuilder.AddDataset(dataset);
}
}
}
responseBuilder.AddDataset(BuildVaultDataset(parser.ApplicationContext, parser.FieldCollection,
parser.Uri, locked));
AddSaveInfo(parser, responseBuilder, parser.FieldCollection);
parser.Uri, locked, inlinePresentationSpecs));
responseBuilder.SetIgnoredIds(parser.FieldCollection.IgnoreAutofillIds.ToArray());
return responseBuilder.Build();
return responseBuilder;
}
public static Dataset BuildDataset(Context context, FieldCollection fields, FilledItem filledItem)
public static Dataset BuildDataset(Context context, FieldCollection fields, FilledItem filledItem,
InlinePresentationSpec inlinePresentationSpec = null)
{
var datasetBuilder = new Dataset.Builder(
BuildListView(filledItem.Name, filledItem.Subtitle, filledItem.Icon, context));
if(filledItem.ApplyToFields(fields, datasetBuilder))
var overlayPresentation = BuildOverlayPresentation(
filledItem.Name,
filledItem.Subtitle,
filledItem.Icon,
context);
var inlinePresentation = BuildInlinePresentation(
inlinePresentationSpec,
filledItem.Name,
filledItem.Subtitle,
filledItem.Icon,
null,
context);
var datasetBuilder = new Dataset.Builder(overlayPresentation);
if (inlinePresentation != null)
{
datasetBuilder.SetInlinePresentation(inlinePresentation);
}
if (filledItem.ApplyToFields(fields, datasetBuilder))
{
return datasetBuilder.Build();
}
return null;
}
public static Dataset BuildVaultDataset(Context context, FieldCollection fields, string uri, bool locked)
public static Dataset BuildVaultDataset(Context context, FieldCollection fields, string uri, bool locked,
IList<InlinePresentationSpec> inlinePresentationSpecs = null)
{
var intent = new Intent(context, typeof(MainActivity));
intent.PutExtra("autofillFramework", true);
if(fields.FillableForLogin)
if (fields.FillableForLogin)
{
intent.PutExtra("autofillFrameworkFillType", (int)CipherType.Login);
}
else if(fields.FillableForCard)
else if (fields.FillableForCard)
{
intent.PutExtra("autofillFrameworkFillType", (int)CipherType.Card);
}
else if(fields.FillableForIdentity)
else if (fields.FillableForIdentity)
{
intent.PutExtra("autofillFrameworkFillType", (int)CipherType.Identity);
}
@@ -145,24 +271,36 @@ namespace Bit.Droid.Autofill
var pendingIntent = PendingIntent.GetActivity(context, ++_pendingIntentId, intent,
PendingIntentFlags.CancelCurrent);
var view = BuildListView(
var overlayPresentation = BuildOverlayPresentation(
AppResources.AutofillWithBitwarden,
locked ? AppResources.VaultIsLocked : AppResources.GoToMyVault,
Resource.Drawable.icon,
context);
var datasetBuilder = new Dataset.Builder(view);
datasetBuilder.SetAuthentication(pendingIntent.IntentSender);
var inlinePresentation = BuildInlinePresentation(
inlinePresentationSpecs?.Last(),
AppResources.Bitwarden,
locked ? AppResources.VaultIsLocked : AppResources.MyVault,
Resource.Drawable.icon,
pendingIntent,
context);
var datasetBuilder = new Dataset.Builder(overlayPresentation);
if (inlinePresentation != null)
{
datasetBuilder.SetInlinePresentation(inlinePresentation);
}
datasetBuilder.SetAuthentication(pendingIntent?.IntentSender);
// Dataset must have a value set. We will reset this in the main activity when the real item is chosen.
foreach(var autofillId in fields.AutofillIds)
foreach (var autofillId in fields.AutofillIds)
{
datasetBuilder.SetValue(autofillId, AutofillValue.ForText("PLACEHOLDER"));
}
return datasetBuilder.Build();
}
public static RemoteViews BuildListView(string text, string subtext, int iconId, Context context)
public static RemoteViews BuildOverlayPresentation(string text, string subtext, int iconId, Context context)
{
var packageName = context.PackageName;
var view = new RemoteViews(packageName, Resource.Layout.autofill_listitem);
@@ -172,29 +310,105 @@ namespace Bit.Droid.Autofill
return view;
}
public static void AddSaveInfo(Parser parser, FillResponse.Builder responseBuilder, FieldCollection fields)
public static InlinePresentation BuildInlinePresentation(InlinePresentationSpec inlinePresentationSpec,
string text, string subtext, int iconId, PendingIntent pendingIntent, Context context)
{
if ((int)Build.VERSION.SdkInt < 30 || inlinePresentationSpec == null)
{
return null;
}
if (pendingIntent == null)
{
// InlinePresentation requires nonNull pending intent (even though we only utilize one for the
// "my vault" presentation) so we're including an empty one here
pendingIntent = PendingIntent.GetService(context, 0, new Intent(),
PendingIntentFlags.OneShot | PendingIntentFlags.UpdateCurrent);
}
var slice = CreateInlinePresentationSlice(
inlinePresentationSpec,
text,
subtext,
iconId,
"Autofill option",
pendingIntent,
context);
if (slice != null)
{
return new InlinePresentation(slice, inlinePresentationSpec, false);
}
return null;
}
private static Slice CreateInlinePresentationSlice(
InlinePresentationSpec inlinePresentationSpec,
string text,
string subtext,
int iconId,
string contentDescription,
PendingIntent pendingIntent,
Context context)
{
var imeStyle = inlinePresentationSpec.Style;
if (!UiVersions.GetVersions(imeStyle).Contains(UiVersions.InlineUiVersion1))
{
return null;
}
var contentBuilder = InlineSuggestionUi.NewContentBuilder(pendingIntent)
.SetContentDescription(contentDescription);
if (!string.IsNullOrWhiteSpace(text))
{
contentBuilder.SetTitle(text);
}
if (!string.IsNullOrWhiteSpace(subtext))
{
contentBuilder.SetSubtitle(subtext);
}
if (iconId > 0)
{
var icon = Icon.CreateWithResource(context, iconId);
if (icon != null)
{
if (iconId == Resource.Drawable.icon)
{
// Don't tint our logo
icon.SetTintBlendMode(BlendMode.Dst);
}
contentBuilder.SetStartIcon(icon);
}
}
return contentBuilder.Build().JavaCast<InlineSuggestionUi.Content>()?.Slice;
}
public static void AddSaveInfo(Parser parser, FillRequest fillRequest, FillResponse.Builder responseBuilder,
FieldCollection fields)
{
// Docs state that password fields cannot be reliably saved in Compat mode since they will show as
// masked values.
var compatBrowser = CompatBrowsers.Contains(parser.PackageName);
if(compatBrowser && fields.SaveType == SaveDataType.Password)
bool? compatRequest = null;
if (Build.VERSION.SdkInt >= BuildVersionCodes.Q && fillRequest != null)
{
// Attempt to automatically establish compat request mode on Android 10+
compatRequest = (fillRequest.Flags | FillRequest.FlagCompatibilityModeRequest) == fillRequest.Flags;
}
var compatBrowser = compatRequest ?? CompatBrowsers.Contains(parser.PackageName);
if (compatBrowser && fields.SaveType == SaveDataType.Password)
{
return;
}
var requiredIds = fields.GetRequiredSaveFields();
if(fields.SaveType == SaveDataType.Generic || requiredIds.Length == 0)
if (fields.SaveType == SaveDataType.Generic || requiredIds.Length == 0)
{
return;
}
var saveBuilder = new SaveInfo.Builder(fields.SaveType, requiredIds);
var optionalIds = fields.GetOptionalSaveIds();
if(optionalIds.Length > 0)
if (optionalIds.Length > 0)
{
saveBuilder.SetOptionalIds(optionalIds);
}
if(compatBrowser)
if (compatBrowser)
{
saveBuilder.SetFlags(SaveFlags.SaveOnAllViewsInvisible);
}

View File

@@ -1,4 +1,7 @@
using Android;
using System;
using System.Collections.Generic;
using System.Linq;
using Android;
using Android.App;
using Android.Content;
using Android.OS;
@@ -9,8 +12,6 @@ using Bit.Core;
using Bit.Core.Abstractions;
using Bit.Core.Enums;
using Bit.Core.Utilities;
using System.Collections.Generic;
using System.Linq;
namespace Bit.Droid.Autofill
{
@@ -21,110 +22,142 @@ namespace Bit.Droid.Autofill
public class AutofillService : Android.Service.Autofill.AutofillService
{
private ICipherService _cipherService;
private ILockService _lockService;
private IStorageService _storageService;
private IVaultTimeoutService _vaultTimeoutService;
private IPolicyService _policyService;
private IStateService _stateService;
private LazyResolve<ILogger> _logger = new LazyResolve<ILogger>("logger");
public async override void OnFillRequest(FillRequest request, CancellationSignal cancellationSignal,
FillCallback callback)
{
var structure = request.FillContexts?.LastOrDefault()?.Structure;
if(structure == null)
try
{
return;
}
var parser = new Parser(structure, ApplicationContext);
parser.Parse();
if(_storageService == null)
{
_storageService = ServiceContainer.Resolve<IStorageService>("storageService");
}
var shouldAutofill = await parser.ShouldAutofillAsync(_storageService);
if(!shouldAutofill)
{
return;
}
if(_lockService == null)
{
_lockService = ServiceContainer.Resolve<ILockService>("lockService");
}
List<FilledItem> items = null;
var locked = await _lockService.IsLockedAsync();
if(!locked)
{
if(_cipherService == null)
var structure = request.FillContexts?.LastOrDefault()?.Structure;
if (structure == null)
{
_cipherService = ServiceContainer.Resolve<ICipherService>("cipherService");
return;
}
items = await AutofillHelpers.GetFillItemsAsync(parser, _cipherService);
}
// build response
var response = AutofillHelpers.BuildFillResponse(parser, items, locked);
callback.OnSuccess(response);
var parser = new Parser(structure, ApplicationContext);
parser.Parse();
if (_stateService == null)
{
_stateService = ServiceContainer.Resolve<IStateService>("stateService");
}
var shouldAutofill = await parser.ShouldAutofillAsync(_stateService);
if (!shouldAutofill)
{
return;
}
var inlineAutofillEnabled = await _stateService.GetInlineAutofillEnabledAsync() ?? true;
if (_vaultTimeoutService == null)
{
_vaultTimeoutService = ServiceContainer.Resolve<IVaultTimeoutService>("vaultTimeoutService");
}
List<FilledItem> items = null;
await _vaultTimeoutService.CheckVaultTimeoutAsync();
var locked = await _vaultTimeoutService.IsLockedAsync();
if (!locked)
{
if (_cipherService == null)
{
_cipherService = ServiceContainer.Resolve<ICipherService>("cipherService");
}
items = await AutofillHelpers.GetFillItemsAsync(parser, _cipherService);
}
// build response
var response = AutofillHelpers.CreateFillResponse(parser, items, locked, inlineAutofillEnabled, request);
var disableSavePrompt = await _stateService.GetAutofillDisableSavePromptAsync();
if (!disableSavePrompt.GetValueOrDefault())
{
AutofillHelpers.AddSaveInfo(parser, request, response, parser.FieldCollection);
}
callback.OnSuccess(response.Build());
}
catch (Exception e)
{
_logger.Value.Exception(e);
}
}
public async override void OnSaveRequest(SaveRequest request, SaveCallback callback)
{
var structure = request.FillContexts?.LastOrDefault()?.Structure;
if(structure == null)
try
{
return;
}
if(_storageService == null)
{
_storageService = ServiceContainer.Resolve<IStorageService>("storageService");
}
var disableSavePrompt = await _storageService.GetAsync<bool?>(Constants.AutofillDisableSavePromptKey);
if(disableSavePrompt.GetValueOrDefault())
{
return;
}
var parser = new Parser(structure, ApplicationContext);
parser.Parse();
var savedItem = parser.FieldCollection.GetSavedItem();
if(savedItem == null)
{
Toast.MakeText(this, "Unable to save this form.", ToastLength.Short).Show();
return;
}
var intent = new Intent(this, typeof(MainActivity));
intent.SetFlags(ActivityFlags.NewTask | ActivityFlags.ClearTop);
intent.PutExtra("autofillFramework", true);
intent.PutExtra("autofillFrameworkSave", true);
intent.PutExtra("autofillFrameworkType", (int)savedItem.Type);
switch(savedItem.Type)
{
case CipherType.Login:
intent.PutExtra("autofillFrameworkName", parser.Uri
.Replace(Constants.AndroidAppProtocol, string.Empty)
.Replace("https://", string.Empty)
.Replace("http://", string.Empty));
intent.PutExtra("autofillFrameworkUri", parser.Uri);
intent.PutExtra("autofillFrameworkUsername", savedItem.Login.Username);
intent.PutExtra("autofillFrameworkPassword", savedItem.Login.Password);
break;
case CipherType.Card:
intent.PutExtra("autofillFrameworkCardName", savedItem.Card.Name);
intent.PutExtra("autofillFrameworkCardNumber", savedItem.Card.Number);
intent.PutExtra("autofillFrameworkCardExpMonth", savedItem.Card.ExpMonth);
intent.PutExtra("autofillFrameworkCardExpYear", savedItem.Card.ExpYear);
intent.PutExtra("autofillFrameworkCardCode", savedItem.Card.Code);
break;
default:
Toast.MakeText(this, "Unable to save this type of form.", ToastLength.Short).Show();
var structure = request.FillContexts?.LastOrDefault()?.Structure;
if (structure == null)
{
return;
}
if (_stateService == null)
{
_stateService = ServiceContainer.Resolve<IStateService>("stateService");
}
var disableSavePrompt = await _stateService.GetAutofillDisableSavePromptAsync();
if (disableSavePrompt.GetValueOrDefault())
{
return;
}
_policyService ??= ServiceContainer.Resolve<IPolicyService>("policyService");
var personalOwnershipPolicyApplies = await _policyService.PolicyAppliesToUser(PolicyType.PersonalOwnership);
if (personalOwnershipPolicyApplies)
{
return;
}
var parser = new Parser(structure, ApplicationContext);
parser.Parse();
var savedItem = parser.FieldCollection.GetSavedItem();
if (savedItem == null)
{
Toast.MakeText(this, "Unable to save this form.", ToastLength.Short).Show();
return;
}
var intent = new Intent(this, typeof(MainActivity));
intent.SetFlags(ActivityFlags.NewTask | ActivityFlags.ClearTop);
intent.PutExtra("autofillFramework", true);
intent.PutExtra("autofillFrameworkSave", true);
intent.PutExtra("autofillFrameworkType", (int)savedItem.Type);
switch (savedItem.Type)
{
case CipherType.Login:
intent.PutExtra("autofillFrameworkName", parser.Uri
.Replace(Constants.AndroidAppProtocol, string.Empty)
.Replace("https://", string.Empty)
.Replace("http://", string.Empty));
intent.PutExtra("autofillFrameworkUri", parser.Uri);
intent.PutExtra("autofillFrameworkUsername", savedItem.Login.Username);
intent.PutExtra("autofillFrameworkPassword", savedItem.Login.Password);
break;
case CipherType.Card:
intent.PutExtra("autofillFrameworkCardName", savedItem.Card.Name);
intent.PutExtra("autofillFrameworkCardNumber", savedItem.Card.Number);
intent.PutExtra("autofillFrameworkCardExpMonth", savedItem.Card.ExpMonth);
intent.PutExtra("autofillFrameworkCardExpYear", savedItem.Card.ExpYear);
intent.PutExtra("autofillFrameworkCardCode", savedItem.Card.Code);
break;
default:
Toast.MakeText(this, "Unable to save this type of form.", ToastLength.Short).Show();
return;
}
StartActivity(intent);
}
catch (Exception e)
{
_logger.Value.Exception(e);
}
StartActivity(intent);
}
}
}

View File

@@ -31,26 +31,26 @@ namespace Bit.Droid.Autofill
HtmlInfo = node.HtmlInfo;
Node = node;
if(node.AutofillValue != null)
if (node.AutofillValue != null)
{
if(node.AutofillValue.IsList)
if (node.AutofillValue.IsList)
{
var autofillOptions = node.GetAutofillOptions();
if(autofillOptions != null && autofillOptions.Length > 0)
if (autofillOptions != null && autofillOptions.Length > 0)
{
ListValue = node.AutofillValue.ListValue;
TextValue = autofillOptions[node.AutofillValue.ListValue];
}
}
else if(node.AutofillValue.IsDate)
else if (node.AutofillValue.IsDate)
{
DateValue = node.AutofillValue.DateValue;
}
else if(node.AutofillValue.IsText)
else if (node.AutofillValue.IsText)
{
TextValue = node.AutofillValue.TextValue;
}
else if(node.AutofillValue.IsToggle)
else if (node.AutofillValue.IsToggle)
{
ToggleValue = node.AutofillValue.ToggleValue;
}
@@ -93,20 +93,20 @@ namespace Bit.Droid.Autofill
public override bool Equals(object obj)
{
if(this == obj)
if (this == obj)
{
return true;
}
if(obj == null || GetType() != obj.GetType())
if (obj == null || GetType() != obj.GetType())
{
return false;
}
var field = obj as Field;
if(TextValue != null ? !TextValue.Equals(field.TextValue) : field.TextValue != null)
if (TextValue != null ? !TextValue.Equals(field.TextValue) : field.TextValue != null)
{
return false;
}
if(DateValue != null ? !DateValue.Equals(field.DateValue) : field.DateValue != null)
if (DateValue != null ? !DateValue.Equals(field.DateValue) : field.DateValue != null)
{
return false;
}
@@ -128,7 +128,7 @@ namespace Bit.Droid.Autofill
private static bool IsValidHint(string hint)
{
switch(hint)
switch (hint)
{
case View.AutofillHintCreditCardExpirationDate:
case View.AutofillHintCreditCardExpirationDay:
@@ -152,14 +152,14 @@ namespace Bit.Droid.Autofill
private void UpdateSaveTypeFromHints()
{
SaveType = SaveDataType.Generic;
if(_hints == null)
if (_hints == null)
{
return;
}
foreach(var hint in _hints)
foreach (var hint in _hints)
{
switch(hint)
switch (hint)
{
case View.AutofillHintCreditCardExpirationDate:
case View.AutofillHintCreditCardExpirationDay:

View File

@@ -19,11 +19,11 @@ namespace Bit.Droid.Autofill
{
get
{
if(FillableForLogin)
if (FillableForLogin)
{
return SaveDataType.Password;
}
else if(FillableForCard)
else if (FillableForCard)
{
return SaveDataType.CreditCard;
}
@@ -43,14 +43,14 @@ namespace Bit.Droid.Autofill
{
get
{
if(_passwordFields != null)
if (_passwordFields != null)
{
return _passwordFields;
}
if(Hints.Any())
if (Hints.Any())
{
_passwordFields = new List<Field>();
if(HintToFieldsMap.ContainsKey(View.AutofillHintPassword))
if (HintToFieldsMap.ContainsKey(View.AutofillHintPassword))
{
_passwordFields.AddRange(HintToFieldsMap[View.AutofillHintPassword]);
}
@@ -58,7 +58,7 @@ namespace Bit.Droid.Autofill
else
{
_passwordFields = Fields.Where(f => FieldIsPassword(f)).ToList();
if(!_passwordFields.Any())
if (!_passwordFields.Any())
{
_passwordFields = Fields.Where(f => FieldHasPasswordTerms(f)).ToList();
}
@@ -71,29 +71,29 @@ namespace Bit.Droid.Autofill
{
get
{
if(_usernameFields != null)
if (_usernameFields != null)
{
return _usernameFields;
}
_usernameFields = new List<Field>();
if(Hints.Any())
if (Hints.Any())
{
if(HintToFieldsMap.ContainsKey(View.AutofillHintEmailAddress))
if (HintToFieldsMap.ContainsKey(View.AutofillHintEmailAddress))
{
_usernameFields.AddRange(HintToFieldsMap[View.AutofillHintEmailAddress]);
}
if(HintToFieldsMap.ContainsKey(View.AutofillHintUsername))
if (HintToFieldsMap.ContainsKey(View.AutofillHintUsername))
{
_usernameFields.AddRange(HintToFieldsMap[View.AutofillHintUsername]);
}
}
else
{
foreach(var passwordField in PasswordFields)
foreach (var passwordField in PasswordFields)
{
var usernameField = Fields.TakeWhile(f => f.AutofillId != passwordField.AutofillId)
.LastOrDefault();
if(usernameField != null)
if (usernameField != null)
{
_usernameFields.Add(usernameField);
}
@@ -127,7 +127,7 @@ namespace Bit.Droid.Autofill
public void Add(Field field)
{
if(field == null || FieldTrackingIds.Contains(field.TrackingId))
if (field == null || FieldTrackingIds.Contains(field.TrackingId))
{
return;
}
@@ -137,16 +137,16 @@ namespace Bit.Droid.Autofill
Fields.Add(field);
AutofillIds.Add(field.AutofillId);
if(field.Hints != null)
if (field.Hints != null)
{
foreach(var hint in field.Hints)
foreach (var hint in field.Hints)
{
Hints.Add(hint);
if(field.Focused)
if (field.Focused)
{
FocusedHints.Add(hint);
}
if(!HintToFieldsMap.ContainsKey(hint))
if (!HintToFieldsMap.ContainsKey(hint))
{
HintToFieldsMap.Add(hint, new List<Field>());
}
@@ -157,10 +157,10 @@ namespace Bit.Droid.Autofill
public SavedItem GetSavedItem()
{
if(SaveType == SaveDataType.Password)
if (SaveType == SaveDataType.Password)
{
var passwordField = PasswordFields.FirstOrDefault(f => !string.IsNullOrWhiteSpace(f.TextValue));
if(passwordField == null)
if (passwordField == null)
{
return null;
}
@@ -178,7 +178,7 @@ namespace Bit.Droid.Autofill
savedItem.Login.Username = GetFieldValue(usernameField);
return savedItem;
}
else if(SaveType == SaveDataType.CreditCard)
else if (SaveType == SaveDataType.CreditCard)
{
var savedItem = new SavedItem
{
@@ -199,26 +199,26 @@ namespace Bit.Droid.Autofill
public AutofillId[] GetOptionalSaveIds()
{
if(SaveType == SaveDataType.Password)
if (SaveType == SaveDataType.Password)
{
return UsernameFields.Select(f => f.AutofillId).ToArray();
}
else if(SaveType == SaveDataType.CreditCard)
else if (SaveType == SaveDataType.CreditCard)
{
var fieldList = new List<Field>();
if(HintToFieldsMap.ContainsKey(View.AutofillHintCreditCardSecurityCode))
if (HintToFieldsMap.ContainsKey(View.AutofillHintCreditCardSecurityCode))
{
fieldList.AddRange(HintToFieldsMap[View.AutofillHintCreditCardSecurityCode]);
}
if(HintToFieldsMap.ContainsKey(View.AutofillHintCreditCardExpirationYear))
if (HintToFieldsMap.ContainsKey(View.AutofillHintCreditCardExpirationYear))
{
fieldList.AddRange(HintToFieldsMap[View.AutofillHintCreditCardExpirationYear]);
}
if(HintToFieldsMap.ContainsKey(View.AutofillHintCreditCardExpirationMonth))
if (HintToFieldsMap.ContainsKey(View.AutofillHintCreditCardExpirationMonth))
{
fieldList.AddRange(HintToFieldsMap[View.AutofillHintCreditCardExpirationMonth]);
}
if(HintToFieldsMap.ContainsKey(View.AutofillHintName))
if (HintToFieldsMap.ContainsKey(View.AutofillHintName))
{
fieldList.AddRange(HintToFieldsMap[View.AutofillHintName]);
}
@@ -229,11 +229,11 @@ namespace Bit.Droid.Autofill
public AutofillId[] GetRequiredSaveFields()
{
if(SaveType == SaveDataType.Password)
if (SaveType == SaveDataType.Password)
{
return PasswordFields.Select(f => f.AutofillId).ToArray();
}
else if(SaveType == SaveDataType.CreditCard && HintToFieldsMap.ContainsKey(View.AutofillHintCreditCardNumber))
else if (SaveType == SaveDataType.CreditCard && HintToFieldsMap.ContainsKey(View.AutofillHintCreditCardNumber))
{
return HintToFieldsMap[View.AutofillHintCreditCardNumber].Select(f => f.AutofillId).ToArray();
}
@@ -247,12 +247,12 @@ namespace Bit.Droid.Autofill
private string GetFieldValue(string hint, bool monthValue = false)
{
if(HintToFieldsMap.ContainsKey(hint))
if (HintToFieldsMap.ContainsKey(hint))
{
foreach(var field in HintToFieldsMap[hint])
foreach (var field in HintToFieldsMap[hint])
{
var val = GetFieldValue(field, monthValue);
if(!string.IsNullOrWhiteSpace(val))
if (!string.IsNullOrWhiteSpace(val))
{
return val;
}
@@ -263,30 +263,30 @@ namespace Bit.Droid.Autofill
private string GetFieldValue(Field field, bool monthValue = false)
{
if(field == null)
if (field == null)
{
return null;
}
if(!string.IsNullOrWhiteSpace(field.TextValue))
if (!string.IsNullOrWhiteSpace(field.TextValue))
{
if(field.AutofillType == AutofillType.List && field.ListValue.HasValue && monthValue)
if (field.AutofillType == AutofillType.List && field.ListValue.HasValue && monthValue)
{
if(field.AutofillOptions.Count == 13)
if (field.AutofillOptions.Count == 13)
{
return field.ListValue.ToString();
}
else if(field.AutofillOptions.Count == 12)
else if (field.AutofillOptions.Count == 12)
{
return (field.ListValue + 1).ToString();
}
}
return field.TextValue;
}
else if(field.DateValue.HasValue)
else if (field.DateValue.HasValue)
{
return field.DateValue.Value.ToString();
}
else if(field.ToggleValue.HasValue)
else if (field.ToggleValue.HasValue)
{
return field.ToggleValue.Value.ToString();
}
@@ -300,20 +300,20 @@ namespace Bit.Droid.Autofill
f.InputType.HasFlag(InputTypes.TextVariationWebPassword);
// For whatever reason, multi-line input types are coming through with TextVariationPassword flags
if(inputTypePassword && f.InputType.HasFlag(InputTypes.TextVariationPassword) &&
if (inputTypePassword && f.InputType.HasFlag(InputTypes.TextVariationPassword) &&
f.InputType.HasFlag(InputTypes.TextFlagMultiLine))
{
inputTypePassword = false;
}
if(!inputTypePassword && f.HtmlInfo != null && f.HtmlInfo.Tag == "input" &&
if (!inputTypePassword && f.HtmlInfo != null && f.HtmlInfo.Tag == "input" &&
(f.HtmlInfo.Attributes?.Any() ?? false))
{
foreach(var a in f.HtmlInfo.Attributes)
foreach (var a in f.HtmlInfo.Attributes)
{
var key = a.First as Java.Lang.String;
var val = a.Second as Java.Lang.String;
if(key != null && val != null && key.ToString() == "type" && val.ToString() == "password")
if (key != null && val != null && key.ToString() == "type" && val.ToString() == "password")
{
return true;
}
@@ -331,7 +331,7 @@ namespace Bit.Droid.Autofill
private bool ValueContainsAnyTerms(string value, HashSet<string> terms)
{
if(string.IsNullOrWhiteSpace(value))
if (string.IsNullOrWhiteSpace(value))
{
return false;
}

View File

@@ -27,7 +27,7 @@ namespace Bit.Droid.Autofill
Type = cipher.Type;
Subtitle = cipher.SubTitle;
switch(Type)
switch (Type)
{
case CipherType.Login:
Icon = Resource.Drawable.login;
@@ -62,32 +62,32 @@ namespace Bit.Droid.Autofill
public bool ApplyToFields(FieldCollection fieldCollection, Dataset.Builder datasetBuilder)
{
if(!fieldCollection?.Fields.Any() ?? true)
if (!fieldCollection?.Fields.Any() ?? true)
{
return false;
}
var setValues = false;
if(Type == CipherType.Login)
if (Type == CipherType.Login)
{
if(fieldCollection.PasswordFields.Any() && !string.IsNullOrWhiteSpace(_password))
if (fieldCollection.PasswordFields.Any() && !string.IsNullOrWhiteSpace(_password))
{
foreach(var f in fieldCollection.PasswordFields)
foreach (var f in fieldCollection.PasswordFields)
{
var val = ApplyValue(f, _password);
if(val != null)
if (val != null)
{
setValues = true;
datasetBuilder.SetValue(f.AutofillId, val);
}
}
}
if(fieldCollection.UsernameFields.Any() && !string.IsNullOrWhiteSpace(Subtitle))
if (fieldCollection.UsernameFields.Any() && !string.IsNullOrWhiteSpace(Subtitle))
{
foreach(var f in fieldCollection.UsernameFields)
foreach (var f in fieldCollection.UsernameFields)
{
var val = ApplyValue(f, Subtitle);
if(val != null)
if (val != null)
{
setValues = true;
datasetBuilder.SetValue(f.AutofillId, val);
@@ -95,59 +95,59 @@ namespace Bit.Droid.Autofill
}
}
}
else if(Type == CipherType.Card)
else if (Type == CipherType.Card)
{
if(ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintCreditCardNumber,
if (ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintCreditCardNumber,
_cardNumber))
{
setValues = true;
}
if(ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintCreditCardSecurityCode,
if (ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintCreditCardSecurityCode,
_cardCode))
{
setValues = true;
}
if(ApplyValue(datasetBuilder, fieldCollection,
if (ApplyValue(datasetBuilder, fieldCollection,
Android.Views.View.AutofillHintCreditCardExpirationMonth, _cardExpMonth, true))
{
setValues = true;
}
if(ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintCreditCardExpirationYear,
if (ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintCreditCardExpirationYear,
_cardExpYear))
{
setValues = true;
}
if(ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintName, _cardName))
if (ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintName, _cardName))
{
setValues = true;
}
}
else if(Type == CipherType.Identity)
else if (Type == CipherType.Identity)
{
if(ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintPhone, _idPhone))
if (ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintPhone, _idPhone))
{
setValues = true;
}
if(ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintEmailAddress, _idEmail))
if (ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintEmailAddress, _idEmail))
{
setValues = true;
}
if(ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintUsername,
if (ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintUsername,
_idUsername))
{
setValues = true;
}
if(ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintPostalAddress,
if (ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintPostalAddress,
_idAddress))
{
setValues = true;
}
if(ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintPostalCode,
if (ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintPostalCode,
_idPostalCode))
{
setValues = true;
}
if(ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintName, Subtitle))
if (ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintName, Subtitle))
{
setValues = true;
}
@@ -159,12 +159,12 @@ namespace Bit.Droid.Autofill
string hint, string value, bool monthValue = false)
{
bool setValues = false;
if(fieldCollection.HintToFieldsMap.ContainsKey(hint) && !string.IsNullOrWhiteSpace(value))
if (fieldCollection.HintToFieldsMap.ContainsKey(hint) && !string.IsNullOrWhiteSpace(value))
{
foreach(var f in fieldCollection.HintToFieldsMap[hint])
foreach (var f in fieldCollection.HintToFieldsMap[hint])
{
var val = ApplyValue(f, value, monthValue);
if(val != null)
if (val != null)
{
setValues = true;
builder.SetValue(f.AutofillId, val);
@@ -176,31 +176,31 @@ namespace Bit.Droid.Autofill
private static AutofillValue ApplyValue(Field field, string value, bool monthValue = false)
{
switch(field.AutofillType)
switch (field.AutofillType)
{
case AutofillType.Date:
if(long.TryParse(value, out long dateValue))
if (long.TryParse(value, out long dateValue))
{
return AutofillValue.ForDate(dateValue);
}
break;
case AutofillType.List:
if(field.AutofillOptions != null)
if (field.AutofillOptions != null)
{
if(monthValue && int.TryParse(value, out int monthIndex))
if (monthValue && int.TryParse(value, out int monthIndex))
{
if(field.AutofillOptions.Count == 13)
if (field.AutofillOptions.Count == 13)
{
return AutofillValue.ForList(monthIndex);
}
else if(field.AutofillOptions.Count >= monthIndex)
else if (field.AutofillOptions.Count >= monthIndex)
{
return AutofillValue.ForList(monthIndex - 1);
}
}
for(var i = 0; i < field.AutofillOptions.Count; i++)
for (var i = 0; i < field.AutofillOptions.Count; i++)
{
if(field.AutofillOptions[i].Equals(value))
if (field.AutofillOptions[i].Equals(value))
{
return AutofillValue.ForList(i);
}
@@ -210,7 +210,7 @@ namespace Bit.Droid.Autofill
case AutofillType.Text:
return AutofillValue.ForText(value);
case AutofillType.Toggle:
if(bool.TryParse(value, out bool toggleValue))
if (bool.TryParse(value, out bool toggleValue))
{
return AutofillValue.ForToggle(toggleValue);
}
@@ -221,4 +221,4 @@ namespace Bit.Droid.Autofill
return null;
}
}
}
}

View File

@@ -5,6 +5,7 @@ using Bit.Core;
using Android.Content;
using Bit.Core.Abstractions;
using System.Threading.Tasks;
using Android.OS;
namespace Bit.Droid.Autofill
{
@@ -17,7 +18,7 @@ namespace Bit.Droid.Autofill
private readonly AssistStructure _structure;
private string _uri;
private string _packageName;
private string _webDomain;
private string _website;
public Parser(AssistStructure structure, Context applicationContext)
{
@@ -32,18 +33,18 @@ namespace Bit.Droid.Autofill
{
get
{
if(!string.IsNullOrWhiteSpace(_uri))
if (!string.IsNullOrWhiteSpace(_uri))
{
return _uri;
}
var webDomainNull = string.IsNullOrWhiteSpace(WebDomain);
if(webDomainNull && string.IsNullOrWhiteSpace(PackageName))
var websiteNull = string.IsNullOrWhiteSpace(Website);
if (websiteNull && string.IsNullOrWhiteSpace(PackageName))
{
_uri = null;
}
else if(!webDomainNull)
else if (!websiteNull)
{
_uri = string.Concat("http://", WebDomain);
_uri = Website;
}
else
{
@@ -58,7 +59,7 @@ namespace Bit.Droid.Autofill
get => _packageName;
set
{
if(string.IsNullOrWhiteSpace(value))
if (string.IsNullOrWhiteSpace(value))
{
_packageName = _uri = null;
}
@@ -66,27 +67,27 @@ namespace Bit.Droid.Autofill
}
}
public string WebDomain
public string Website
{
get => _webDomain;
get => _website;
set
{
if(string.IsNullOrWhiteSpace(value))
if (string.IsNullOrWhiteSpace(value))
{
_webDomain = _uri = null;
_website = _uri = null;
}
_webDomain = value;
_website = value;
}
}
public async Task<bool> ShouldAutofillAsync(IStorageService storageService)
public async Task<bool> ShouldAutofillAsync(IStateService stateService)
{
var fillable = !string.IsNullOrWhiteSpace(Uri) && !AutofillHelpers.BlacklistedUris.Contains(Uri) &&
FieldCollection != null && FieldCollection.Fillable;
if(fillable)
if (fillable)
{
var blacklistedUris = await storageService.GetAsync<List<string>>(Constants.AutofillBlacklistedUrisKey);
if(blacklistedUris != null && blacklistedUris.Count > 0)
var blacklistedUris = await stateService.GetAutofillBlacklistedUrisAsync();
if (blacklistedUris != null && blacklistedUris.Count > 0)
{
fillable = !new HashSet<string>(blacklistedUris).Contains(Uri);
}
@@ -96,15 +97,24 @@ namespace Bit.Droid.Autofill
public void Parse()
{
for(var i = 0; i < _structure.WindowNodeCount; i++)
string titlePackageId = null;
for (var i = 0; i < _structure.WindowNodeCount; i++)
{
var node = _structure.GetWindowNodeAt(i);
if (i == 0)
{
titlePackageId = GetTitlePackageId(node);
}
ParseNode(node.RootViewNode);
}
if(!AutofillHelpers.TrustedBrowsers.Contains(PackageName) &&
if (string.IsNullOrWhiteSpace(PackageName) && string.IsNullOrWhiteSpace(Website))
{
PackageName = titlePackageId;
}
if (!AutofillHelpers.TrustedBrowsers.Contains(PackageName) &&
!AutofillHelpers.CompatBrowsers.Contains(PackageName))
{
WebDomain = null;
Website = null;
}
}
@@ -113,7 +123,7 @@ namespace Bit.Droid.Autofill
SetPackageAndDomain(node);
var hints = node.GetAutofillHints();
var isEditText = node.ClassName == "android.widget.EditText" || node?.HtmlInfo?.Tag == "input";
if(isEditText || (hints?.Length ?? 0) > 0)
if (isEditText || (hints?.Length ?? 0) > 0)
{
FieldCollection.Add(new Field(node));
}
@@ -122,7 +132,7 @@ namespace Bit.Droid.Autofill
FieldCollection.IgnoreAutofillIds.Add(node.AutofillId);
}
for(var i = 0; i < node.ChildCount; i++)
for (var i = 0; i < node.ChildCount; i++)
{
ParseNode(node.GetChildAt(i));
}
@@ -130,15 +140,37 @@ namespace Bit.Droid.Autofill
private void SetPackageAndDomain(ViewNode node)
{
if(string.IsNullOrWhiteSpace(PackageName) && !string.IsNullOrWhiteSpace(node.IdPackage) &&
if (string.IsNullOrWhiteSpace(PackageName) && !string.IsNullOrWhiteSpace(node.IdPackage) &&
!_excludedPackageIds.Contains(node.IdPackage))
{
PackageName = node.IdPackage;
}
if(string.IsNullOrWhiteSpace(WebDomain) && !string.IsNullOrWhiteSpace(node.WebDomain))
if (string.IsNullOrWhiteSpace(Website) && !string.IsNullOrWhiteSpace(node.WebDomain))
{
WebDomain = node.WebDomain;
var scheme = "http";
if ((int)Build.VERSION.SdkInt >= 28)
{
scheme = node.WebScheme;
}
Website = string.Format("{0}://{1}", scheme, node.WebDomain);
}
}
private string GetTitlePackageId(WindowNode node)
{
if (node != null && !string.IsNullOrWhiteSpace(node.Title))
{
var slashPosition = node.Title.IndexOf('/');
if (slashPosition > -1)
{
var packageId = node.Title.Substring(0, slashPosition);
if (packageId.Contains("."))
{
return packageId;
}
}
}
return null;
}
}
}

View File

@@ -0,0 +1,30 @@
using Android.Graphics.Drawables;
using Bit.Droid.Effects;
using Bit.Droid.Utilities;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportEffect(typeof(FabShadowEffect), "FabShadowEffect")]
namespace Bit.Droid.Effects
{
public class FabShadowEffect : PlatformEffect
{
protected override void OnAttached ()
{
if (Control is Android.Widget.Button button)
{
var gd = new GradientDrawable();
gd.SetColor(ThemeHelpers.FabColor);
gd.SetCornerRadius(100);
button.SetBackground(gd);
button.Elevation = 6;
button.TranslationZ = 20;
}
}
protected override void OnDetached ()
{
}
}
}

View File

@@ -1,7 +1,4 @@
using Android.Support.Design.BottomNavigation;
using Android.Support.Design.Widget;
using Android.Views;
using Android.Widget;
using Android.Widget;
using Bit.Droid.Effects;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
@@ -13,7 +10,7 @@ namespace Bit.Droid.Effects
{
protected override void OnAttached()
{
if(Element is Label label && Control is TextView textView)
if (Element is Label label && Control is TextView textView)
{
textView.SetTextSize(Android.Util.ComplexUnitType.Pt, (float)label.FontSize);
}
@@ -23,4 +20,4 @@ namespace Bit.Droid.Effects
{
}
}
}
}

View File

@@ -1,26 +0,0 @@
using Android.Support.Design.BottomNavigation;
using Android.Support.Design.Widget;
using Android.Views;
using Android.Widget;
using Bit.Droid.Effects;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportEffect(typeof(SelectableLabelEffect), "SelectableLabelEffect")]
namespace Bit.Droid.Effects
{
public class SelectableLabelEffect : PlatformEffect
{
protected override void OnAttached()
{
if(Control is TextView textView)
{
textView.SetTextIsSelectable(true);
}
}
protected override void OnDetached()
{
}
}
}

View File

@@ -1,7 +1,6 @@
using Android.Support.Design.BottomNavigation;
using Android.Support.Design.Widget;
using Android.Views;
using Android.Views;
using Bit.Droid.Effects;
using Google.Android.Material.BottomNavigation;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
@@ -13,11 +12,11 @@ namespace Bit.Droid.Effects
{
protected override void OnAttached()
{
if(!(Container.GetChildAt(0) is ViewGroup layout))
if (!(Container.GetChildAt(0) is ViewGroup layout))
{
return;
}
if(!(layout.GetChildAt(1) is BottomNavigationView bottomNavigationView))
if (!(layout.GetChildAt(1) is BottomNavigationView bottomNavigationView))
{
return;
}
@@ -28,4 +27,4 @@ namespace Bit.Droid.Effects
{
}
}
}
}

View File

@@ -1,45 +1,41 @@
using Android.App;
using Android.Content.PM;
using Android.Runtime;
using Android.OS;
using Bit.Core;
using System.Linq;
using Bit.App.Abstractions;
using Bit.Core.Utilities;
using Bit.Core.Abstractions;
using System;
using System.IO;
using System;
using Android.Content;
using Bit.Droid.Utilities;
using Bit.Droid.Receivers;
using Bit.App.Models;
using Bit.Core.Enums;
using Android.Nfc;
using Bit.App.Utilities;
using System.Linq;
using System.Threading.Tasks;
using Android.App;
using Android.Content;
using Android.Content.PM;
using Android.Nfc;
using Android.OS;
using Android.Runtime;
using AndroidX.Core.Content;
using Bit.App.Abstractions;
using Bit.App.Models;
using Bit.App.Utilities;
using Bit.Core;
using Bit.Core.Abstractions;
using Bit.Core.Enums;
using Bit.Core.Utilities;
using Bit.Droid.Receivers;
using Bit.Droid.Utilities;
using ZXing.Net.Mobile.Android;
namespace Bit.Droid
{
[Activity(
Label = "Bitwarden",
Icon = "@mipmap/ic_launcher",
Theme = "@style/LightTheme.Splash",
MainLauncher = true,
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
// Activity and IntentFilter declarations have been moved to Properties/AndroidManifest.xml
// They have been hardcoded so we can use the default LaunchMode on Android 11+
// LaunchMode defined in values/manifest.xml for Android 10- and values-v30/manifest.xml for Android 11+
// See https://github.com/bitwarden/mobile/pull/1673 for details
[Register("com.x8bit.bitwarden.MainActivity")]
public class MainActivity : Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
private const string HockeyAppId = "d3834185b4a643479047b86c65293d42";
private IDeviceActionService _deviceActionService;
private IMessagingService _messagingService;
private IBroadcasterService _broadcasterService;
private IUserService _userService;
private IAppIdService _appIdService;
private IStorageService _storageService;
private IStateService _stateService;
private PendingIntent _lockAlarmPendingIntent;
private PendingIntent _clearClipboardPendingIntent;
private IAppIdService _appIdService;
private IEventService _eventService;
private PendingIntent _eventUploadPendingIntent;
private AppOptions _appOptions;
private string _activityKey = $"{nameof(MainActivity)}_{Java.Lang.JavaSystem.CurrentTimeMillis().ToString()}";
private Java.Util.Regex.Pattern _otpPattern =
@@ -47,11 +43,8 @@ namespace Bit.Droid
protected override void OnCreate(Bundle savedInstanceState)
{
var alarmIntent = new Intent(this, typeof(LockAlarmReceiver));
_lockAlarmPendingIntent = PendingIntent.GetBroadcast(this, 0, alarmIntent,
PendingIntentFlags.UpdateCurrent);
var clearClipboardIntent = new Intent(this, typeof(ClearClipboardAlarmReceiver));
_clearClipboardPendingIntent = PendingIntent.GetBroadcast(this, 0, clearClipboardIntent,
var eventUploadIntent = new Intent(this, typeof(EventUploadReceiver));
_eventUploadPendingIntent = PendingIntent.GetBroadcast(this, 0, eventUploadIntent,
PendingIntentFlags.UpdateCurrent);
var policy = new StrictMode.ThreadPolicy.Builder().PermitAll().Build();
@@ -60,67 +53,62 @@ namespace Bit.Droid
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
_messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
_broadcasterService = ServiceContainer.Resolve<IBroadcasterService>("broadcasterService");
_userService = ServiceContainer.Resolve<IUserService>("userService");
_appIdService = ServiceContainer.Resolve<IAppIdService>("appIdService");
_storageService = ServiceContainer.Resolve<IStorageService>("storageService");
_stateService = ServiceContainer.Resolve<IStateService>("stateService");
_appIdService = ServiceContainer.Resolve<IAppIdService>("appIdService");
_eventService = ServiceContainer.Resolve<IEventService>("eventService");
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
UpdateTheme(ThemeManager.GetTheme());
// this needs to be called here before base.OnCreate(...)
Intent?.Validate();
base.OnCreate(savedInstanceState);
if(!CoreHelpers.InDebugMode())
if (!CoreHelpers.InDebugMode())
{
Window.AddFlags(Android.Views.WindowManagerFlags.Secure);
}
#if !FDROID
var hockeyAppListener = new HockeyAppCrashManagerListener(_appIdService, _userService);
var hockeyAppTask = hockeyAppListener.InitAsync();
HockeyApp.Android.CrashManager.Register(this, HockeyAppId, hockeyAppListener);
#endif
ServiceContainer.Resolve<ILogger>("logger").InitAsync();
var toplayout = Window?.DecorView?.RootView;
if (toplayout != null)
{
toplayout.FilterTouchesWhenObscured = true;
}
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
Xamarin.Forms.Forms.Init(this, savedInstanceState);
_appOptions = GetOptions();
LoadApplication(new App.App(_appOptions));
_broadcasterService.Subscribe(_activityKey, (message) =>
{
if(message.Command == "scheduleLockTimer")
if (message.Command == "startEventTimer")
{
var lockOptionMinutes = (int)message.Data;
var lockOptionMs = lockOptionMinutes * 60000;
var triggerMs = Java.Lang.JavaSystem.CurrentTimeMillis() + lockOptionMs + 10;
var alarmManager = GetSystemService(AlarmService) as AlarmManager;
alarmManager.Set(AlarmType.RtcWakeup, triggerMs, _lockAlarmPendingIntent);
StartEventAlarm();
}
else if(message.Command == "cancelLockTimer")
else if (message.Command == "stopEventTimer")
{
var alarmManager = GetSystemService(AlarmService) as AlarmManager;
alarmManager.Cancel(_lockAlarmPendingIntent);
var task = StopEventAlarmAsync();
}
else if(message.Command == "finishMainActivity")
else if (message.Command == "finishMainActivity")
{
Xamarin.Forms.Device.BeginInvokeOnMainThread(() => Finish());
}
else if(message.Command == "listenYubiKeyOTP")
else if (message.Command == "listenYubiKeyOTP")
{
ListenYubiKey((bool)message.Data);
}
else if(message.Command == "updatedTheme")
else if (message.Command == "updatedTheme")
{
RestartApp();
Xamarin.Forms.Device.BeginInvokeOnMainThread(() => AppearanceAdjustments());
}
else if(message.Command == "exit")
else if (message.Command == "exit")
{
ExitApp();
}
else if(message.Command == "copiedToClipboard")
{
var task = ClearClipboardAlarmAsync(message.Data as Tuple<string, int?, bool>);
}
});
}
@@ -133,7 +121,12 @@ namespace Bit.Droid
protected override void OnResume()
{
base.OnResume();
if(_deviceActionService.SupportsNfc())
Xamarin.Essentials.Platform.OnResume();
AppearanceAdjustments();
ThemeManager.UpdateThemeOnPagesAsync();
if (_deviceActionService.SupportsNfc())
{
try
{
@@ -141,39 +134,65 @@ namespace Bit.Droid
}
catch { }
}
AndroidHelpers.SetPreconfiguredRestrictionSettingsAsync(this)
.GetAwaiter()
.GetResult();
}
protected override void OnNewIntent(Intent intent)
{
base.OnNewIntent(intent);
if(intent.GetBooleanExtra("generatorTile", false))
try
{
_messagingService.Send("popAllAndGoToTabGenerator");
if(_appOptions != null)
if (intent?.GetStringExtra("uri") is string uri)
{
_appOptions.GeneratorTile = true;
_messagingService.Send("popAllAndGoToAutofillCiphers");
if (_appOptions != null)
{
_appOptions.Uri = uri;
}
}
else if (intent.GetBooleanExtra("generatorTile", false))
{
_messagingService.Send("popAllAndGoToTabGenerator");
if (_appOptions != null)
{
_appOptions.GeneratorTile = true;
}
}
else if (intent.GetBooleanExtra("myVaultTile", false))
{
_messagingService.Send("popAllAndGoToTabMyVault");
if (_appOptions != null)
{
_appOptions.MyVaultTile = true;
}
}
else if (intent.Action == Intent.ActionSend && intent.Type != null)
{
if (_appOptions != null)
{
_appOptions.CreateSend = GetCreateSendRequest(intent);
}
_messagingService.Send("popAllAndGoToTabSend");
}
else
{
ParseYubiKey(intent.DataString);
}
}
if(intent.GetBooleanExtra("myVaultTile", false))
catch (Exception e)
{
_messagingService.Send("popAllAndGoToTabMyVault");
if(_appOptions != null)
{
_appOptions.MyVaultTile = true;
}
}
else
{
ParseYubiKey(intent.DataString);
System.Diagnostics.Debug.WriteLine(">>> {0}: {1}", e.GetType(), e.StackTrace);
}
}
public async override void OnRequestPermissionsResult(int requestCode, string[] permissions,
[GeneratedEnum] Permission[] grantResults)
{
if(requestCode == Constants.SelectFilePermissionRequestCode)
if (requestCode == Constants.SelectFilePermissionRequestCode)
{
if(grantResults.Any(r => r != Permission.Granted))
if (grantResults.Any(r => r != Permission.Granted))
{
_messagingService.Send("selectFileCameraPermissionDenied");
}
@@ -182,19 +201,19 @@ namespace Bit.Droid
else
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
ZXing.Net.Mobile.Forms.Android.PermissionsHandler.OnRequestPermissionsResult(
requestCode, permissions, grantResults);
PermissionsHandler.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
if(requestCode == Constants.SelectFileRequestCode && resultCode == Result.Ok)
if (resultCode == Result.Ok &&
(requestCode == Constants.SelectFileRequestCode || requestCode == Constants.SaveFileRequestCode))
{
Android.Net.Uri uri = null;
string fileName = null;
if(data != null && data.Data != null)
if (data != null && data.Data != null)
{
uri = data.Data;
fileName = AndroidHelpers.GetFileName(ApplicationContext, uri);
@@ -202,27 +221,34 @@ namespace Bit.Droid
else
{
// camera
var root = new Java.IO.File(Android.OS.Environment.ExternalStorageDirectory, "bitwarden");
var file = new Java.IO.File(root, "temp_camera_photo.jpg");
uri = Android.Net.Uri.FromFile(file);
var file = new Java.IO.File(FilesDir, "temp_camera_photo.jpg");
uri = FileProvider.GetUriForFile(this, "com.x8bit.bitwarden.fileprovider", file);
fileName = $"photo_{DateTime.UtcNow.ToString("yyyyMMddHHmmss")}.jpg";
}
if(uri == null)
if (uri == null)
{
return;
}
if (requestCode == Constants.SaveFileRequestCode)
{
_messagingService.Send("selectSaveFileResult",
new Tuple<string, string>(uri.ToString(), fileName));
return;
}
try
{
using(var stream = ContentResolver.OpenInputStream(uri))
using(var memoryStream = new MemoryStream())
using (var stream = ContentResolver.OpenInputStream(uri))
using (var memoryStream = new MemoryStream())
{
stream.CopyTo(memoryStream);
_messagingService.Send("selectFileResult",
new Tuple<byte[], string>(memoryStream.ToArray(), fileName ?? "unknown_file_name"));
}
}
catch(Java.IO.FileNotFoundException)
catch (Java.IO.FileNotFoundException)
{
return;
}
@@ -237,12 +263,12 @@ namespace Bit.Droid
private void ListenYubiKey(bool listen)
{
if(!_deviceActionService.SupportsNfc())
if (!_deviceActionService.SupportsNfc())
{
return;
}
var adapter = NfcAdapter.GetDefaultAdapter(this);
if(listen)
if (listen)
{
var intent = new Intent(this, Class);
intent.AddFlags(ActivityFlags.SingleTop);
@@ -276,14 +302,15 @@ namespace Bit.Droid
Uri = Intent.GetStringExtra("uri") ?? Intent.GetStringExtra("autofillFrameworkUri"),
MyVaultTile = Intent.GetBooleanExtra("myVaultTile", false),
GeneratorTile = Intent.GetBooleanExtra("generatorTile", false),
FromAutofillFramework = Intent.GetBooleanExtra("autofillFramework", false)
FromAutofillFramework = Intent.GetBooleanExtra("autofillFramework", false),
CreateSend = GetCreateSendRequest(Intent)
};
var fillType = Intent.GetIntExtra("autofillFrameworkFillType", 0);
if(fillType > 0)
if (fillType > 0)
{
options.FillType = (CipherType)fillType;
}
if(Intent.GetBooleanExtra("autofillFrameworkSave", false))
if (Intent.GetBooleanExtra("autofillFrameworkSave", false))
{
options.SaveType = (CipherType)Intent.GetIntExtra("autofillFrameworkType", 0);
options.SaveName = Intent.GetStringExtra("autofillFrameworkName");
@@ -298,48 +325,61 @@ namespace Bit.Droid
return options;
}
private Tuple<SendType, string, byte[], string> GetCreateSendRequest(Intent intent)
{
if (intent.Action == Intent.ActionSend && intent.Type != null)
{
if ((intent.Flags & ActivityFlags.LaunchedFromHistory) == ActivityFlags.LaunchedFromHistory)
{
// don't re-deliver intent if resuming from app switcher
return null;
}
var type = intent.Type;
if (type.Contains("text/"))
{
var subject = intent.GetStringExtra(Intent.ExtraSubject);
var text = intent.GetStringExtra(Intent.ExtraText);
return new Tuple<SendType, string, byte[], string>(SendType.Text, subject, null, text);
}
else
{
var data = intent.ClipData?.GetItemAt(0);
var uri = data?.Uri;
var filename = AndroidHelpers.GetFileName(ApplicationContext, uri);
try
{
using (var stream = ContentResolver.OpenInputStream(uri))
using (var memoryStream = new MemoryStream())
{
stream.CopyTo(memoryStream);
return new Tuple<SendType, string, byte[], string>(SendType.File, filename, memoryStream.ToArray(), null);
}
}
catch (Java.IO.FileNotFoundException) { }
}
}
return null;
}
private void ParseYubiKey(string data)
{
if(data == null)
if (data == null)
{
return;
}
var otpMatch = _otpPattern.Matcher(data);
if(otpMatch.Matches())
if (otpMatch.Matches())
{
var otp = otpMatch.Group(1);
_messagingService.Send("gotYubiKeyOTP", otp);
}
}
private void UpdateTheme(string theme)
private void AppearanceAdjustments()
{
if(theme == "dark")
{
SetTheme(Resource.Style.DarkTheme);
}
else if(theme == "black")
{
SetTheme(Resource.Style.BlackTheme);
}
else if(theme == "nord")
{
SetTheme(Resource.Style.NordTheme);
}
else
{
SetTheme(Resource.Style.LightTheme);
}
}
private void RestartApp()
{
var intent = new Intent(this, typeof(MainActivity));
var pendingIntent = PendingIntent.GetActivity(this, 5923650, intent, PendingIntentFlags.CancelCurrent);
var alarmManager = GetSystemService(AlarmService) as AlarmManager;
var triggerMs = Java.Lang.JavaSystem.CurrentTimeMillis() + 500;
alarmManager.Set(AlarmType.Rtc, triggerMs, pendingIntent);
Java.Lang.JavaSystem.Exit(0);
Window?.SetStatusBarColor(ThemeHelpers.NavBarBackgroundColor);
Window?.DecorView.SetBackgroundColor(ThemeHelpers.BackgroundColor);
ThemeHelpers.SetAppearance(ThemeManager.GetTheme(), ThemeManager.OsDarkModeEnabled());
}
private void ExitApp()
@@ -348,29 +388,17 @@ namespace Bit.Droid
Java.Lang.JavaSystem.Exit(0);
}
private async Task ClearClipboardAlarmAsync(Tuple<string, int?, bool> data)
private void StartEventAlarm()
{
if(data.Item3)
{
return;
}
var clearMs = data.Item2;
if(clearMs == null)
{
var clearSeconds = await _storageService.GetAsync<int?>(Constants.ClearClipboardKey);
if(clearSeconds != null)
{
clearMs = clearSeconds.Value * 1000;
}
}
if(clearMs == null)
{
return;
}
await _stateService.SaveAsync(Constants.LastClipboardValueKey, data.Item1);
var triggerMs = Java.Lang.JavaSystem.CurrentTimeMillis() + clearMs.Value;
var alarmManager = GetSystemService(AlarmService) as AlarmManager;
alarmManager.Set(AlarmType.Rtc, triggerMs, _clearClipboardPendingIntent);
alarmManager.SetInexactRepeating(AlarmType.ElapsedRealtime, 120000, 300000, _eventUploadPendingIntent);
}
private async Task StopEventAlarmAsync()
{
var alarmManager = GetSystemService(AlarmService) as AlarmManager;
alarmManager.Cancel(_eventUploadPendingIntent);
await _eventService.UploadEventsAsync();
}
}
}

View File

@@ -2,6 +2,8 @@
using System.IO;
using System.Threading.Tasks;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Bit.App.Abstractions;
using Bit.App.Services;
@@ -10,10 +12,17 @@ using Bit.Core.Abstractions;
using Bit.Core.Services;
using Bit.Core.Utilities;
using Bit.Droid.Services;
using Bit.Droid.Utilities;
using Plugin.CurrentActivity;
using Plugin.Fingerprint;
using Plugin.Fingerprint.Abstractions;
using Xamarin.Android.Net;
using System.Net.Http;
using System.Net;
using Bit.App.Utilities;
using Bit.App.Pages;
using Bit.App.Utilities.AccountManagement;
#if !FDROID
using Android.Gms.Security;
#endif
namespace Bit.Droid
{
@@ -23,21 +32,52 @@ namespace Bit.Droid
[Application(Debuggable = false)]
#endif
[Register("com.x8bit.bitwarden.MainApplication")]
#if FDROID
public class MainApplication : Application
#else
public class MainApplication : Application, ProviderInstaller.IProviderInstallListener
#endif
{
public MainApplication(IntPtr handle, JniHandleOwnership transer)
: base(handle, transer)
{
if(ServiceContainer.RegisteredServices.Count == 0)
if (ServiceContainer.RegisteredServices.Count == 0)
{
RegisterLocalServices();
ServiceContainer.Init();
if(App.Migration.MigrationHelpers.NeedsMigration())
{
var task = App.Migration.MigrationHelpers.PerformMigrationAsync();
Task.Delay(2000).Wait();
}
var deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
ServiceContainer.Init(deviceActionService.DeviceUserAgent, Constants.ClearCiphersCacheKey,
Constants.AndroidAllClearCipherCacheKeys);
// TODO: Update when https://github.com/bitwarden/mobile/pull/1662 gets merged
var deleteAccountActionFlowExecutioner = new DeleteAccountActionFlowExecutioner(
ServiceContainer.Resolve<IApiService>("apiService"),
ServiceContainer.Resolve<IMessagingService>("messagingService"),
ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService"),
ServiceContainer.Resolve<IDeviceActionService>("deviceActionService"),
ServiceContainer.Resolve<ILogger>("logger"));
ServiceContainer.Register<IDeleteAccountActionFlowExecutioner>("deleteAccountActionFlowExecutioner", deleteAccountActionFlowExecutioner);
var verificationActionsFlowHelper = new VerificationActionsFlowHelper(
ServiceContainer.Resolve<IKeyConnectorService>("keyConnectorService"),
ServiceContainer.Resolve<IPasswordRepromptService>("passwordRepromptService"),
ServiceContainer.Resolve<ICryptoService>("cryptoService"));
ServiceContainer.Register<IVerificationActionsFlowHelper>("verificationActionsFlowHelper", verificationActionsFlowHelper);
var accountsManager = new AccountsManager(
ServiceContainer.Resolve<IBroadcasterService>("broadcasterService"),
ServiceContainer.Resolve<IVaultTimeoutService>("vaultTimeoutService"),
ServiceContainer.Resolve<IStorageService>("secureStorageService"),
ServiceContainer.Resolve<IStateService>("stateService"),
ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService"),
ServiceContainer.Resolve<IAuthService>("authService"));
ServiceContainer.Register<IAccountsManager>("accountsManager", accountsManager);
}
#if !FDROID
if (Build.VERSION.SdkInt <= BuildVersionCodes.Kitkat)
{
ProviderInstaller.InstallIfNeededAsync(ApplicationContext, this);
}
#endif
}
public override void OnCreate()
@@ -47,17 +87,25 @@ namespace Bit.Droid
CrossCurrentActivity.Current.Init(this);
}
public void OnProviderInstallFailed(int errorCode, Intent recoveryIntent)
{
}
public void OnProviderInstalled()
{
}
private void RegisterLocalServices()
{
ServiceContainer.Register<ILogService>("logService", new AndroidLogService());
ServiceContainer.Register("settingsShim", new App.Migration.SettingsShim());
if(App.Migration.MigrationHelpers.NeedsMigration())
{
ServiceContainer.Register<App.Migration.Abstractions.IOldSecureStorageService>(
"oldSecureStorageService", new Migration.AndroidKeyStoreStorageService());
}
ServiceContainer.Register<INativeLogService>("nativeLogService", new AndroidLogService());
#if FDROID
ServiceContainer.Register<ILogger>("logger", new StubLogger());
#elif DEBUG
ServiceContainer.Register<ILogger>("logger", DebugLogger.Instance);
#else
ServiceContainer.Register<ILogger>("logger", Logger.Instance);
#endif
Refractored.FabControl.Droid.FloatingActionButtonViewRenderer.Init();
// Note: This might cause a race condition. Investigate more.
Task.Run(() =>
{
@@ -65,17 +113,16 @@ namespace Bit.Droid
FFImageLoading.ImageService.Instance.Initialize(new FFImageLoading.Config.Configuration
{
FadeAnimationEnabled = false,
FadeAnimationForCachedImages = false
FadeAnimationForCachedImages = false,
HttpClient = new HttpClient(new AndroidClientHandler() { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate })
});
ZXing.Net.Mobile.Forms.Android.Platform.Init();
});
CrossFingerprint.SetCurrentActivityResolver(() => CrossCurrentActivity.Current.Activity);
CrossFingerprint.SetDialogFragmentType<CustomFingerprintDialogFragment>();
var preferencesStorage = new PreferencesStorageService(null);
var documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
var documentsPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
var liteDbStorage = new LiteDbStorageService(Path.Combine(documentsPath, "bitwarden.db"));
liteDbStorage.InitAsync();
var localizeService = new LocalizeService();
var broadcasterService = new BroadcasterService();
var messagingService = new MobileBroadcasterMessagingService(broadcasterService);
@@ -83,10 +130,18 @@ namespace Bit.Droid
var secureStorageService = new SecureStorageService();
var cryptoPrimitiveService = new CryptoPrimitiveService();
var mobileStorageService = new MobileStorageService(preferencesStorage, liteDbStorage);
var deviceActionService = new DeviceActionService(mobileStorageService, messagingService,
broadcasterService);
var platformUtilsService = new MobilePlatformUtilsService(deviceActionService, messagingService,
broadcasterService);
var stateService = new StateService(mobileStorageService, secureStorageService, messagingService);
var stateMigrationService =
new StateMigrationService(liteDbStorage, preferencesStorage, secureStorageService);
var clipboardService = new ClipboardService(stateService);
var deviceActionService = new DeviceActionService(clipboardService, stateService, messagingService,
broadcasterService, () => ServiceContainer.Resolve<IEventService>("eventService"));
var platformUtilsService = new MobilePlatformUtilsService(deviceActionService, clipboardService,
messagingService, broadcasterService);
var biometricService = new BiometricService();
var cryptoFunctionService = new PclCryptoFunctionService(cryptoPrimitiveService);
var cryptoService = new CryptoService(stateService, cryptoFunctionService);
var passwordRepromptService = new MobilePasswordRepromptService(platformUtilsService, cryptoService);
ServiceContainer.Register<IBroadcasterService>("broadcasterService", broadcasterService);
ServiceContainer.Register<IMessagingService>("messagingService", messagingService);
@@ -95,8 +150,15 @@ namespace Bit.Droid
ServiceContainer.Register<ICryptoPrimitiveService>("cryptoPrimitiveService", cryptoPrimitiveService);
ServiceContainer.Register<IStorageService>("storageService", mobileStorageService);
ServiceContainer.Register<IStorageService>("secureStorageService", secureStorageService);
ServiceContainer.Register<IStateService>("stateService", stateService);
ServiceContainer.Register<IStateMigrationService>("stateMigrationService", stateMigrationService);
ServiceContainer.Register<IClipboardService>("clipboardService", clipboardService);
ServiceContainer.Register<IDeviceActionService>("deviceActionService", deviceActionService);
ServiceContainer.Register<IPlatformUtilsService>("platformUtilsService", platformUtilsService);
ServiceContainer.Register<IBiometricService>("biometricService", biometricService);
ServiceContainer.Register<ICryptoFunctionService>("cryptoFunctionService", cryptoFunctionService);
ServiceContainer.Register<ICryptoService>("cryptoService", cryptoService);
ServiceContainer.Register<IPasswordRepromptService>("passwordRepromptService", passwordRepromptService);
// Push
#if FDROID
@@ -109,7 +171,7 @@ namespace Bit.Droid
ServiceContainer.Register<IPushNotificationListenerService>(
"pushNotificationListenerService", notificationListenerService);
var androidPushNotificationService = new AndroidPushNotificationService(
mobileStorageService, notificationListenerService);
stateService, notificationListenerService);
ServiceContainer.Register<IPushNotificationService>(
"pushNotificationService", androidPushNotificationService);
#endif
@@ -125,11 +187,7 @@ namespace Bit.Droid
private async Task BootstrapAsync()
{
var disableFavicon = await ServiceContainer.Resolve<IStorageService>("storageService").GetAsync<bool?>(
Constants.DisableFaviconKey);
await ServiceContainer.Resolve<IStateService>("stateService").SaveAsync(Constants.DisableFaviconKey,
disableFavicon);
await ServiceContainer.Resolve<IEnvironmentService>("environmentService").SetUrlsFromStorageAsync();
}
}
}
}

View File

@@ -1,373 +0,0 @@
using Java.Security;
using Javax.Crypto;
using Android.OS;
using Bit.App.Abstractions;
using System;
using Android.Security;
using Javax.Security.Auth.X500;
using Java.Math;
using Android.Security.Keystore;
using Android.App;
using Java.Util;
using Javax.Crypto.Spec;
using Android.Preferences;
using Bit.App.Migration;
using Bit.Core.Utilities;
using Bit.App.Migration.Abstractions;
namespace Bit.Droid.Migration
{
public class AndroidKeyStoreStorageService : IOldSecureStorageService
{
private const string AndroidKeyStore = "AndroidKeyStore";
private const string AesMode = "AES/GCM/NoPadding";
private const string KeyAlias = "bitwardenKey2";
private const string KeyAliasV1 = "bitwardenKey";
private const string SettingsFormat = "ksSecured2:{0}";
private const string SettingsFormatV1 = "ksSecured:{0}";
private const string AesKey = "ksSecured2:aesKeyForService";
private const string AesKeyV1 = "ksSecured:aesKeyForService";
private readonly string _rsaMode;
private readonly bool _oldAndroid;
private readonly SettingsShim _settings;
private readonly KeyStore _keyStore;
public AndroidKeyStoreStorageService()
{
_oldAndroid = Build.VERSION.SdkInt < BuildVersionCodes.M;
_rsaMode = _oldAndroid ? "RSA/ECB/PKCS1Padding" : "RSA/ECB/OAEPWithSHA-1AndMGF1Padding";
_settings = ServiceContainer.Resolve<SettingsShim>("settingsShim");
_keyStore = KeyStore.GetInstance(AndroidKeyStore);
_keyStore.Load(null);
/*
try
{
GenerateStoreKey(true);
}
catch
{
GenerateStoreKey(false);
}
GenerateAesKey();
*/
}
public bool Contains(string key)
{
return _settings.Contains(string.Format(SettingsFormat, key)) ||
_settings.Contains(string.Format(SettingsFormatV1, key));
}
public void Delete(string key)
{
CleanupOld(key);
var formattedKey = string.Format(SettingsFormat, key);
if(_settings.Contains(formattedKey))
{
_settings.Remove(formattedKey);
}
}
public byte[] Retrieve(string key)
{
var formattedKey = string.Format(SettingsFormat, key);
if(!_settings.Contains(formattedKey))
{
return TryGetAndMigrate(key);
}
var cs = _settings.GetValueOrDefault(formattedKey, null);
if(string.IsNullOrWhiteSpace(cs))
{
return null;
}
var aesKey = GetAesKey();
if(aesKey == null)
{
return null;
}
try
{
return App.Migration.Crypto.AesCbcDecrypt(new App.Migration.Models.CipherString(cs), aesKey);
}
catch
{
Console.WriteLine("Failed to decrypt from secure storage.");
_settings.Remove(formattedKey);
//Utilities.SendCrashEmail(e);
//Utilities.SaveCrashFile(e);
return null;
}
}
public void Store(string key, byte[] dataBytes)
{
var formattedKey = string.Format(SettingsFormat, key);
CleanupOld(key);
if(dataBytes == null)
{
_settings.Remove(formattedKey);
return;
}
var aesKey = GetAesKey();
if(aesKey == null)
{
return;
}
try
{
var cipherString = App.Migration.Crypto.AesCbcEncrypt(dataBytes, aesKey);
_settings.AddOrUpdateValue(formattedKey, cipherString.EncryptedString);
}
catch
{
Console.WriteLine("Failed to encrypt to secure storage.");
//Utilities.SendCrashEmail(e);
//Utilities.SaveCrashFile(e);
}
}
private void GenerateStoreKey(bool withDate)
{
if(_keyStore.ContainsAlias(KeyAlias))
{
return;
}
ClearSettings();
var end = Calendar.Instance;
end.Add(CalendarField.Year, 99);
if(_oldAndroid)
{
var subject = new X500Principal($"CN={KeyAlias}");
var builder = new KeyPairGeneratorSpec.Builder(Application.Context)
.SetAlias(KeyAlias)
.SetSubject(subject)
.SetSerialNumber(BigInteger.Ten);
if(withDate)
{
builder.SetStartDate(new Date(0)).SetEndDate(end.Time);
}
var spec = builder.Build();
var gen = KeyPairGenerator.GetInstance(KeyProperties.KeyAlgorithmRsa, AndroidKeyStore);
gen.Initialize(spec);
gen.GenerateKeyPair();
}
else
{
var builder = new KeyGenParameterSpec.Builder(KeyAlias, KeyStorePurpose.Decrypt | KeyStorePurpose.Encrypt)
.SetBlockModes(KeyProperties.BlockModeGcm)
.SetEncryptionPaddings(KeyProperties.EncryptionPaddingNone);
if(withDate)
{
builder.SetKeyValidityStart(new Date(0)).SetKeyValidityEnd(end.Time);
}
var spec = builder.Build();
var gen = KeyGenerator.GetInstance(KeyProperties.KeyAlgorithmAes, AndroidKeyStore);
gen.Init(spec);
gen.GenerateKey();
}
}
private KeyStore.PrivateKeyEntry GetRsaKeyEntry(string alias)
{
return _keyStore.GetEntry(alias, null) as KeyStore.PrivateKeyEntry;
}
private void GenerateAesKey()
{
if(_settings.Contains(AesKey))
{
return;
}
var key = App.Migration.Crypto.RandomBytes(512 / 8);
var encKey = _oldAndroid ? RsaEncrypt(key) : AesEncrypt(key);
_settings.AddOrUpdateValue(AesKey, encKey);
}
private App.Migration.Models.SymmetricCryptoKey GetAesKey(bool v1 = false)
{
try
{
var aesKey = v1 ? AesKeyV1 : AesKey;
if(!_settings.Contains(aesKey))
{
return null;
}
var encKey = _settings.GetValueOrDefault(aesKey, null);
if(string.IsNullOrWhiteSpace(encKey))
{
return null;
}
if(_oldAndroid || v1)
{
var encKeyBytes = Convert.FromBase64String(encKey);
var key = RsaDecrypt(encKeyBytes, v1);
return new App.Migration.Models.SymmetricCryptoKey(key);
}
else
{
var parts = encKey.Split('|');
if(parts.Length < 2)
{
return null;
}
var ivBytes = Convert.FromBase64String(parts[0]);
var encKeyBytes = Convert.FromBase64String(parts[1]);
var key = AesDecrypt(ivBytes, encKeyBytes);
return new App.Migration.Models.SymmetricCryptoKey(key);
}
}
catch
{
Console.WriteLine("Cannot get AesKey.");
_keyStore.DeleteEntry(KeyAlias);
_settings.Remove(AesKey);
if(!v1)
{
//Utilities.SendCrashEmail(e);
//Utilities.SaveCrashFile(e);
}
return null;
}
}
private string AesEncrypt(byte[] input)
{
using(var entry = _keyStore.GetKey(KeyAlias, null))
using(var cipher = Cipher.GetInstance(AesMode))
{
cipher.Init(CipherMode.EncryptMode, entry);
var encBytes = cipher.DoFinal(input);
var ivBytes = cipher.GetIV();
return $"{Convert.ToBase64String(ivBytes)}|{Convert.ToBase64String(encBytes)}";
}
}
private byte[] AesDecrypt(byte[] iv, byte[] encData)
{
using(var entry = _keyStore.GetKey(KeyAlias, null))
using(var cipher = Cipher.GetInstance(AesMode))
{
var spec = new GCMParameterSpec(128, iv);
cipher.Init(CipherMode.DecryptMode, entry, spec);
var decBytes = cipher.DoFinal(encData);
return decBytes;
}
}
private string RsaEncrypt(byte[] data)
{
using(var entry = GetRsaKeyEntry(KeyAlias))
using(var cipher = Cipher.GetInstance(_rsaMode))
{
cipher.Init(CipherMode.EncryptMode, entry.Certificate.PublicKey);
var cipherText = cipher.DoFinal(data);
return Convert.ToBase64String(cipherText);
}
}
private byte[] RsaDecrypt(byte[] encData, bool v1)
{
using(var entry = GetRsaKeyEntry(v1 ? KeyAliasV1 : KeyAlias))
using(var cipher = Cipher.GetInstance(_rsaMode))
{
if(_oldAndroid)
{
cipher.Init(CipherMode.DecryptMode, entry.PrivateKey);
}
else
{
cipher.Init(CipherMode.DecryptMode, entry.PrivateKey, OAEPParameterSpec.Default);
}
var plainText = cipher.DoFinal(encData);
return plainText;
}
}
private byte[] TryGetAndMigrate(string key)
{
var formattedKeyV1 = string.Format(SettingsFormatV1, key);
if(_settings.Contains(formattedKeyV1))
{
var aesKeyV1 = GetAesKey(true);
if(aesKeyV1 != null)
{
try
{
var cs = _settings.GetValueOrDefault(formattedKeyV1, null);
var value = App.Migration.Crypto.AesCbcDecrypt(new App.Migration.Models.CipherString(cs), aesKeyV1);
Store(key, value);
return value;
}
catch
{
Console.WriteLine("Failed to decrypt v1 from secure storage.");
}
}
_settings.Remove(formattedKeyV1);
}
return null;
}
private void CleanupOld(string key)
{
var formattedKeyV1 = string.Format(SettingsFormatV1, key);
if(_settings.Contains(formattedKeyV1))
{
_settings.Remove(formattedKeyV1);
}
}
private void ClearSettings(string format = SettingsFormat)
{
var prefix = string.Format(format, string.Empty);
using(var sharedPreferences = PreferenceManager.GetDefaultSharedPreferences(Application.Context))
using(var sharedPreferencesEditor = sharedPreferences.Edit())
{
var removed = false;
foreach(var pref in sharedPreferences.All)
{
if(pref.Key.StartsWith(prefix))
{
removed = true;
sharedPreferencesEditor.Remove(pref.Key);
}
}
if(removed)
{
sharedPreferencesEditor.Commit();
}
}
}
}
}

View File

@@ -1,55 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:versionCode="1"
android:versionName="2.0.0"
package="com.x8bit.bitwarden">
<?xml version='1.0' encoding='UTF-8'?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:versionCode="1" android:versionName="2022.6.0" android:installLocation="internalOnly" package="com.x8bit.bitwarden">
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="28" />
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
<uses-permission android:name="com.samsung.android.providers.context.permission.WRITE_USE_APP_FEATURE_SURVEY" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.NFC"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.USE_FINGERPRINT"/>
<uses-permission android:name="android.permission.USE_BIOMETRIC"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="com.samsung.android.providers.context.permission.WRITE_USE_APP_FEATURE_SURVEY"/>
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
<uses-feature android:name="android.hardware.camera" android:required="false"/>
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
<application
android:label="Bitwarden"
android:theme="@style/LightTheme.Splash"
android:allowBackup="false"
tools:replace="android:allowBackup"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:networkSecurityConfig="@xml/network_security_config">
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.x8bit.bitwarden.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
<application android:label="Bitwarden" android:theme="@style/LaunchTheme" android:allowBackup="false" tools:replace="android:allowBackup" android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:networkSecurityConfig="@xml/network_security_config">
<provider android:name="androidx.core.content.FileProvider" android:authorities="com.x8bit.bitwarden.fileprovider" android:exported="false" android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/filepaths"/>
</provider>
<receiver
android:name="com.google.firebase.iid.FirebaseInstanceIdInternalReceiver"
android:exported="false" />
<receiver
android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.x8bit.bitwarden" />
</intent-filter>
</receiver>
<meta-data android:name="android.max_aspect" android:value="2.1"/>
<meta-data android:name="android.content.APP_RESTRICTIONS" android:resource="@xml/app_restrictions"/>
<meta-data android:name="android.max_aspect" android:value="2.1" />
<!-- Support for Samsung "Multi Window" mode (for Android < 7.0 users) -->
<meta-data android:name="com.samsung.android.sdk.multiwindow.enable" android:value="true"/>
<meta-data android:name="com.samsung.android.sdk.multiwindow.penwindow.enable" android:value="true"/>
<!-- Support for LG "Dual Window" mode (for Android < 7.0 users) -->
<meta-data android:name="com.lge.support.SPLIT_WINDOW" android:value="true"/>
<!-- Declare MainActivity manually so we can set LaunchMode using API dependant resource -->
<activity android:name="com.x8bit.bitwarden.MainActivity" android:configChanges="keyboard|keyboardHidden|navigation|orientation|screenSize|uiMode" android:exported="true" android:icon="@mipmap/ic_launcher" android:label="Bitwarden" android:launchMode="@integer/launchModeAPIlevel" android:theme="@style/LaunchTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="application/*"/>
<data android:mimeType="image/*"/>
<data android:mimeType="video/*"/>
<data android:mimeType="text/*"/>
</intent-filter>
</activity>
</application>
<!-- Package visibility (for Android 11+) -->
<queries>
<intent>
<action android:name="*"/>
</intent>
</queries>
</manifest>

View File

@@ -7,7 +7,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTitle("BitwardenAndroid")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("8bit Solutions LLC")]
[assembly: AssemblyCompany("Bitwarden Inc.")]
[assembly: AssemblyProduct("Bitwarden")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: AssemblyTrademark("")]

View File

@@ -1,25 +0,0 @@
#if !FDROID
using Android.App;
using Android.Content;
using Bit.App.Abstractions;
using Bit.Core;
using Bit.Core.Abstractions;
using Bit.Core.Utilities;
using Firebase.Iid;
namespace Bit.Droid.Push
{
[Service]
[IntentFilter(new[] { "com.google.firebase.INSTANCE_ID_EVENT" })]
public class FirebaseInstanceIdService : Firebase.Iid.FirebaseInstanceIdService
{
public async override void OnTokenRefresh()
{
var storageService = ServiceContainer.Resolve<IStorageService>("storageService");
var pushNotificationService = ServiceContainer.Resolve<IPushNotificationService>("pushNotificationService");
await storageService.SaveAsync(Constants.PushRegisteredTokenKey, FirebaseInstanceId.Instance.Token);
await pushNotificationService.RegisterAsync();
}
}
}
#endif

View File

@@ -1,7 +1,7 @@
#if !FDROID
using Android.App;
using Android.Content;
using Bit.App.Abstractions;
using Bit.Core.Abstractions;
using Bit.Core.Utilities;
using Firebase.Messaging;
using Newtonsoft.Json;
@@ -10,18 +10,27 @@ using Xamarin.Forms;
namespace Bit.Droid.Push
{
[Service]
[Service(Exported=false)]
[IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
public class FirebaseMessagingService : Firebase.Messaging.FirebaseMessagingService
{
public async override void OnNewToken(string token)
{
var stateService = ServiceContainer.Resolve<IStateService>("stateService");
var pushNotificationService = ServiceContainer.Resolve<IPushNotificationService>("pushNotificationService");
await stateService.SetPushRegisteredTokenAsync(token);
await pushNotificationService.RegisterAsync();
}
public async override void OnMessageReceived(RemoteMessage message)
{
if(message?.Data == null)
if (message?.Data == null)
{
return;
}
var data = message.Data.ContainsKey("data") ? message.Data["data"] : null;
if(data == null)
if (data == null)
{
return;
}
@@ -32,7 +41,7 @@ namespace Bit.Droid.Push
"pushNotificationListenerService");
await listener.OnMessageAsync(obj, Device.Android);
}
catch(JsonReaderException ex)
catch (JsonReaderException ex)
{
System.Diagnostics.Debug.WriteLine(ex.ToString());
}

View File

@@ -1,23 +1,14 @@
using Android.Content;
using Bit.Core;
using Bit.Core.Abstractions;
using Bit.Core.Utilities;
namespace Bit.Droid.Receivers
{
[BroadcastReceiver(Name = "com.x8bit.bitwarden.ClearClipboardAlarmReceiver", Exported = false)]
public class ClearClipboardAlarmReceiver : BroadcastReceiver
{
public async override void OnReceive(Context context, Intent intent)
public override void OnReceive(Context context, Intent intent)
{
var stateService = ServiceContainer.Resolve<IStateService>("stateService");
var clipboardManager = context.GetSystemService(Context.ClipboardService) as ClipboardManager;
var lastClipboardValue = await stateService.GetAsync<string>(Constants.LastClipboardValueKey);
await stateService.RemoveAsync(Constants.LastClipboardValueKey);
if(lastClipboardValue == clipboardManager.Text)
{
clipboardManager.Text = string.Empty;
}
clipboardManager.PrimaryClip = ClipData.NewPlainText("bitwarden", " ");
}
}
}

View File

@@ -0,0 +1,16 @@
using Android.Content;
using Bit.Core.Abstractions;
using Bit.Core.Utilities;
namespace Bit.Droid.Receivers
{
[BroadcastReceiver(Name = "com.x8bit.bitwarden.EventUploadReceiver", Exported = false)]
public class EventUploadReceiver : BroadcastReceiver
{
public async override void OnReceive(Context context, Intent intent)
{
var eventService = ServiceContainer.Resolve<IEventService>("eventService");
await eventService.UploadEventsAsync();
}
}
}

View File

@@ -1,16 +0,0 @@
using Android.Content;
using Bit.Core.Abstractions;
using Bit.Core.Utilities;
namespace Bit.Droid.Receivers
{
[BroadcastReceiver(Name = "com.x8bit.bitwarden.LockAlarmReceiver", Exported = false)]
public class LockAlarmReceiver : BroadcastReceiver
{
public async override void OnReceive(Context context, Intent intent)
{
var lockService = ServiceContainer.Resolve<ILockService>("lockService");
await lockService.CheckLockAsync();
}
}
}

View File

@@ -1,5 +1,4 @@
using System;
using Android.App;
using Android.App;
using Android.Content;
using Bit.App.Abstractions;
using Bit.App.Utilities;
@@ -14,9 +13,10 @@ namespace Bit.Droid.Receivers
{
public override async void OnReceive(Context context, Intent intent)
{
var storageService = ServiceContainer.Resolve<IStorageService>("storageService");
await AppHelpers.PerformUpdateTasksAsync(ServiceContainer.Resolve<ISyncService>("syncService"),
ServiceContainer.Resolve<IDeviceActionService>("deviceActionService"), storageService);
await AppHelpers.PerformUpdateTasksAsync(
ServiceContainer.Resolve<ISyncService>("syncService"),
ServiceContainer.Resolve<IDeviceActionService>("deviceActionService"),
ServiceContainer.Resolve<IStateService>("stateService"));
}
}
}

View File

@@ -0,0 +1,23 @@
using System.Collections.Generic;
using Android.App;
using Android.Content;
using Bit.App.Utilities;
using Bit.Core.Abstractions;
using Bit.Core.Utilities;
using Bit.Droid.Utilities;
namespace Bit.Droid.Receivers
{
[BroadcastReceiver(Name = "com.x8bit.bitwarden.RestrictionsChangedReceiver", Exported = false)]
[IntentFilter(new[] { Intent.ActionApplicationRestrictionsChanged })]
public class RestrictionsChangedReceiver : BroadcastReceiver
{
public async override void OnReceive(Context context, Intent intent)
{
if (intent.Action == Intent.ActionApplicationRestrictionsChanged)
{
await AndroidHelpers.SetPreconfiguredRestrictionSettingsAsync(context);
}
}
}
}

View File

@@ -1,241 +0,0 @@
using Android.App;
using Android.Content;
using Android.Graphics;
using Android.Runtime;
using Android.Util;
using Android.Views;
using Android.Views.InputMethods;
using Android.Widget;
using Bit.App.Controls;
using Bit.Droid.Renderers;
using FFImageLoading;
using FFImageLoading.Views;
using FFImageLoading.Work;
using System;
using System.ComponentModel;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(CipherViewCell), typeof(CipherViewCellRenderer))]
namespace Bit.Droid.Renderers
{
public class CipherViewCellRenderer : ViewCellRenderer
{
private static Typeface _faTypeface;
private static Typeface _miTypeface;
private static Android.Graphics.Color _textColor;
private static Android.Graphics.Color _mutedColor;
private static Android.Graphics.Color _disabledIconColor;
private AndroidCipherCell _cell;
protected override Android.Views.View GetCellCore(Cell item, Android.Views.View convertView,
ViewGroup parent, Context context)
{
if(_faTypeface == null)
{
_faTypeface = Typeface.CreateFromAsset(context.Assets, "FontAwesome.ttf");
}
if(_miTypeface == null)
{
_miTypeface = Typeface.CreateFromAsset(context.Assets, "MaterialIcons_Regular.ttf");
}
if(_textColor == default(Android.Graphics.Color))
{
_textColor = ((Xamarin.Forms.Color)Xamarin.Forms.Application.Current.Resources["TextColor"])
.ToAndroid();
}
if(_mutedColor == default(Android.Graphics.Color))
{
_mutedColor = ((Xamarin.Forms.Color)Xamarin.Forms.Application.Current.Resources["MutedColor"])
.ToAndroid();
}
if(_disabledIconColor == default(Android.Graphics.Color))
{
_disabledIconColor =
((Xamarin.Forms.Color)Xamarin.Forms.Application.Current.Resources["DisabledIconColor"])
.ToAndroid();
}
var cipherCell = item as CipherViewCell;
_cell = convertView as AndroidCipherCell;
if(_cell == null)
{
_cell = new AndroidCipherCell(context, cipherCell, _faTypeface, _miTypeface);
}
else
{
_cell.CipherViewCell.PropertyChanged -= CellPropertyChanged;
}
cipherCell.PropertyChanged += CellPropertyChanged;
_cell.UpdateCell(cipherCell);
_cell.UpdateColors(_textColor, _mutedColor, _disabledIconColor);
return _cell;
}
public void CellPropertyChanged(object sender, PropertyChangedEventArgs e)
{
var cipherCell = sender as CipherViewCell;
_cell.CipherViewCell = cipherCell;
if(e.PropertyName == CipherViewCell.CipherProperty.PropertyName)
{
_cell.UpdateCell(cipherCell);
}
else if(e.PropertyName == CipherViewCell.WebsiteIconsEnabledProperty.PropertyName)
{
_cell.UpdateIconImage(cipherCell);
}
}
}
public class AndroidCipherCell : LinearLayout, INativeElementView
{
private readonly Typeface _faTypeface;
private readonly Typeface _miTypeface;
private IScheduledWork _currentTask;
public AndroidCipherCell(Context context, CipherViewCell cipherView, Typeface faTypeface, Typeface miTypeface)
: base(context)
{
CipherViewCell = cipherView;
_faTypeface = faTypeface;
_miTypeface = miTypeface;
var view = (context as Activity).LayoutInflater.Inflate(Resource.Layout.CipherViewCell, null);
IconImage = view.FindViewById<IconImageView>(Resource.Id.CipherCellIconImage);
Icon = view.FindViewById<TextView>(Resource.Id.CipherCellIcon);
Name = view.FindViewById<TextView>(Resource.Id.CipherCellName);
SubTitle = view.FindViewById<TextView>(Resource.Id.CipherCellSubTitle);
SharedIcon = view.FindViewById<TextView>(Resource.Id.CipherCellSharedIcon);
AttachmentsIcon = view.FindViewById<TextView>(Resource.Id.CipherCellAttachmentsIcon);
MoreButton = view.FindViewById<Android.Widget.Button>(Resource.Id.CipherCellButton);
MoreButton.Click += MoreButton_Click;
Icon.Typeface = _faTypeface;
SharedIcon.Typeface = _faTypeface;
AttachmentsIcon.Typeface = _faTypeface;
MoreButton.Typeface = _miTypeface;
var small = (float)Device.GetNamedSize(NamedSize.Small, typeof(Label));
Icon.SetTextSize(ComplexUnitType.Pt, 10);
Name.SetTextSize(ComplexUnitType.Sp, (float)Device.GetNamedSize(NamedSize.Medium, typeof(Label)));
SubTitle.SetTextSize(ComplexUnitType.Sp, small);
SharedIcon.SetTextSize(ComplexUnitType.Sp, small);
AttachmentsIcon.SetTextSize(ComplexUnitType.Sp, small);
MoreButton.SetTextSize(ComplexUnitType.Sp, 25);
AddView(view);
}
public CipherViewCell CipherViewCell { get; set; }
public Element Element => CipherViewCell;
public IconImageView IconImage { get; set; }
public TextView Icon { get; set; }
public TextView Name { get; set; }
public TextView SubTitle { get; set; }
public TextView SharedIcon { get; set; }
public TextView AttachmentsIcon { get; set; }
public Android.Widget.Button MoreButton { get; set; }
public void UpdateCell(CipherViewCell cipherCell)
{
UpdateIconImage(cipherCell);
var cipher = cipherCell.Cipher;
Name.Text = cipher.Name;
if(!string.IsNullOrWhiteSpace(cipher.SubTitle))
{
SubTitle.Text = cipher.SubTitle;
SubTitle.Visibility = ViewStates.Visible;
}
else
{
SubTitle.Visibility = ViewStates.Invisible;
}
SharedIcon.Visibility = cipher.Shared ? ViewStates.Visible : ViewStates.Gone;
AttachmentsIcon.Visibility = cipher.HasAttachments ? ViewStates.Visible : ViewStates.Gone;
}
public void UpdateIconImage(CipherViewCell cipherCell)
{
if(_currentTask != null && !_currentTask.IsCancelled && !_currentTask.IsCompleted)
{
_currentTask.Cancel();
}
var cipher = cipherCell.Cipher;
var iconImage = cipherCell.GetIconImage(cipher);
if(iconImage.Item2 != null)
{
IconImage.SetImageResource(Resource.Drawable.login);
IconImage.Visibility = ViewStates.Visible;
Icon.Visibility = ViewStates.Gone;
_currentTask = ImageService.Instance.LoadUrl(iconImage.Item2).DownSample(64).Into(IconImage);
IconImage.Key = iconImage.Item2;
}
else
{
IconImage.Visibility = ViewStates.Gone;
Icon.Visibility = ViewStates.Visible;
Icon.Text = iconImage.Item1;
}
}
public void UpdateColors(Android.Graphics.Color textColor, Android.Graphics.Color mutedColor,
Android.Graphics.Color iconDisabledColor)
{
Name.SetTextColor(textColor);
SubTitle.SetTextColor(mutedColor);
Icon.SetTextColor(mutedColor);
SharedIcon.SetTextColor(mutedColor);
AttachmentsIcon.SetTextColor(mutedColor);
MoreButton.SetTextColor(iconDisabledColor);
}
private void MoreButton_Click(object sender, EventArgs e)
{
if(CipherViewCell.ButtonCommand?.CanExecute(CipherViewCell.Cipher) ?? false)
{
CipherViewCell.ButtonCommand.Execute(CipherViewCell.Cipher);
}
}
protected override void Dispose(bool disposing)
{
if(disposing)
{
MoreButton.Click -= MoreButton_Click;
}
base.Dispose(disposing);
}
}
[Android.Runtime.Preserve(AllMembers = true)]
[Register("bit.droid.renderers.IconImageView")]
public class IconImageView : ImageViewAsync
{
public IconImageView(Context context) : base(context)
{ }
public IconImageView(IntPtr javaReference, JniHandleOwnership transfer)
: base(javaReference, transfer)
{ }
public IconImageView(Context context, IAttributeSet attrs)
: base(context, attrs)
{ }
public string Key { get; set; }
protected override void JavaFinalize()
{
SetImageDrawable(null);
SetImageBitmap(null);
ImageService.Instance.InvalidateCacheEntryAsync(Key, FFImageLoading.Cache.CacheType.Memory);
base.JavaFinalize();
}
}
}

View File

@@ -1,6 +1,9 @@
using Android.Content;
using System.ComponentModel;
using Android.Content;
using Android.Content.Res;
using Android.Views.InputMethods;
using Bit.Droid.Renderers;
using Bit.Droid.Utilities;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
@@ -12,11 +15,21 @@ namespace Bit.Droid.Renderers
public CustomEditorRenderer(Context context)
: base(context)
{ }
// Workaround for issue described here:
// https://github.com/xamarin/Xamarin.Forms/issues/8291#issuecomment-617456651
protected override void OnAttachedToWindow()
{
base.OnAttachedToWindow();
EditText.Enabled = false;
EditText.Enabled = true;
}
protected override void OnElementChanged(ElementChangedEventArgs<Editor> e)
{
base.OnElementChanged(e);
if(Control != null && e.NewElement != null)
UpdateBorderColor();
if (Control != null && e.NewElement != null)
{
Control.SetPadding(Control.PaddingLeft, Control.PaddingTop - 10, Control.PaddingRight,
Control.PaddingBottom + 20);
@@ -24,5 +37,33 @@ namespace Bit.Droid.Renderers
(ImeAction)ImeFlags.NoExtractUi;
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == Entry.TextColorProperty.PropertyName)
{
UpdateBorderColor();
}
}
private void UpdateBorderColor()
{
if (Control != null)
{
var states = new[]
{
new[] { Android.Resource.Attribute.StateFocused }, // focused
new[] { -Android.Resource.Attribute.StateFocused }, // unfocused
};
var colors = new int[]
{
ThemeHelpers.PrimaryColor,
ThemeHelpers.MutedColor
};
Control.BackgroundTintList = new ColorStateList(states, colors);
}
}
}
}

View File

@@ -1,6 +1,12 @@
using Android.Content;
using System.ComponentModel;
using Android.Content;
using Android.Content.Res;
using Android.Graphics;
using Android.Text;
using Android.Views.InputMethods;
using Android.Widget;
using Bit.Droid.Renderers;
using Bit.Droid.Utilities;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
@@ -16,12 +22,85 @@ namespace Bit.Droid.Renderers
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if(Control != null && e.NewElement != null)
UpdateBorderColor();
if (Control != null && e.NewElement != null)
{
Control.SetPadding(Control.PaddingLeft, Control.PaddingTop - 10, Control.PaddingRight,
Control.PaddingBottom + 20);
Control.ImeOptions = Control.ImeOptions | (ImeAction)ImeFlags.NoPersonalizedLearning |
(ImeAction)ImeFlags.NoExtractUi;
}
}
// Workaround for bug preventing long-press -> copy/paste on Android 11
// See https://issuetracker.google.com/issues/37095917
protected override void OnAttachedToWindow()
{
base.OnAttachedToWindow();
Control.Enabled = false;
Control.Enabled = true;
}
// Workaround for failure to disable text prediction on non-password fields
// see https://github.com/xamarin/Xamarin.Forms/issues/10857
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
// Check if changed property is "IsPassword", otherwise ignore
if (e.PropertyName == Entry.IsPasswordProperty.PropertyName)
{
// Check if field type is text, otherwise ignore (numeric passwords, etc.)
EditText.InputType = Element.Keyboard.ToInputType();
bool isText = (EditText.InputType & InputTypes.ClassText) == InputTypes.ClassText,
isNumber = (EditText.InputType & InputTypes.ClassNumber) == InputTypes.ClassNumber;
if (isText || isNumber)
{
if (Element.IsPassword)
{
// Element is a password field, set inputType to TextVariationPassword which disables
// predictive text by default
EditText.InputType = EditText.InputType |
(isText ? InputTypes.TextVariationPassword : InputTypes.NumberVariationPassword);
}
else
{
// Element is not a password field, set inputType to TextVariationVisiblePassword to
// disable predictive text while still displaying the content.
EditText.InputType = EditText.InputType |
(isText ? InputTypes.TextVariationVisiblePassword : InputTypes.NumberVariationNormal);
}
// The workaround above forces a reset of the style properties, so we need to re-apply the font.
// see https://xamarin.github.io/bugzilla-archives/33/33666/bug.html
var typeface = Typeface.CreateFromAsset(Context.Assets, "RobotoMono_Regular.ttf");
if (Control is TextView label)
{
label.Typeface = typeface;
}
}
}
else if (e.PropertyName == Entry.TextColorProperty.PropertyName)
{
UpdateBorderColor();
}
}
private void UpdateBorderColor()
{
if (Control != null)
{
var states = new[]
{
new[] { Android.Resource.Attribute.StateFocused }, // focused
new[] { -Android.Resource.Attribute.StateFocused }, // unfocused
};
var colors = new int[]
{
ThemeHelpers.PrimaryColor,
ThemeHelpers.MutedColor
};
Control.BackgroundTintList = new ColorStateList(states, colors);
}
}
}

View File

@@ -0,0 +1,31 @@
using System;
using Android.App;
using Android.Content;
using AndroidX.AppCompat.Widget;
using Bit.App.Resources;
using Bit.Droid.Renderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(ContentPage), typeof(CustomPageRenderer))]
namespace Bit.Droid.Renderers
{
public class CustomPageRenderer : PageRenderer
{
public CustomPageRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Page> e)
{
base.OnElementChanged(e);
Activity context = (Activity)this.Context;
var toolbar = context.FindViewById<Toolbar>(Resource.Id.toolbar);
if(toolbar != null)
{
toolbar.NavigationContentDescription = AppResources.TapToGoBack;
}
}
}
}

View File

@@ -1,5 +1,8 @@
using Android.Content;
using System.ComponentModel;
using Android.Content;
using Android.Content.Res;
using Bit.Droid.Renderers;
using Bit.Droid.Utilities;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
@@ -15,11 +18,40 @@ namespace Bit.Droid.Renderers
protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
{
base.OnElementChanged(e);
if(Control != null && e.NewElement != null)
UpdateBorderColor();
if (Control != null && e.NewElement != null)
{
Control.SetPadding(Control.PaddingLeft, Control.PaddingTop - 10, Control.PaddingRight,
Control.PaddingBottom + 20);
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == Picker.TextColorProperty.PropertyName)
{
UpdateBorderColor();
}
}
private void UpdateBorderColor()
{
if (Control != null)
{
var states = new[]
{
new[] { Android.Resource.Attribute.StateFocused }, // focused
new[] { -Android.Resource.Attribute.StateFocused }, // unfocused
};
var colors = new int[]
{
ThemeHelpers.PrimaryColor,
ThemeHelpers.MutedColor
};
Control.BackgroundTintList = new ColorStateList(states, colors);
}
}
}
}

View File

@@ -16,7 +16,7 @@ namespace Bit.Droid.Renderers
protected override void OnElementChanged(ElementChangedEventArgs<SearchBar> e)
{
base.OnElementChanged(e);
if(Control != null && e.NewElement != null)
if (Control != null && e.NewElement != null)
{
try
{

View File

@@ -0,0 +1,66 @@
using System.ComponentModel;
using Android.Content;
using Android.Content.Res;
using Android.Graphics.Drawables;
using Android.OS;
using AndroidX.Core.Content.Resources;
using Bit.Droid.Renderers;
using Bit.Droid.Utilities;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(Switch), typeof(CustomSwitchRenderer))]
namespace Bit.Droid.Renderers
{
public class CustomSwitchRenderer : SwitchRenderer
{
public CustomSwitchRenderer(Context context)
: base(context)
{}
protected override void OnElementChanged(ElementChangedEventArgs<Switch> e)
{
base.OnElementChanged(e);
UpdateColors();
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == Switch.OnColorProperty.PropertyName)
{
UpdateColors();
}
}
private void UpdateColors()
{
if (Build.VERSION.SdkInt <= BuildVersionCodes.LollipopMr1)
{
// Android 5.x doesn't support ThumbTintList, and using SwitchCompat on every version after 5.x
// doesn't apply tinting the way we want. Let 5.x to do its own thing here.
return;
}
if (Control != null)
{
var t = ResourcesCompat.GetDrawable(Resources, Resource.Drawable.switch_thumb, null);
if (t is GradientDrawable thumb)
{
Control.ThumbDrawable = thumb;
}
var thumbStates = new[]
{
new[] { Android.Resource.Attribute.StateChecked }, // checked
new[] { -Android.Resource.Attribute.StateChecked }, // unchecked
};
var thumbColors = new int[]
{
ThemeHelpers.SwitchOnColor,
ThemeHelpers.SwitchThumbColor
};
Control.ThumbTintList = new ColorStateList(thumbStates, thumbColors);
}
}
}
}

View File

@@ -0,0 +1,66 @@
using Android.Content;
using Android.Views;
using Bit.App.Pages;
using Bit.Droid.Renderers;
using Google.Android.Material.BottomNavigation;
using Google.Android.Material.Navigation;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using Xamarin.Forms.Platform.Android.AppCompat;
[assembly: ExportRenderer(typeof(TabbedPage), typeof(CustomTabbedRenderer))]
namespace Bit.Droid.Renderers
{
public class CustomTabbedRenderer : TabbedPageRenderer, NavigationBarView.IOnItemReselectedListener
{
private TabbedPage _page;
public CustomTabbedRenderer(Context context) : base(context) { }
protected override void OnElementChanged(ElementChangedEventArgs<TabbedPage> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
_page = e.NewElement;
GetBottomNavigationView()?.SetOnItemReselectedListener(this);
}
else
{
_page = e.OldElement;
}
}
private BottomNavigationView GetBottomNavigationView()
{
for (var i = 0; i < ViewGroup.ChildCount; i++)
{
var childView = ViewGroup.GetChildAt(i);
if (childView is ViewGroup viewGroup)
{
for (var j = 0; j < viewGroup.ChildCount; j++)
{
var childRelativeLayoutView = viewGroup.GetChildAt(j);
if (childRelativeLayoutView is BottomNavigationView bottomNavigationView)
{
return bottomNavigationView;
}
}
}
}
return null;
}
public void OnNavigationItemReselected(IMenuItem item)
{
if (_page?.CurrentPage?.Navigation != null && _page.CurrentPage.Navigation.NavigationStack.Count > 0)
{
if (_page is TabsPage tabsPage)
{
tabsPage.OnPageReselected();
}
Device.BeginInvokeOnMainThread(async () => await _page.CurrentPage.Navigation.PopToRootAsync());
}
}
}
}

View File

@@ -0,0 +1,50 @@
using System.ComponentModel;
using Android.Content;
using Android.Views;
using Bit.App.Controls;
using Bit.Droid.Renderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(ExtendedDatePicker), typeof(ExtendedDatePickerRenderer))]
namespace Bit.Droid.Renderers
{
public class ExtendedDatePickerRenderer : DatePickerRenderer
{
public ExtendedDatePickerRenderer(Context context)
: base(context) { }
protected override void OnElementChanged(ElementChangedEventArgs<DatePicker> e)
{
base.OnElementChanged(e);
if (Control != null && Element is ExtendedDatePicker element)
{
// center text
Control.Gravity = GravityFlags.CenterHorizontal;
// use placeholder until NullableDate set
if (!element.NullableDate.HasValue)
{
Control.Text = element.PlaceHolder;
}
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == DatePicker.DateProperty.PropertyName ||
e.PropertyName == DatePicker.FormatProperty.PropertyName)
{
if (Control != null && Element is ExtendedDatePicker element)
{
if (Element.Format == element.PlaceHolder)
{
Control.Text = element.PlaceHolder;
return;
}
}
}
base.OnElementPropertyChanged(sender, e);
}
}
}

View File

@@ -0,0 +1,23 @@
using Android.Content;
using Bit.App.Controls;
using Bit.Droid.Renderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(ExtendedGrid), typeof(ExtendedGridRenderer))]
namespace Bit.Droid.Renderers
{
public class ExtendedGridRenderer : ViewRenderer
{
public ExtendedGridRenderer(Context context) : base(context) { }
protected override void OnElementChanged(ElementChangedEventArgs<View> elementChangedEvent)
{
base.OnElementChanged(elementChangedEvent);
if (elementChangedEvent.NewElement != null)
{
SetBackgroundResource(Resource.Drawable.list_item_bg);
}
}
}
}

View File

@@ -1,29 +0,0 @@
using Android.Content;
using Android.Views;
using Bit.App.Controls;
using Bit.Droid.Renderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(ExtendedListView), typeof(ExtendedListViewRenderer))]
namespace Bit.Droid.Renderers
{
public class ExtendedListViewRenderer : ListViewRenderer
{
public ExtendedListViewRenderer(Context context)
: base(context)
{ }
protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
{
base.OnElementChanged(e);
if(Control != null && e.NewElement != null && e.NewElement is ExtendedListView listView)
{
// Pad for FAB
Control.SetPadding(0, 0, 0, 170);
Control.SetClipToPadding(false);
Control.ScrollBarStyle = ScrollbarStyles.OutsideOverlay;
}
}
}
}

View File

@@ -1,6 +1,7 @@
using Android.Content;
using System.ComponentModel;
using Android.Content;
using Android.Graphics.Drawables;
using Android.Support.V4.Content.Res;
using AndroidX.Core.Content.Resources;
using Bit.App.Controls;
using Bit.Droid.Renderers;
using Xamarin.Forms;
@@ -18,12 +19,34 @@ namespace Bit.Droid.Renderers
protected override void OnElementChanged(ElementChangedEventArgs<Slider> e)
{
base.OnElementChanged(e);
if(Control != null && Element is ExtendedSlider view)
UpdateColor();
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == ExtendedSlider.ThumbBorderColorProperty.PropertyName)
{
UpdateColor();
}
}
private void UpdateColor()
{
if (Control != null && Element is ExtendedSlider view)
{
var t = ResourcesCompat.GetDrawable(Resources, Resource.Drawable.slider_thumb, null);
if(t is GradientDrawable thumb)
if (t is GradientDrawable thumb)
{
thumb.SetColor(view.ThumbColor.ToAndroid());
if (view.ThumbColor == Color.Default)
{
thumb.SetColor(Color.White.ToAndroid());
}
else
{
thumb.SetColor(view.ThumbColor.ToAndroid());
}
thumb.SetStroke(3, view.ThumbBorderColor.ToAndroid());
Control.SetThumb(thumb);
}

View File

@@ -0,0 +1,23 @@
using Android.Content;
using Bit.App.Controls;
using Bit.Droid.Renderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(ExtendedStackLayout), typeof(ExtendedStackLayoutRenderer))]
namespace Bit.Droid.Renderers
{
public class ExtendedStackLayoutRenderer : ViewRenderer
{
public ExtendedStackLayoutRenderer(Context context) : base(context) { }
protected override void OnElementChanged(ElementChangedEventArgs<View> elementChangedEvent)
{
base.OnElementChanged(elementChangedEvent);
if (elementChangedEvent.NewElement != null)
{
SetBackgroundResource(Resource.Drawable.list_item_bg);
}
}
}
}

View File

@@ -0,0 +1,72 @@
using System.ComponentModel;
using Android.Content;
using Android.Graphics;
using Android.OS;
using Bit.App.Controls;
using Bit.Droid.Renderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(ExtendedStepper), typeof(ExtendedStepperRenderer))]
namespace Bit.Droid.Renderers
{
public class ExtendedStepperRenderer : StepperRenderer
{
public ExtendedStepperRenderer(Context context)
: base(context)
{}
protected override void OnElementChanged(ElementChangedEventArgs<Stepper> e)
{
base.OnElementChanged(e);
UpdateBgColor();
UpdateFgColor();
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == ExtendedStepper.StepperBackgroundColorProperty.PropertyName)
{
UpdateBgColor();
}
else if (e.PropertyName == ExtendedStepper.StepperForegroundColorProperty.PropertyName)
{
UpdateFgColor();
}
}
private void UpdateBgColor()
{
if (Control != null && Element is ExtendedStepper view)
{
if (Build.VERSION.SdkInt >= BuildVersionCodes.Q)
{
Control.GetChildAt(0)?.Background?.SetColorFilter(
new BlendModeColorFilter(view.StepperBackgroundColor.ToAndroid(), BlendMode.Multiply));
Control.GetChildAt(1)?.Background?.SetColorFilter(
new BlendModeColorFilter(view.StepperBackgroundColor.ToAndroid(), BlendMode.Multiply));
}
else
{
Control.GetChildAt(0)?.Background?.SetColorFilter(
view.StepperBackgroundColor.ToAndroid(), PorterDuff.Mode.Multiply);
Control.GetChildAt(1)?.Background?.SetColorFilter(
view.StepperBackgroundColor.ToAndroid(), PorterDuff.Mode.Multiply);
}
}
}
private void UpdateFgColor()
{
if (Control != null && Element is ExtendedStepper view)
{
var btn0 = Control.GetChildAt(0) as Android.Widget.Button;
btn0?.SetTextColor(view.StepperForegroundColor.ToAndroid());
var btn1 = Control.GetChildAt(1) as Android.Widget.Button;
btn1?.SetTextColor(view.StepperForegroundColor.ToAndroid());
}
}
}
}

View File

@@ -0,0 +1,50 @@
using System.ComponentModel;
using Android.Content;
using Android.Views;
using Bit.App.Controls;
using Bit.Droid.Renderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(ExtendedTimePicker), typeof(ExtendedTimePickerRenderer))]
namespace Bit.Droid.Renderers
{
public class ExtendedTimePickerRenderer : TimePickerRenderer
{
public ExtendedTimePickerRenderer(Context context)
: base(context) { }
protected override void OnElementChanged(ElementChangedEventArgs<TimePicker> e)
{
base.OnElementChanged(e);
if (Control != null && Element is ExtendedTimePicker element)
{
// center text
Control.Gravity = GravityFlags.CenterHorizontal;
// use placeholder until NullableTime set
if (!element.NullableTime.HasValue)
{
Control.Text = element.PlaceHolder;
}
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == TimePicker.TimeProperty.PropertyName ||
e.PropertyName == TimePicker.FormatProperty.PropertyName)
{
if (Control != null && Element is ExtendedTimePicker element)
{
if (Element.Format == element.PlaceHolder)
{
Control.Text = element.PlaceHolder;
return;
}
}
}
base.OnElementPropertyChanged(sender, e);
}
}
}

View File

@@ -28,20 +28,20 @@ namespace Bit.Droid.Renderers
{
base.OnElementChanged(e);
if(Control == null)
if (Control == null)
{
var webView = new AWebkit.WebView(_context);
webView.Settings.JavaScriptEnabled = true;
webView.SetWebViewClient(new JSWebViewClient(string.Format("javascript: {0}", JSFunction)));
SetNativeControl(webView);
}
if(e.OldElement != null)
if (e.OldElement != null)
{
Control.RemoveJavascriptInterface("jsBridge");
var hybridWebView = e.OldElement as HybridWebView;
hybridWebView.Cleanup();
}
if(e.NewElement != null)
if (e.NewElement != null)
{
Control.AddJavascriptInterface(new JSBridge(this), "jsBridge");
Control.LoadUrl(Element.Uri);
@@ -51,7 +51,7 @@ namespace Bit.Droid.Renderers
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if(e.PropertyName == HybridWebView.UriProperty.PropertyName)
if (e.PropertyName == HybridWebView.UriProperty.PropertyName)
{
Control.LoadUrl(Element.Uri);
}
@@ -70,7 +70,7 @@ namespace Bit.Droid.Renderers
[Export("invokeAction")]
public void InvokeAction(string data)
{
if(_hybridWebViewRenderer != null &&
if (_hybridWebViewRenderer != null &&
_hybridWebViewRenderer.TryGetTarget(out HybridWebViewRenderer hybridRenderer))
{
hybridRenderer.Element.InvokeAction(data);

View File

@@ -0,0 +1,25 @@
using System;
using Android.Content;
using Bit.App.Controls;
using Bit.Droid.Renderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(SelectableLabel), typeof(SelectableLabelRenderer))]
namespace Bit.Droid.Renderers
{
public class SelectableLabelRenderer : LabelRenderer
{
public SelectableLabelRenderer(Context context) : base(context) { }
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.SetTextIsSelectable(true);
}
}
}
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 180 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 775 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 487 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 581 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 904 B

View File

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 495 B

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