Compare commits
406 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ee9ecfbee9 | ||
|
|
9d8a9387bc | ||
|
|
8934cebc2a | ||
|
|
c03a42e108 | ||
|
|
a39dfcf4d5 | ||
|
|
f25ab537f2 | ||
|
|
ff776e485a | ||
|
|
3b9f4433ad | ||
|
|
a8c18cf83a | ||
|
|
dff91dc67d | ||
|
|
fdea212415 | ||
|
|
421f7e8799 | ||
|
|
8fc5ad099b | ||
|
|
0b1c0be0f0 | ||
|
|
5cc1e2bb29 | ||
|
|
c0eb84b7b1 | ||
|
|
66e8d955d9 | ||
|
|
e280f585cf | ||
|
|
366578600b | ||
|
|
8611501423 | ||
|
|
8175af4e84 | ||
|
|
7ff628ea51 | ||
|
|
5792372a47 | ||
|
|
9a169251d7 | ||
|
|
2f0935dbbe | ||
|
|
5af7c7d58a | ||
|
|
9e1abb13a3 | ||
|
|
bbea5fe53c | ||
|
|
ed087b81b4 | ||
|
|
0b06c87cb7 | ||
|
|
a9d204d3fa | ||
|
|
36e263b9ff | ||
|
|
49af74729f | ||
|
|
aec0415cad | ||
|
|
8c8cec08e5 | ||
|
|
8d0ee1caba | ||
|
|
a2a6d5a57f | ||
|
|
9593f330db | ||
|
|
144d932591 | ||
|
|
726db336a8 | ||
|
|
8632f7cadc | ||
|
|
525b5fa19a | ||
|
|
b7c6b65a3d | ||
|
|
a4f93eea45 | ||
|
|
8d9a5bc08f | ||
|
|
28a93cdcb4 | ||
|
|
d32dd95e12 | ||
|
|
f19a8a3cc5 | ||
|
|
f8d5ee9d5d | ||
|
|
a98fb7d41e | ||
|
|
d2ccc5c022 | ||
|
|
3339c8b676 | ||
|
|
2cc331b136 | ||
|
|
df1a65e6a3 | ||
|
|
f416f95b77 | ||
|
|
44fe5af4fb | ||
|
|
f394eddc01 | ||
|
|
07dd9df3ec | ||
|
|
340d4ce714 | ||
|
|
2870b8331e | ||
|
|
bc79f22e22 | ||
|
|
b3e0b148a6 | ||
|
|
6131dfeb2c | ||
|
|
42fc868b68 | ||
|
|
e9ec02929d | ||
|
|
389d7d77c2 | ||
|
|
03a55d38d3 | ||
|
|
5504298251 | ||
|
|
0fff61de34 | ||
|
|
4db7311611 | ||
|
|
650d970b5e | ||
|
|
7f796963f3 | ||
|
|
9231da2f1c | ||
|
|
0d422c53d1 | ||
|
|
7bf9354e32 | ||
|
|
277fd67814 | ||
|
|
68e9cd3779 | ||
|
|
73b2ae71a9 | ||
|
|
f9028245d8 | ||
|
|
3fff0617fe | ||
|
|
d958dc6bce | ||
|
|
045ce42168 | ||
|
|
edef84a4f9 | ||
|
|
ec9b2d7f7d | ||
|
|
640beeed23 | ||
|
|
a998ee84ec | ||
|
|
bd74634201 | ||
|
|
364287028b | ||
|
|
7be8513bb5 | ||
|
|
89c2f62f11 | ||
|
|
fce2a7ba94 | ||
|
|
e613198252 | ||
|
|
3e240c4d2f | ||
|
|
eee96bf8cf | ||
|
|
471871eb2e | ||
|
|
225b8b8cd8 | ||
|
|
cb2d133eb0 | ||
|
|
d957111249 | ||
|
|
f0a701e134 | ||
|
|
0c8c216fba | ||
|
|
f153c7509c | ||
|
|
197683b722 | ||
|
|
fbce0be457 | ||
|
|
24304c2f55 | ||
|
|
b0c6c09cea | ||
|
|
2732fc93f9 | ||
|
|
cc9a4a288a | ||
|
|
f57db917d1 | ||
|
|
d32eb9c9bc | ||
|
|
219af7f288 | ||
|
|
e767b6c5be | ||
|
|
5f1a8017f1 | ||
|
|
df80122ce1 | ||
|
|
6904ea118b | ||
|
|
0baa07daa2 | ||
|
|
2abf407b36 | ||
|
|
55dc9cbfc7 | ||
|
|
fa15a10ae0 | ||
|
|
e821d8a135 | ||
|
|
cefcc14d4d | ||
|
|
a52d1e1506 | ||
|
|
42df1aecd5 | ||
|
|
920f4fc525 | ||
|
|
d57d583076 | ||
|
|
1c8cd2dcbb | ||
|
|
bb66a6c805 | ||
|
|
10ecdfbe31 | ||
|
|
43dad1df63 | ||
|
|
fdcc6b0cb8 | ||
|
|
ac82d6bc6b | ||
|
|
a8e98cfa78 | ||
|
|
fa51314639 | ||
|
|
3e0097c22c | ||
|
|
e62ff2fe36 | ||
|
|
88a13eb54f | ||
|
|
355dc151c4 | ||
|
|
4f0ea44078 | ||
|
|
9cc12fd577 | ||
|
|
960c2567bd | ||
|
|
430e4dd445 | ||
|
|
1ec31c6899 | ||
|
|
42c21ce892 | ||
|
|
d278fde5f2 | ||
|
|
2616a5f500 | ||
|
|
cc58f7730e | ||
|
|
d49e001b21 | ||
|
|
f12ceb69ce | ||
|
|
7862005055 | ||
|
|
e70dbf8d8d | ||
|
|
16ee34d7a7 | ||
|
|
2ad55e8a8c | ||
|
|
a8a1750d5c | ||
|
|
5407e20150 | ||
|
|
58aa37bf8e | ||
|
|
7c781b60c5 | ||
|
|
acdfce7e88 | ||
|
|
4e4b56d7fe | ||
|
|
a3174d7015 | ||
|
|
b595c8aeac | ||
|
|
a9a33ad71e | ||
|
|
4d08ce90cc | ||
|
|
01d9ccc110 | ||
|
|
029f069ad5 | ||
|
|
13b9e01604 | ||
|
|
19c46a472a | ||
|
|
37edfffb97 | ||
|
|
67fa653d06 | ||
|
|
366b9ddc4a | ||
|
|
c9354f79b8 | ||
|
|
d5b3bd5905 | ||
|
|
45dd240415 | ||
|
|
bf99cea004 | ||
|
|
f680b1e856 | ||
|
|
b2f40c7af0 | ||
|
|
82b17677b9 | ||
|
|
b7df2d5441 | ||
|
|
dd511ba365 | ||
|
|
d705e3c1fb | ||
|
|
4bd1322904 | ||
|
|
ac027ee3a0 | ||
|
|
e5e3ebdbba | ||
|
|
993fc2e6f4 | ||
|
|
61c480618c | ||
|
|
db7f2622c8 | ||
|
|
a39e78a989 | ||
|
|
5a461d68a7 | ||
|
|
899816673c | ||
|
|
84a10139c1 | ||
|
|
da3aa56d86 | ||
|
|
a6dcd512ea | ||
|
|
572d32c1de | ||
|
|
e8b67ead1e | ||
|
|
377029226e | ||
|
|
72d1421f1d | ||
|
|
d359547dab | ||
|
|
9523c7ab33 | ||
|
|
7cac07c185 | ||
|
|
a607a7f3ef | ||
|
|
b5277e89d5 | ||
|
|
99713f8ed7 | ||
|
|
145dac500c | ||
|
|
eefd9bf31c | ||
|
|
3f47ca645b | ||
|
|
c906f037b5 | ||
|
|
ffc4e32119 | ||
|
|
51eb46241b | ||
|
|
541416f64b | ||
|
|
14d1d132a3 | ||
|
|
22a0045796 | ||
|
|
2e5ba0335d | ||
|
|
3315704c14 | ||
|
|
f90c407fb6 | ||
|
|
d3646e10a5 | ||
|
|
d3003efe72 | ||
|
|
235ca947be | ||
|
|
e7bc9ed5ba | ||
|
|
740a18dbc0 | ||
|
|
add5189bb1 | ||
|
|
62002b8bb3 | ||
|
|
41b4ee33fe | ||
|
|
85c67ac676 | ||
|
|
4637b7d93f | ||
|
|
8b9a178c87 | ||
|
|
c595c381a9 | ||
|
|
c308d7a610 | ||
|
|
f7570122c6 | ||
|
|
1e5f186b58 | ||
|
|
b732b2ffa7 | ||
|
|
617a7be4f3 | ||
|
|
5c5e368d6b | ||
|
|
ff9f49416a | ||
|
|
93cae0e9cc | ||
|
|
61e75ce747 | ||
|
|
50affe26c5 | ||
|
|
8566362607 | ||
|
|
36925770d0 | ||
|
|
d17ca1686e | ||
|
|
2ad709dae4 | ||
|
|
5a3d86a12a | ||
|
|
1a4ba36820 | ||
|
|
ddeae3b5ba | ||
|
|
10df9e7cd5 | ||
|
|
be11933c60 | ||
|
|
d2db68b781 | ||
|
|
da6e271584 | ||
|
|
5103c80e1e | ||
|
|
b5c80ea267 | ||
|
|
b5747fbb44 | ||
|
|
215ded8a77 | ||
|
|
e7ab6da068 | ||
|
|
ee881f67ee | ||
|
|
f33248aa4f | ||
|
|
c6a40bac03 | ||
|
|
aa38e79d08 | ||
|
|
9cac10e559 | ||
|
|
efbd418f56 | ||
|
|
4ff3464abd | ||
|
|
907ddbf903 | ||
|
|
7041991d5a | ||
|
|
b26067e5da | ||
|
|
e519b13533 | ||
|
|
30bc3867bf | ||
|
|
5326c3aecc | ||
|
|
c95251c903 | ||
|
|
e08a0a0938 | ||
|
|
fcb072c37d | ||
|
|
262c19b194 | ||
|
|
1031ddcd83 | ||
|
|
aaee0212f0 | ||
|
|
8fc95759ba | ||
|
|
b6a3a0a54f | ||
|
|
e3091be314 | ||
|
|
045d0678b3 | ||
|
|
e3eeaddb3e | ||
|
|
f2b202c714 | ||
|
|
e6f3ad60ef | ||
|
|
fb6e0c9eb8 | ||
|
|
fb6e488339 | ||
|
|
0bccc8f0d5 | ||
|
|
560d831e92 | ||
|
|
7c8f6a1cc7 | ||
|
|
deb1ead4ea | ||
|
|
005b2a4fb6 | ||
|
|
4c8204f29a | ||
|
|
83fd19784a | ||
|
|
1f21a2ecc7 | ||
|
|
c3f4d56d1e | ||
|
|
7e4f79bacb | ||
|
|
b8267d4329 | ||
|
|
205ca693b3 | ||
|
|
23159c2201 | ||
|
|
884521ced0 | ||
|
|
aeb01ba292 | ||
|
|
2b1a556e9e | ||
|
|
d5c3ae3d19 | ||
|
|
7654bb7088 | ||
|
|
64c301caeb | ||
|
|
e875b530b1 | ||
|
|
ee8c2b5272 | ||
|
|
9b8bdb0639 | ||
|
|
1a99bbb040 | ||
|
|
0982b45473 | ||
|
|
bcd210d504 | ||
|
|
c71608824b | ||
|
|
170876ac16 | ||
|
|
a6b172c445 | ||
|
|
e625450100 | ||
|
|
fca5447094 | ||
|
|
89f32beec5 | ||
|
|
65eb7662ad | ||
|
|
ea090dbe18 | ||
|
|
5750817620 | ||
|
|
93386d0e8b | ||
|
|
e9dd7b8f98 | ||
|
|
5010e7cb7a | ||
|
|
fb35f4fbca | ||
|
|
00c0a93a6b | ||
|
|
cd9a312e0b | ||
|
|
8cdb27fe43 | ||
|
|
d84d11d064 | ||
|
|
5d646a6112 | ||
|
|
dd334858ff | ||
|
|
dfd39ebc95 | ||
|
|
9dbb1f15a4 | ||
|
|
32fd04a7d9 | ||
|
|
3a33ff375d | ||
|
|
8877e71bd2 | ||
|
|
5b5385c01d | ||
|
|
9c365ecc48 | ||
|
|
99d1a6d043 | ||
|
|
854ef7e645 | ||
|
|
a8eeb12325 | ||
|
|
86a3f516b1 | ||
|
|
d6818939b3 | ||
|
|
c51449e607 | ||
|
|
333894ddeb | ||
|
|
052e227b65 | ||
|
|
4dd6df5bbe | ||
|
|
8847991bba | ||
|
|
0ffc6e4a1a | ||
|
|
9a399e06f3 | ||
|
|
6afccc2aea | ||
|
|
8cd3a21468 | ||
|
|
8b6d2d2b83 | ||
|
|
a39f4d5987 | ||
|
|
e236d045b0 | ||
|
|
592c7951df | ||
|
|
41efa96291 | ||
|
|
53f406a267 | ||
|
|
1390df48b6 | ||
|
|
01878ef00c | ||
|
|
6f119f25f4 | ||
|
|
3f31d78db1 | ||
|
|
014bf7777b | ||
|
|
7191969e9c | ||
|
|
0950510526 | ||
|
|
9eba3064a7 | ||
|
|
a4d785258e | ||
|
|
efef49f976 | ||
|
|
32a7b5bafb | ||
|
|
5fa080063c | ||
|
|
b3573f9482 | ||
|
|
916b7ee46b | ||
|
|
bfe8ad2034 | ||
|
|
bb9db7bf9d | ||
|
|
d7f7c8c568 | ||
|
|
10839588dd | ||
|
|
12cd2b67cd | ||
|
|
9a13036f4e | ||
|
|
2f025d51ff | ||
|
|
6cb6d3a358 | ||
|
|
0bb01d14bd | ||
|
|
2229c4e4d1 | ||
|
|
5c90c62378 | ||
|
|
b7ed0a29fe | ||
|
|
796c2ed58c | ||
|
|
39bd573d9d | ||
|
|
d4aaa547a7 | ||
|
|
f7e2382847 | ||
|
|
4bb16e7d93 | ||
|
|
e7e00e4ebf | ||
|
|
55d050fca7 | ||
|
|
98d4fef0ee | ||
|
|
5521892736 | ||
|
|
8f0fd0dfef | ||
|
|
514eab0b98 | ||
|
|
e35c84245d | ||
|
|
4a2391eb1b | ||
|
|
04eb497e10 | ||
|
|
a9a5da6dc6 | ||
|
|
3f1aab27d6 | ||
|
|
8f77df4ebb | ||
|
|
65a8b3fcd4 | ||
|
|
71dd4e512e | ||
|
|
ca03a5ecf4 | ||
|
|
694efb9508 | ||
|
|
c60a112039 | ||
|
|
c3570dd07a | ||
|
|
b680b190d4 | ||
|
|
310d51d859 | ||
|
|
cf9e820227 | ||
|
|
b91d2f4fb1 | ||
|
|
9456f5dc31 | ||
|
|
fa9e22730a | ||
|
|
7261fd7ed9 | ||
|
|
ad9e5fbf07 |
@@ -6,8 +6,8 @@ Code contributions are welcome! Please commit any pull requests against the `mas
|
||||
|
||||
We use a translation tool called [Crowdin](https://crowdin.com) to help manage our localization efforts across many different languages.
|
||||
|
||||
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 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/mail/compose/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/kspearrin).
|
||||
|
||||
You can read Crowdin's getting started guide for translators here: https://support.crowdin.com/crowdin-intro/
|
||||
|
||||
5
ISSUE_TEMPLATE.md
Normal file
@@ -0,0 +1,5 @@
|
||||
<!--
|
||||
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
|
||||
-->
|
||||
12
README.md
@@ -2,24 +2,28 @@
|
||||
[](https://crowdin.com/project/bitwarden-mobile)
|
||||
[](https://gitter.im/bitwarden/Lobby)
|
||||
|
||||
# bitwarden mobile
|
||||
# Bitwarden Mobile Application
|
||||
|
||||
<a href="https://play.google.com/store/apps/details?id=com.x8bit.bitwarden" target="_blank"><img alt="Get it on Google Play" src="https://imgur.com/YQzmZi9.png" width="153" height="46"></a> <a href="https://itunes.apple.com/us/app/bitwarden-free-password-manager/id1137397744?mt=8" target="_blank"><img src="https://imgur.com/GdGqPMY.png" width="135" height="40"></a>
|
||||
|
||||
The bitwarden mobile application is written in C# with Xamarin Android, Xamarin iOS, and Xamarin Forms.
|
||||
The Bitwarden mobile application is written in C# with Xamarin Android, Xamarin iOS, UWP, and Xamarin Forms.
|
||||
|
||||
<img src="https://i.imgur.com/Ty8wkSO.png" alt="" width="300" height="533" /> <img src="https://i.imgur.com/BYb4gVc.png" alt="" width="300" height="533" />
|
||||
<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" />
|
||||
|
||||
# Build/Run
|
||||
|
||||
**Requirements**
|
||||
|
||||
- [Visual Studio w/ Xamarin -or- Xamarin Studio](https://store.xamarin.com/)
|
||||
- [Visual Studio](https://store.xamarin.com/)
|
||||
|
||||
**API endpoint**
|
||||
|
||||
By default the app is targeting the production API. If you are running the [Core](https://github.com/bitwarden/core) API locally,
|
||||
you'll need to switch the app to target your local instance. Open `src/App/Utilities/ApiHttpClient.cs` and `src/App/Utilities/IdentityHttpClient.cs` and set the `BaseAddress` to your local
|
||||
API endpoints (ex. `new Uri("http://localhost:5000")`). Alternatively, you can also adjust the environment endpoints from the environment settings page on the home screen of the app (log out).
|
||||
|
||||
**Run the app**
|
||||
|
||||
After restoring the nuget packages, you can now build and run the app.
|
||||
|
||||
# Contribute
|
||||
|
||||
16
SECURITY.md
@@ -1,4 +1,4 @@
|
||||
bitwarden believes that working with security researchers across the globe is crucial to keeping our
|
||||
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!
|
||||
|
||||
@@ -16,7 +16,7 @@ notify us. We welcome working with you to resolve the issue promptly. Thanks in
|
||||
|
||||
# In-scope
|
||||
|
||||
- Security issues in any current release of bitwarden. This includes the web vault, browser extension,
|
||||
- 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.
|
||||
|
||||
@@ -24,14 +24,14 @@ notify us. We welcome working with you to resolve the issue promptly. Thanks in
|
||||
|
||||
The following bug classes are out-of scope:
|
||||
|
||||
- Bugs that are already reported on any of bitwarden's issue trackers (https://github.com/bitwarden),
|
||||
- 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
|
||||
- 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
|
||||
|
||||
@@ -39,7 +39,7 @@ While researching, we'd like to ask you to refrain from:
|
||||
|
||||
- Denial of service
|
||||
- Spamming
|
||||
- Social engineering (including phishing) of bitwarden staff or contractors
|
||||
- Any physical attempts against bitwarden property or data centers
|
||||
- Social engineering (including phishing) of Bitwarden staff or contractors
|
||||
- Any physical attempts against Bitwarden property or data centers
|
||||
|
||||
Thank you for helping keep bitwarden and our users safe!
|
||||
Thank you for helping keep Bitwarden and our users safe!
|
||||
|
||||
22
appveyor.yml
@@ -1,21 +1,29 @@
|
||||
install:
|
||||
- appveyor DownloadFile https://dist.nuget.org/win-x86-commandline/latest/nuget.exe
|
||||
#init:
|
||||
# - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||
#on_finish:
|
||||
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||
#install:
|
||||
# - choco install cloc --no-progress
|
||||
# - "cloc --vcs git --exclude-dir Resources,store,test,UWP,Properties --include-lang C#,JavaScript,TypeScript,PowerShell"
|
||||
# - appveyor DownloadFile https://dist.nuget.org/win-x86-commandline/latest/nuget.exe
|
||||
# - appveyor DownloadFile https://aka.ms/vs/15/release/vs_community.exe
|
||||
# - vs_community.exe update --wait --quiet --norestart --installPath "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community"
|
||||
# - ps: .\src\Android\update-android.ps1
|
||||
before_build:
|
||||
- nuget restore
|
||||
- IF DEFINED keystore_dec_secret nuget install secure-file -ExcludeVersion
|
||||
- IF DEFINED google_services_dec_secret secure-file\tools\secure-file -decrypt src\Android\google-services.json.enc -secret %google_services_dec_secret%
|
||||
after_build:
|
||||
- ps: IF($env:keystore_dec_secret) { .\src\Android\increment-version.ps1 $($env:APPVEYOR_BUILD_FOLDER) $($env:APPVEYOR_BUILD_NUMBER) }
|
||||
- IF DEFINED keystore_dec_secret secure-file\tools\secure-file -decrypt src\Android\8bit.keystore.enc -secret %keystore_dec_secret%
|
||||
- IF DEFINED keystore_password msbuild "/t:SignAndroidPackage" "/p:Configuration=Release" "/p:AndroidKeyStore=true" "/p:AndroidSigningKeyAlias=bitwarden" "/p:AndroidSigningKeyPass=%keystore_password%" "/p:AndroidSigningKeyStore=8bit.keystore" "/p:AndroidSigningStorePass=%keystore_password%" "src\Android\Android.csproj"
|
||||
- ps: IF($env:keystore_dec_secret) { copy-item src\Android\bin\Release\com.x8bit.bitwarden-Signed.apk .\com.x8bit.bitwarden-$($env:APPVEYOR_BUILD_NUMBER).apk }
|
||||
- ps: IF($env:keystore_dec_secret) { .\src\Android\ci-build-apks.ps1 }
|
||||
on_success:
|
||||
- IF DEFINED play_dec_secret secure-file\tools\secure-file -decrypt store\google\Publisher\play_creds.json.enc -secret %play_dec_secret%
|
||||
- IF DEFINED play_dec_secret dotnet store\google\Publisher\bin\Debug\netcoreapp2.0\Publisher.dll %APPVEYOR_BUILD_FOLDER%\store\google\Publisher\play_creds.json %APPVEYOR_BUILD_FOLDER%\src\Android\bin\Release\com.x8bit.bitwarden-Signed.apk alpha
|
||||
- IF DEFINED play_dec_secret dotnet store\google\Publisher\bin\Release\netcoreapp2.0\Publisher.dll %APPVEYOR_BUILD_FOLDER%\store\google\Publisher\play_creds.json %APPVEYOR_BUILD_FOLDER%\com.x8bit.bitwarden-%APPVEYOR_BUILD_NUMBER%.apk alpha
|
||||
artifacts:
|
||||
- path: com.x8bit.bitwarden-%APPVEYOR_BUILD_NUMBER%.apk
|
||||
- path: com.x8bit.bitwarden-fdroid-%APPVEYOR_BUILD_NUMBER%.apk
|
||||
branches:
|
||||
except:
|
||||
- l10n_master
|
||||
skip_tags: true
|
||||
configuration: Release
|
||||
image: Visual Studio 2017
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.27130.2003
|
||||
VisualStudioVersion = 15.0.27130.2010
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Android", "src\Android\Android.csproj", "{04B18ED2-B76D-4947-8474-191F8FD2B5E0}"
|
||||
EndProject
|
||||
@@ -21,13 +21,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "store", "store", "{92470CBD
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "google", "google", "{2E399654-26A2-46F6-B9CA-1B496A3F370A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UWP", "src\UWP\UWP.csproj", "{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}"
|
||||
EndProject
|
||||
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "UWP.Images", "src\UWP.Images\UWP.Images.shproj", "{0BE54BBB-7772-4289-BD51-1FDBB0CC2446}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "App", "src\App\App.csproj", "{8A279EE4-4537-4656-9C93-44945E594556}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Publisher", "store\google\Publisher\Publisher.csproj", "{D5D91152-CB01-4F24-A503-304D3A94408B}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Publisher", "store\google\Publisher\Publisher.csproj", "{D5D91152-CB01-4F24-A503-304D3A94408B}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{F0E2E596-C3DB-474A-9C88-7824662894FA}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
@@ -38,11 +34,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
||||
SECURITY.md = SECURITY.md
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.Autofill", "src\iOS.Autofill\iOS.Autofill.csproj", "{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SharedMSBuildProjectFiles) = preSolution
|
||||
src\UWP.Images\UWP.Images.projitems*{0be54bbb-7772-4289-bd51-1fdbb0cc2446}*SharedItemsImports = 13
|
||||
src\UWP.Images\UWP.Images.projitems*{3a2d5669-ed71-4f2b-ba85-2d36baa05141}*SharedItemsImports = 4
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Ad-Hoc|Any CPU = Ad-Hoc|Any CPU
|
||||
Ad-Hoc|ARM = Ad-Hoc|ARM
|
||||
@@ -62,6 +56,12 @@ Global
|
||||
Debug|iPhoneSimulator = Debug|iPhoneSimulator
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
FDroid|Any CPU = FDroid|Any CPU
|
||||
FDroid|ARM = FDroid|ARM
|
||||
FDroid|iPhone = FDroid|iPhone
|
||||
FDroid|iPhoneSimulator = FDroid|iPhoneSimulator
|
||||
FDroid|x64 = FDroid|x64
|
||||
FDroid|x86 = FDroid|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|ARM = Release|ARM
|
||||
Release|iPhone = Release|iPhone
|
||||
@@ -110,6 +110,24 @@ Global
|
||||
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Debug|x86.Deploy.0 = Debug|Any CPU
|
||||
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.FDroid|Any CPU.ActiveCfg = FDroid|Any CPU
|
||||
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.FDroid|Any CPU.Build.0 = FDroid|Any CPU
|
||||
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.FDroid|Any CPU.Deploy.0 = FDroid|Any CPU
|
||||
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.FDroid|ARM.ActiveCfg = FDroid|Any CPU
|
||||
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.FDroid|ARM.Build.0 = FDroid|Any CPU
|
||||
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.FDroid|ARM.Deploy.0 = FDroid|Any CPU
|
||||
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.FDroid|iPhone.ActiveCfg = FDroid|Any CPU
|
||||
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.FDroid|iPhone.Build.0 = FDroid|Any CPU
|
||||
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.FDroid|iPhone.Deploy.0 = FDroid|Any CPU
|
||||
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.FDroid|iPhoneSimulator.ActiveCfg = FDroid|Any CPU
|
||||
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.FDroid|iPhoneSimulator.Build.0 = FDroid|Any CPU
|
||||
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.FDroid|iPhoneSimulator.Deploy.0 = FDroid|Any CPU
|
||||
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.FDroid|x64.ActiveCfg = FDroid|Any CPU
|
||||
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.FDroid|x64.Build.0 = FDroid|Any CPU
|
||||
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.FDroid|x64.Deploy.0 = FDroid|Any CPU
|
||||
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.FDroid|x86.ActiveCfg = FDroid|Any CPU
|
||||
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.FDroid|x86.Build.0 = FDroid|Any CPU
|
||||
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.FDroid|x86.Deploy.0 = FDroid|Any CPU
|
||||
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||
@@ -149,6 +167,18 @@ Global
|
||||
{1F78403F-9A28-405B-9289-B9DBEB55F074}.Debug|x64.ActiveCfg = Debug|iPhone
|
||||
{1F78403F-9A28-405B-9289-B9DBEB55F074}.Debug|x86.ActiveCfg = Debug|iPhone
|
||||
{1F78403F-9A28-405B-9289-B9DBEB55F074}.Debug|x86.Build.0 = Debug|iPhone
|
||||
{1F78403F-9A28-405B-9289-B9DBEB55F074}.FDroid|Any CPU.ActiveCfg = Release|iPhoneSimulator
|
||||
{1F78403F-9A28-405B-9289-B9DBEB55F074}.FDroid|Any CPU.Build.0 = Release|iPhoneSimulator
|
||||
{1F78403F-9A28-405B-9289-B9DBEB55F074}.FDroid|ARM.ActiveCfg = Release|iPhoneSimulator
|
||||
{1F78403F-9A28-405B-9289-B9DBEB55F074}.FDroid|ARM.Build.0 = Release|iPhoneSimulator
|
||||
{1F78403F-9A28-405B-9289-B9DBEB55F074}.FDroid|iPhone.ActiveCfg = Release|iPhone
|
||||
{1F78403F-9A28-405B-9289-B9DBEB55F074}.FDroid|iPhone.Build.0 = Release|iPhone
|
||||
{1F78403F-9A28-405B-9289-B9DBEB55F074}.FDroid|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
|
||||
{1F78403F-9A28-405B-9289-B9DBEB55F074}.FDroid|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
|
||||
{1F78403F-9A28-405B-9289-B9DBEB55F074}.FDroid|x64.ActiveCfg = Release|iPhoneSimulator
|
||||
{1F78403F-9A28-405B-9289-B9DBEB55F074}.FDroid|x64.Build.0 = Release|iPhoneSimulator
|
||||
{1F78403F-9A28-405B-9289-B9DBEB55F074}.FDroid|x86.ActiveCfg = Release|iPhoneSimulator
|
||||
{1F78403F-9A28-405B-9289-B9DBEB55F074}.FDroid|x86.Build.0 = Release|iPhoneSimulator
|
||||
{1F78403F-9A28-405B-9289-B9DBEB55F074}.Release|Any CPU.ActiveCfg = Release|iPhone
|
||||
{1F78403F-9A28-405B-9289-B9DBEB55F074}.Release|ARM.ActiveCfg = Release|iPhone
|
||||
{1F78403F-9A28-405B-9289-B9DBEB55F074}.Release|iPhone.ActiveCfg = Release|iPhone
|
||||
@@ -186,6 +216,18 @@ Global
|
||||
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.FDroid|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.FDroid|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.FDroid|ARM.ActiveCfg = Debug|Any CPU
|
||||
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.FDroid|ARM.Build.0 = Debug|Any CPU
|
||||
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.FDroid|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.FDroid|iPhone.Build.0 = Debug|Any CPU
|
||||
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.FDroid|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.FDroid|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.FDroid|x64.ActiveCfg = Debug|Any CPU
|
||||
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.FDroid|x64.Build.0 = Debug|Any CPU
|
||||
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.FDroid|x86.ActiveCfg = Debug|Any CPU
|
||||
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.FDroid|x86.Build.0 = Debug|Any CPU
|
||||
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
@@ -221,6 +263,18 @@ Global
|
||||
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.Debug|x64.ActiveCfg = Debug|iPhone
|
||||
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.Debug|x86.ActiveCfg = Debug|iPhone
|
||||
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.Debug|x86.Build.0 = Debug|iPhone
|
||||
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.FDroid|Any CPU.ActiveCfg = Release|iPhoneSimulator
|
||||
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.FDroid|Any CPU.Build.0 = Release|iPhoneSimulator
|
||||
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.FDroid|ARM.ActiveCfg = Release|iPhoneSimulator
|
||||
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.FDroid|ARM.Build.0 = Release|iPhoneSimulator
|
||||
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.FDroid|iPhone.ActiveCfg = Release|iPhone
|
||||
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.FDroid|iPhone.Build.0 = Release|iPhone
|
||||
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.FDroid|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
|
||||
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.FDroid|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
|
||||
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.FDroid|x64.ActiveCfg = Release|iPhoneSimulator
|
||||
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.FDroid|x64.Build.0 = Release|iPhoneSimulator
|
||||
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.FDroid|x86.ActiveCfg = Release|iPhoneSimulator
|
||||
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.FDroid|x86.Build.0 = Release|iPhoneSimulator
|
||||
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.Release|Any CPU.ActiveCfg = Release|iPhone
|
||||
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.Release|ARM.ActiveCfg = Release|iPhone
|
||||
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.Release|iPhone.ActiveCfg = Release|iPhone
|
||||
@@ -262,6 +316,18 @@ Global
|
||||
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.FDroid|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.FDroid|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.FDroid|ARM.ActiveCfg = Debug|Any CPU
|
||||
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.FDroid|ARM.Build.0 = Debug|Any CPU
|
||||
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.FDroid|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.FDroid|iPhone.Build.0 = Debug|Any CPU
|
||||
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.FDroid|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.FDroid|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.FDroid|x64.ActiveCfg = Debug|Any CPU
|
||||
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.FDroid|x64.Build.0 = Debug|Any CPU
|
||||
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.FDroid|x86.ActiveCfg = Debug|Any CPU
|
||||
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.FDroid|x86.Build.0 = Debug|Any CPU
|
||||
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
@@ -272,66 +338,6 @@ Global
|
||||
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Release|x64.Build.0 = Release|Any CPU
|
||||
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Release|x86.Build.0 = Release|Any CPU
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Ad-Hoc|Any CPU.ActiveCfg = Release|x64
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Ad-Hoc|Any CPU.Build.0 = Release|x64
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Ad-Hoc|Any CPU.Deploy.0 = Release|x64
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Ad-Hoc|ARM.ActiveCfg = Release|ARM
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Ad-Hoc|ARM.Build.0 = Release|ARM
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Ad-Hoc|ARM.Deploy.0 = Release|ARM
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Ad-Hoc|iPhone.ActiveCfg = Release|x64
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Ad-Hoc|iPhone.Build.0 = Release|x64
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Ad-Hoc|iPhone.Deploy.0 = Release|x64
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|x64
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|x64
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Ad-Hoc|iPhoneSimulator.Deploy.0 = Release|x64
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Ad-Hoc|x64.ActiveCfg = Release|x64
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Ad-Hoc|x64.Build.0 = Release|x64
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Ad-Hoc|x64.Deploy.0 = Release|x64
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Ad-Hoc|x86.ActiveCfg = Release|x86
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Ad-Hoc|x86.Build.0 = Release|x86
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Ad-Hoc|x86.Deploy.0 = Release|x86
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.AppStore|Any CPU.ActiveCfg = Release|x64
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.AppStore|Any CPU.Build.0 = Release|x64
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.AppStore|Any CPU.Deploy.0 = Release|x64
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.AppStore|ARM.ActiveCfg = Release|ARM
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.AppStore|ARM.Build.0 = Release|ARM
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.AppStore|ARM.Deploy.0 = Release|ARM
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.AppStore|iPhone.ActiveCfg = Release|x64
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.AppStore|iPhone.Build.0 = Release|x64
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.AppStore|iPhone.Deploy.0 = Release|x64
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.AppStore|iPhoneSimulator.ActiveCfg = Release|x64
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.AppStore|iPhoneSimulator.Build.0 = Release|x64
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.AppStore|iPhoneSimulator.Deploy.0 = Release|x64
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.AppStore|x64.ActiveCfg = Release|x64
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.AppStore|x64.Build.0 = Release|x64
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.AppStore|x64.Deploy.0 = Release|x64
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.AppStore|x86.ActiveCfg = Release|x86
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.AppStore|x86.Build.0 = Release|x86
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.AppStore|x86.Deploy.0 = Release|x86
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Debug|ARM.ActiveCfg = Debug|ARM
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Debug|ARM.Build.0 = Debug|ARM
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Debug|ARM.Deploy.0 = Debug|ARM
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Debug|iPhone.ActiveCfg = Debug|x86
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Debug|iPhoneSimulator.ActiveCfg = Debug|x86
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Debug|x64.Build.0 = Debug|x64
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Debug|x64.Deploy.0 = Debug|x64
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Debug|x86.Build.0 = Debug|x86
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Debug|x86.Deploy.0 = Debug|x86
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Release|Any CPU.ActiveCfg = Release|x86
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Release|ARM.ActiveCfg = Release|ARM
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Release|ARM.Build.0 = Release|ARM
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Release|ARM.Deploy.0 = Release|ARM
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Release|iPhone.ActiveCfg = Release|x86
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Release|iPhoneSimulator.ActiveCfg = Release|x86
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Release|x64.ActiveCfg = Release|x64
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Release|x64.Build.0 = Release|x64
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Release|x64.Deploy.0 = Release|x64
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Release|x86.ActiveCfg = Release|x86
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Release|x86.Build.0 = Release|x86
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141}.Release|x86.Deploy.0 = Release|x86
|
||||
{8A279EE4-4537-4656-9C93-44945E594556}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8A279EE4-4537-4656-9C93-44945E594556}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8A279EE4-4537-4656-9C93-44945E594556}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
|
||||
@@ -368,6 +374,18 @@ Global
|
||||
{8A279EE4-4537-4656-9C93-44945E594556}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{8A279EE4-4537-4656-9C93-44945E594556}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{8A279EE4-4537-4656-9C93-44945E594556}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{8A279EE4-4537-4656-9C93-44945E594556}.FDroid|Any CPU.ActiveCfg = FDroid|Any CPU
|
||||
{8A279EE4-4537-4656-9C93-44945E594556}.FDroid|Any CPU.Build.0 = FDroid|Any CPU
|
||||
{8A279EE4-4537-4656-9C93-44945E594556}.FDroid|ARM.ActiveCfg = FDroid|Any CPU
|
||||
{8A279EE4-4537-4656-9C93-44945E594556}.FDroid|ARM.Build.0 = FDroid|Any CPU
|
||||
{8A279EE4-4537-4656-9C93-44945E594556}.FDroid|iPhone.ActiveCfg = FDroid|Any CPU
|
||||
{8A279EE4-4537-4656-9C93-44945E594556}.FDroid|iPhone.Build.0 = FDroid|Any CPU
|
||||
{8A279EE4-4537-4656-9C93-44945E594556}.FDroid|iPhoneSimulator.ActiveCfg = FDroid|Any CPU
|
||||
{8A279EE4-4537-4656-9C93-44945E594556}.FDroid|iPhoneSimulator.Build.0 = FDroid|Any CPU
|
||||
{8A279EE4-4537-4656-9C93-44945E594556}.FDroid|x64.ActiveCfg = FDroid|Any CPU
|
||||
{8A279EE4-4537-4656-9C93-44945E594556}.FDroid|x64.Build.0 = FDroid|Any CPU
|
||||
{8A279EE4-4537-4656-9C93-44945E594556}.FDroid|x86.ActiveCfg = FDroid|Any CPU
|
||||
{8A279EE4-4537-4656-9C93-44945E594556}.FDroid|x86.Build.0 = FDroid|Any CPU
|
||||
{8A279EE4-4537-4656-9C93-44945E594556}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8A279EE4-4537-4656-9C93-44945E594556}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8A279EE4-4537-4656-9C93-44945E594556}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
@@ -416,6 +434,18 @@ Global
|
||||
{D5D91152-CB01-4F24-A503-304D3A94408B}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{D5D91152-CB01-4F24-A503-304D3A94408B}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{D5D91152-CB01-4F24-A503-304D3A94408B}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{D5D91152-CB01-4F24-A503-304D3A94408B}.FDroid|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D5D91152-CB01-4F24-A503-304D3A94408B}.FDroid|Any CPU.Build.0 = Release|Any CPU
|
||||
{D5D91152-CB01-4F24-A503-304D3A94408B}.FDroid|ARM.ActiveCfg = Release|Any CPU
|
||||
{D5D91152-CB01-4F24-A503-304D3A94408B}.FDroid|ARM.Build.0 = Release|Any CPU
|
||||
{D5D91152-CB01-4F24-A503-304D3A94408B}.FDroid|iPhone.ActiveCfg = Release|Any CPU
|
||||
{D5D91152-CB01-4F24-A503-304D3A94408B}.FDroid|iPhone.Build.0 = Release|Any CPU
|
||||
{D5D91152-CB01-4F24-A503-304D3A94408B}.FDroid|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{D5D91152-CB01-4F24-A503-304D3A94408B}.FDroid|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{D5D91152-CB01-4F24-A503-304D3A94408B}.FDroid|x64.ActiveCfg = Release|Any CPU
|
||||
{D5D91152-CB01-4F24-A503-304D3A94408B}.FDroid|x64.Build.0 = Release|Any CPU
|
||||
{D5D91152-CB01-4F24-A503-304D3A94408B}.FDroid|x86.ActiveCfg = Release|Any CPU
|
||||
{D5D91152-CB01-4F24-A503-304D3A94408B}.FDroid|x86.Build.0 = Release|Any CPU
|
||||
{D5D91152-CB01-4F24-A503-304D3A94408B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D5D91152-CB01-4F24-A503-304D3A94408B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D5D91152-CB01-4F24-A503-304D3A94408B}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
@@ -428,6 +458,50 @@ Global
|
||||
{D5D91152-CB01-4F24-A503-304D3A94408B}.Release|x64.Build.0 = Release|Any CPU
|
||||
{D5D91152-CB01-4F24-A503-304D3A94408B}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{D5D91152-CB01-4F24-A503-304D3A94408B}.Release|x86.Build.0 = Release|Any CPU
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhone
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.Ad-Hoc|ARM.ActiveCfg = Ad-Hoc|iPhone
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.Ad-Hoc|x64.ActiveCfg = Ad-Hoc|iPhone
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.Ad-Hoc|x86.ActiveCfg = Ad-Hoc|iPhone
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.AppStore|Any CPU.ActiveCfg = AppStore|iPhone
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.AppStore|ARM.ActiveCfg = AppStore|iPhone
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.AppStore|iPhone.ActiveCfg = AppStore|iPhone
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.AppStore|iPhone.Build.0 = AppStore|iPhone
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.AppStore|x64.ActiveCfg = AppStore|iPhone
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.AppStore|x86.ActiveCfg = AppStore|iPhone
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.Debug|Any CPU.ActiveCfg = Debug|iPhone
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.Debug|ARM.ActiveCfg = Debug|iPhone
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.Debug|iPhone.ActiveCfg = Debug|iPhone
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.Debug|iPhone.Build.0 = Debug|iPhone
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.Debug|x64.ActiveCfg = Debug|iPhone
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.Debug|x86.ActiveCfg = Debug|iPhone
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.FDroid|Any CPU.ActiveCfg = AppStore|iPhone
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.FDroid|Any CPU.Build.0 = AppStore|iPhone
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.FDroid|ARM.ActiveCfg = AppStore|iPhone
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.FDroid|ARM.Build.0 = AppStore|iPhone
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.FDroid|iPhone.ActiveCfg = AppStore|iPhone
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.FDroid|iPhone.Build.0 = AppStore|iPhone
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.FDroid|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.FDroid|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.FDroid|x64.ActiveCfg = AppStore|iPhone
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.FDroid|x64.Build.0 = AppStore|iPhone
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.FDroid|x86.ActiveCfg = AppStore|iPhone
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.FDroid|x86.Build.0 = AppStore|iPhone
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.Release|Any CPU.ActiveCfg = Release|iPhone
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.Release|ARM.ActiveCfg = Release|iPhone
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.Release|iPhone.ActiveCfg = Release|iPhone
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.Release|iPhone.Build.0 = Release|iPhone
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.Release|x64.ActiveCfg = Release|iPhone
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F}.Release|x86.ActiveCfg = Release|iPhone
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -439,10 +513,9 @@ Global
|
||||
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422} = {EC730FD9-F623-4B6C-B503-95CDCFBCF277}
|
||||
{B2538ADA-B605-4D6F-ACD2-62A409680F84} = {EC730FD9-F623-4B6C-B503-95CDCFBCF277}
|
||||
{2E399654-26A2-46F6-B9CA-1B496A3F370A} = {92470CBD-9047-4C3C-8EA3-D972D6622D84}
|
||||
{3A2D5669-ED71-4F2B-BA85-2D36BAA05141} = {EC730FD9-F623-4B6C-B503-95CDCFBCF277}
|
||||
{0BE54BBB-7772-4289-BD51-1FDBB0CC2446} = {EC730FD9-F623-4B6C-B503-95CDCFBCF277}
|
||||
{8A279EE4-4537-4656-9C93-44945E594556} = {EC730FD9-F623-4B6C-B503-95CDCFBCF277}
|
||||
{D5D91152-CB01-4F24-A503-304D3A94408B} = {2E399654-26A2-46F6-B9CA-1B496A3F370A}
|
||||
{C2B7ADCA-5964-43C5-A7C8-D3B6F8023F4F} = {EC730FD9-F623-4B6C-B503-95CDCFBCF277}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {318CB2DF-0118-43A3-AC83-56BADCF71CCD}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
files:
|
||||
- source: /src/App/Resources/AppResources.resx
|
||||
translation: /src/App/Resources/AppResources.%two_letters_code%.resx
|
||||
update_option: update_as_unapproved
|
||||
languages_mapping:
|
||||
two_letters_code:
|
||||
zh-CN: zh-Hans
|
||||
@@ -9,6 +10,7 @@ files:
|
||||
pt-BR: pt-BR
|
||||
- source: /store/apple/en/copy.resx
|
||||
translation: /store/apple/%two_letters_code%/copy.resx
|
||||
update_option: update_as_unapproved
|
||||
languages_mapping:
|
||||
two_letters_code:
|
||||
zh-CN: zh-Hans
|
||||
@@ -17,6 +19,7 @@ files:
|
||||
pt-BR: pt-BR
|
||||
- source: /store/google/en/copy.resx
|
||||
translation: /store/google/%two_letters_code%/copy.resx
|
||||
update_option: update_as_unapproved
|
||||
languages_mapping:
|
||||
two_letters_code:
|
||||
zh-CN: zh-Hans
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
|
||||
<AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest>
|
||||
<AndroidUseLatestPlatformSdk>false</AndroidUseLatestPlatformSdk>
|
||||
<TargetFrameworkVersion>v8.0</TargetFrameworkVersion>
|
||||
<TargetFrameworkVersion>v9.0</TargetFrameworkVersion>
|
||||
<AndroidSupportedAbis>armeabi,armeabi-v7a,x86</AndroidSupportedAbis>
|
||||
<AndroidHttpClientHandlerType>Xamarin.Android.Net.AndroidClientHandler</AndroidHttpClientHandlerType>
|
||||
<AndroidStoreUncompressedFileExtensions />
|
||||
@@ -46,6 +46,7 @@
|
||||
<AotAssemblies>False</AotAssemblies>
|
||||
<EnableLLVM>False</EnableLLVM>
|
||||
<EnableProguard>False</EnableProguard>
|
||||
<AndroidTlsProvider>btls</AndroidTlsProvider>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
@@ -69,6 +70,26 @@
|
||||
<AndroidLinkSkip>PushNotification.Plugin;PushNotification.Plugin.Abstractions;Xamarin.GooglePlayServices.Base;Xamarin.GooglePlayServices.Basement;Xamarin.GooglePlayServices.Measurement;Xamarin.GooglePlayServices.Gcm;BitwardenAndroid;BitwardenApp;SQLite-net;Xamarin.Android.Net</AndroidLinkSkip>
|
||||
<AndroidHttpClientHandlerType>Xamarin.Android.Net.AndroidClientHandler</AndroidHttpClientHandlerType>
|
||||
<AndroidSupportedAbis>armeabi;armeabi-v7a;x86;x86_64;arm64-v8a</AndroidSupportedAbis>
|
||||
<AndroidTlsProvider>btls</AndroidTlsProvider>
|
||||
<AndroidApkSigningAlgorithm>SHA1withRSA</AndroidApkSigningAlgorithm>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'FDroid|AnyCPU'">
|
||||
<OutputPath>bin\FDroid\</OutputPath>
|
||||
<DefineConstants>TRACE;FDROID</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<AndroidUseSharedRuntime>false</AndroidUseSharedRuntime>
|
||||
<EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk>
|
||||
<AndroidLinkMode>Full</AndroidLinkMode>
|
||||
<AndroidLinkSkip>BitwardenAndroid;BitwardenApp;SQLite-net;Xamarin.Android.Net</AndroidLinkSkip>
|
||||
<AndroidTlsProvider>btls</AndroidTlsProvider>
|
||||
<AndroidSupportedAbis>armeabi;armeabi-v7a;x86;x86_64;arm64-v8a</AndroidSupportedAbis>
|
||||
<JavaMaximumHeapSize>1G</JavaMaximumHeapSize>
|
||||
<AndroidApkSigningAlgorithm>SHA1withRSA</AndroidApkSigningAlgorithm>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Mono.Android" />
|
||||
@@ -125,8 +146,6 @@
|
||||
<Compile Include="MainActivity.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Services\LogService.cs" />
|
||||
<Compile Include="Services\MemoryService.cs" />
|
||||
<Compile Include="Services\ReflectionService.cs" />
|
||||
<Compile Include="Services\SqlService.cs" />
|
||||
<Compile Include="SplashActivity.cs" />
|
||||
<Compile Include="PackageReplacedReceiver.cs" />
|
||||
@@ -136,8 +155,9 @@
|
||||
<ItemGroup>
|
||||
<None Include="8bit.keystore.enc" />
|
||||
<GoogleServicesJson Include="google-services.json" />
|
||||
<None Include="update-android.ps1" />
|
||||
<None Include="ci-build-apks.ps1" />
|
||||
<None Include="google-services.json.enc" />
|
||||
<None Include="increment-version.ps1" />
|
||||
<None Include="Resources\AboutResources.txt" />
|
||||
<None Include="Assets\AboutAssets.txt" />
|
||||
<AndroidResource Include="Resources\drawable\slider_thumb.xml">
|
||||
@@ -453,21 +473,6 @@
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable\list_selector.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xxxhdpi\icon.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\icon.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\icon.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-hdpi\icon.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable\icon.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable\notification_sm.png" />
|
||||
</ItemGroup>
|
||||
@@ -853,18 +858,36 @@
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SimpleInjector">
|
||||
<Version>4.0.12</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Firebase.Messaging">
|
||||
<Version>42.1021.1</Version>
|
||||
<Version>60.1142.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.GooglePlayServices.Analytics">
|
||||
<Version>42.1021.1</Version>
|
||||
<Version>60.1142.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="SimpleInjector">
|
||||
<Version>4.4.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Support.Design">
|
||||
<Version>27.0.2.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Support.v4">
|
||||
<Version>27.0.2.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Support.v7.AppCompat">
|
||||
<Version>27.0.2.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Support.v7.CardView">
|
||||
<Version>27.0.2.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Android.Support.v7.MediaRouter">
|
||||
<Version>27.0.2.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.GooglePlayServices.SafetyNet">
|
||||
<Version>60.1142.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="XLabs.IoC.SimpleInjector" Version="2.0.5782" />
|
||||
<PackageReference Include="Portable.BouncyCastle" Version="1.8.1.3" />
|
||||
<PackageReference Include="Plugin.CurrentActivity" Version="1.0.1" />
|
||||
<PackageReference Include="Portable.BouncyCastle" Version="1.8.4" />
|
||||
<PackageReference Include="Plugin.CurrentActivity" Version="2.1.0.4" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable\bottom_nav_bg.xml" />
|
||||
@@ -884,5 +907,122 @@
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xxxhdpi\pencil.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable\refresh_alt.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-hdpi\refresh_alt.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\refresh_alt.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\refresh_alt.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xxxhdpi\refresh_alt.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable\cog_alt.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-hdpi\cog_alt.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\cog_alt.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\cog_alt.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xxxhdpi\cog_alt.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\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\values\ic_launcher_background.xml" />
|
||||
</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\upload2.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-hdpi\upload2.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\upload2.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\upload2.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xxxhdpi\upload2.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\xml\network_security_config.xml" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
|
||||
</Project>
|
||||
@@ -17,6 +17,24 @@ namespace Bit.Android.Autofill
|
||||
{
|
||||
private static int _pendingIntentId = 0;
|
||||
|
||||
// These browser work natively with the autofill framework
|
||||
public static HashSet<string> TrustedBrowsers = new HashSet<string>
|
||||
{
|
||||
"org.mozilla.focus","org.mozilla.klar","com.duckduckgo.mobile.android"
|
||||
};
|
||||
|
||||
// These browsers work using the compatibility shim for the autofill framework
|
||||
public static HashSet<string> CompatBrowsers = new HashSet<string>
|
||||
{
|
||||
"org.mozilla.firefox","org.mozilla.firefox_beta","com.microsoft.emmx","com.android.chrome",
|
||||
"com.chrome.beta","com.android.browser","com.brave.browser","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.sec.android.app.sbrowser","com.sec.android.app.sbrowser.beta","org.codeaurora.swe.browser",
|
||||
"com.amazon.cloud9","mark.via.gp","org.bromite.bromite","org.chromium.chrome","com.kiwibrowser.browser",
|
||||
"com.ecosia.android", "com.opera.mini.native.beta","org.mozilla.fennec_aurora"
|
||||
};
|
||||
|
||||
public static async Task<List<FilledItem>> GetFillItemsAsync(Parser parser, ICipherService service)
|
||||
{
|
||||
var items = new List<FilledItem>();
|
||||
@@ -62,7 +80,7 @@ namespace Bit.Android.Autofill
|
||||
}
|
||||
|
||||
responseBuilder.AddDataset(BuildVaultDataset(context, parser.FieldCollection, parser.Uri, locked));
|
||||
AddSaveInfo(responseBuilder, parser.FieldCollection);
|
||||
AddSaveInfo(parser, responseBuilder, parser.FieldCollection);
|
||||
responseBuilder.SetIgnoredIds(parser.FieldCollection.IgnoreAutofillIds.ToArray());
|
||||
return responseBuilder.Build();
|
||||
}
|
||||
@@ -126,8 +144,16 @@ namespace Bit.Android.Autofill
|
||||
return view;
|
||||
}
|
||||
|
||||
public static void AddSaveInfo(FillResponse.Builder responseBuilder, FieldCollection fields)
|
||||
public static void AddSaveInfo(Parser parser, 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)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var requiredIds = fields.GetRequiredSaveFields();
|
||||
if(fields.SaveType == SaveDataType.Generic || requiredIds.Length == 0)
|
||||
{
|
||||
@@ -140,6 +166,10 @@ namespace Bit.Android.Autofill
|
||||
{
|
||||
saveBuilder.SetOptionalIds(optionalIds);
|
||||
}
|
||||
if(compatBrowser)
|
||||
{
|
||||
saveBuilder.SetFlags(SaveFlags.SaveOnAllViewsInvisible);
|
||||
}
|
||||
responseBuilder.SetSaveInfo(saveBuilder.Build());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ using XLabs.Ioc;
|
||||
|
||||
namespace Bit.Android.Autofill
|
||||
{
|
||||
[Service(Permission = Manifest.Permission.BindAutofillService, Label = "bitwarden")]
|
||||
[Service(Permission = Manifest.Permission.BindAutofillService, Label = "Bitwarden")]
|
||||
[IntentFilter(new string[] { "android.service.autofill.AutofillService" })]
|
||||
[MetaData("android.autofill", Resource = "@xml/autofillservice")]
|
||||
[Register("com.x8bit.bitwarden.Autofill.AutofillService")]
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace Bit.Android.Autofill
|
||||
public Field(ViewNode node)
|
||||
{
|
||||
Id = node.Id;
|
||||
TrackingId = $"{node.Id}_{node.GetHashCode()}";
|
||||
IdEntry = node.IdEntry;
|
||||
AutofillId = node.AutofillId;
|
||||
AutofillType = node.AutofillType;
|
||||
@@ -68,6 +69,7 @@ namespace Bit.Android.Autofill
|
||||
}
|
||||
public string Hint { get; set; }
|
||||
public int Id { get; private set; }
|
||||
public string TrackingId { get; private set; }
|
||||
public string IdEntry { get; set; }
|
||||
public AutofillId AutofillId { get; private set; }
|
||||
public AutofillType AutofillType { get; private set; }
|
||||
|
||||
@@ -11,8 +11,9 @@ namespace Bit.Android.Autofill
|
||||
{
|
||||
private List<Field> _passwordFields = null;
|
||||
private List<Field> _usernameFields = null;
|
||||
private HashSet<string> _ignoreSearchTerms = new HashSet<string> { "search", "find", "recipient", "edit" };
|
||||
private HashSet<string> _passwordTerms = new HashSet<string> { "password", "pswd" };
|
||||
|
||||
public HashSet<int> Ids { get; private set; } = new HashSet<int>();
|
||||
public List<AutofillId> AutofillIds { get; private set; } = new List<AutofillId>();
|
||||
public SaveDataType SaveType
|
||||
{
|
||||
@@ -32,9 +33,8 @@ namespace Bit.Android.Autofill
|
||||
}
|
||||
public HashSet<string> Hints { get; private set; } = new HashSet<string>();
|
||||
public HashSet<string> FocusedHints { get; private set; } = new HashSet<string>();
|
||||
public HashSet<string> FieldTrackingIds { get; private set; } = new HashSet<string>();
|
||||
public List<Field> Fields { get; private set; } = new List<Field>();
|
||||
public IDictionary<int, Field> IdToFieldMap { get; private set; } =
|
||||
new Dictionary<int, Field>();
|
||||
public IDictionary<string, List<Field>> HintToFieldsMap { get; private set; } =
|
||||
new Dictionary<string, List<Field>>();
|
||||
public List<AutofillId> IgnoreAutofillIds { get; private set; } = new List<AutofillId>();
|
||||
@@ -58,21 +58,10 @@ namespace Bit.Android.Autofill
|
||||
}
|
||||
else
|
||||
{
|
||||
_passwordFields = Fields
|
||||
.Where(f =>
|
||||
(!f.IdEntry?.ToLowerInvariant().Contains("search") ?? true) &&
|
||||
(!f.Hint?.ToLowerInvariant().Contains("search") ?? true) &&
|
||||
(
|
||||
f.InputType.HasFlag(InputTypes.TextVariationPassword) ||
|
||||
f.InputType.HasFlag(InputTypes.TextVariationVisiblePassword) ||
|
||||
f.InputType.HasFlag(InputTypes.TextVariationWebPassword)
|
||||
)
|
||||
).ToList();
|
||||
_passwordFields = Fields.Where(f => FieldIsPassword(f)).ToList();
|
||||
if(!_passwordFields.Any())
|
||||
{
|
||||
_passwordFields = Fields.Where(f =>
|
||||
(f.IdEntry?.ToLowerInvariant().Contains("password") ?? false)
|
||||
|| (f.Hint?.ToLowerInvariant().Contains("password") ?? false)).ToList();
|
||||
_passwordFields = Fields.Where(f => FieldHasPasswordTerms(f)).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,7 +94,8 @@ namespace Bit.Android.Autofill
|
||||
{
|
||||
foreach(var passwordField in PasswordFields)
|
||||
{
|
||||
var usernameField = Fields.TakeWhile(f => f.AutofillId != passwordField.AutofillId).LastOrDefault();
|
||||
var usernameField = Fields.TakeWhile(f => f.AutofillId != passwordField.AutofillId)
|
||||
.LastOrDefault();
|
||||
if(usernameField != null)
|
||||
{
|
||||
_usernameFields.Add(usernameField);
|
||||
@@ -131,19 +121,14 @@ namespace Bit.Android.Autofill
|
||||
|
||||
public void Add(Field field)
|
||||
{
|
||||
if(Ids.Contains(field.Id))
|
||||
if(field == null || FieldTrackingIds.Contains(field.TrackingId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_passwordFields = _usernameFields = null;
|
||||
|
||||
if(field.Id > -1)
|
||||
{
|
||||
Ids.Add(field.Id);
|
||||
IdToFieldMap.Add(field.Id, field);
|
||||
}
|
||||
|
||||
FieldTrackingIds.Add(field.TrackingId);
|
||||
Fields.Add(field);
|
||||
AutofillIds.Add(field.AutofillId);
|
||||
|
||||
@@ -312,5 +297,45 @@ namespace Bit.Android.Autofill
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private bool FieldIsPassword(Field f)
|
||||
{
|
||||
var inputTypePassword = f.InputType.HasFlag(InputTypes.TextVariationPassword) ||
|
||||
f.InputType.HasFlag(InputTypes.TextVariationVisiblePassword) ||
|
||||
f.InputType.HasFlag(InputTypes.TextVariationWebPassword);
|
||||
|
||||
if(!inputTypePassword && f.HtmlInfo != null && f.HtmlInfo.Tag == "input" &&
|
||||
(f.HtmlInfo.Attributes?.Any() ?? false))
|
||||
{
|
||||
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")
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return inputTypePassword && !ValueContainsAnyTerms(f.IdEntry, _ignoreSearchTerms) &&
|
||||
!ValueContainsAnyTerms(f.Hint, _ignoreSearchTerms);
|
||||
}
|
||||
|
||||
private bool FieldHasPasswordTerms(Field f)
|
||||
{
|
||||
return ValueContainsAnyTerms(f.IdEntry, _passwordTerms) || ValueContainsAnyTerms(f.Hint, _passwordTerms);
|
||||
}
|
||||
|
||||
private bool ValueContainsAnyTerms(string value, HashSet<string> terms)
|
||||
{
|
||||
if(string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var lowerValue = value.ToLowerInvariant();
|
||||
return terms.Any(t => lowerValue.Contains(t));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,14 +7,10 @@ namespace Bit.Android.Autofill
|
||||
{
|
||||
public class Parser
|
||||
{
|
||||
public static HashSet<string> TrustedBrowsers = new HashSet<string>
|
||||
|
||||
public static HashSet<string> ExcludedPackageIds = new HashSet<string>
|
||||
{
|
||||
"org.mozilla.focus","org.mozilla.firefox","org.mozilla.firefox_beta","com.microsoft.emmx",
|
||||
"com.android.chrome","com.chrome.beta","com.android.browser","com.brave.browser","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.sec.android.app.sbrowser","com.sec.android.app.sbrowser.beta","org.codeaurora.swe.browser",
|
||||
"com.amazon.cloud9"
|
||||
"android"
|
||||
};
|
||||
|
||||
private readonly AssistStructure _structure;
|
||||
@@ -87,32 +83,25 @@ namespace Bit.Android.Autofill
|
||||
var node = _structure.GetWindowNodeAt(i);
|
||||
ParseNode(node.RootViewNode);
|
||||
}
|
||||
|
||||
if(!AutofillHelpers.TrustedBrowsers.Contains(PackageName) &&
|
||||
!AutofillHelpers.CompatBrowsers.Contains(PackageName))
|
||||
{
|
||||
WebDomain = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void ParseNode(ViewNode node)
|
||||
{
|
||||
SetPackageAndDomain(node);
|
||||
var hints = node.GetAutofillHints();
|
||||
var isEditText = node.ClassName == "android.widget.EditText" || node?.HtmlInfo?.Tag == "input";
|
||||
if(isEditText || (hints?.Length ?? 0) > 0)
|
||||
{
|
||||
if(PackageName == null)
|
||||
{
|
||||
PackageName = node.IdPackage;
|
||||
}
|
||||
if(WebDomain == null && TrustedBrowsers.Contains(node.IdPackage))
|
||||
{
|
||||
WebDomain = node.WebDomain;
|
||||
}
|
||||
|
||||
FieldCollection.Add(new Field(node));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(WebDomain == null && TrustedBrowsers.Contains(node.IdPackage))
|
||||
{
|
||||
WebDomain = node.WebDomain;
|
||||
}
|
||||
|
||||
FieldCollection.IgnoreAutofillIds.Add(node.AutofillId);
|
||||
}
|
||||
|
||||
@@ -121,5 +110,18 @@ namespace Bit.Android.Autofill
|
||||
ParseNode(node.GetChildAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
private void SetPackageAndDomain(ViewNode node)
|
||||
{
|
||||
if(string.IsNullOrWhiteSpace(PackageName) && !string.IsNullOrWhiteSpace(node.IdPackage) &&
|
||||
!ExcludedPackageIds.Contains(node.IdPackage))
|
||||
{
|
||||
PackageName = node.IdPackage;
|
||||
}
|
||||
if(string.IsNullOrWhiteSpace(WebDomain) && !string.IsNullOrWhiteSpace(node.WebDomain))
|
||||
{
|
||||
WebDomain = node.WebDomain;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,15 +3,14 @@ using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using System;
|
||||
|
||||
namespace Bit.Android
|
||||
{
|
||||
[Activity(Theme = "@style/BitwardenTheme.Splash",
|
||||
Label = "bitwarden",
|
||||
Icon = "@drawable/icon",
|
||||
WindowSoftInputMode = SoftInput.StateHidden)]
|
||||
[Activity(Theme = "@style/BitwardenTheme.Splash", WindowSoftInputMode = SoftInput.StateHidden)]
|
||||
public class AutofillActivity : Activity
|
||||
{
|
||||
private DateTime? _lastLaunch = null;
|
||||
private string _lastQueriedUri;
|
||||
|
||||
public static AutofillCredentials LastCredentials { get; set; }
|
||||
@@ -93,6 +92,13 @@ namespace Bit.Android
|
||||
return;
|
||||
}
|
||||
|
||||
var now = DateTime.UtcNow;
|
||||
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))
|
||||
{
|
||||
|
||||
@@ -12,22 +12,24 @@ using Bit.App.Resources;
|
||||
|
||||
namespace Bit.Android
|
||||
{
|
||||
[Service(Permission = global::Android.Manifest.Permission.BindAccessibilityService, Label = "bitwarden")]
|
||||
[Service(Permission = global::Android.Manifest.Permission.BindAccessibilityService, Label = "Bitwarden")]
|
||||
[IntentFilter(new string[] { "android.accessibilityservice.AccessibilityService" })]
|
||||
[MetaData("android.accessibilityservice", Resource = "@xml/accessibilityservice")]
|
||||
public class AutofillService : AccessibilityService
|
||||
{
|
||||
private NotificationChannel _notificationChannel;
|
||||
|
||||
private const string BitwardenTag = "bw_access";
|
||||
private const int AutoFillNotificationId = 34573;
|
||||
private const string SystemUiPackage = "com.android.systemui";
|
||||
private const string BitwardenPackage = "com.x8bit.bitwarden";
|
||||
private const string BitwardenWebsite = "bitwarden.com";
|
||||
private const string BitwardenWebsite = "vault.bitwarden.com";
|
||||
|
||||
private 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"),
|
||||
new Browser("com.android.browser", "url"),
|
||||
new Browser("com.brave.browser", "url_bar"),
|
||||
new Browser("com.opera.browser", "url_field"),
|
||||
@@ -42,10 +44,12 @@ namespace Bit.Android
|
||||
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",
|
||||
(s) => s.Split(' ').FirstOrDefault()),
|
||||
(s) => s.Split(new char[]{' ', '<27>'}).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.ghostery.android.ghostery", "search_field"),
|
||||
new Browser("org.adblockplus.browser", "url_bar_title"),
|
||||
new Browser("com.htc.sense.browser", "title"),
|
||||
@@ -59,12 +63,40 @@ namespace Bit.Android
|
||||
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.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"),
|
||||
}.ToDictionary(n => n.PackageName);
|
||||
|
||||
// Known packages to skip
|
||||
private static HashSet<string> FilteredPackageNames => new HashSet<string>
|
||||
{
|
||||
SystemUiPackage,
|
||||
"com.google.android.googlequicksearchbox",
|
||||
"com.google.android.apps.nexuslauncher",
|
||||
"com.google.android.launcher",
|
||||
"com.computer.desktop.ui.launcher",
|
||||
"com.launcher.notelauncher",
|
||||
"com.anddoes.launcher",
|
||||
"com.actionlauncher.playstore",
|
||||
"ch.deletescape.lawnchair.plah",
|
||||
"com.microsoft.launcher",
|
||||
"com.teslacoilsw.launcher",
|
||||
"com.teslacoilsw.launcher.prime",
|
||||
"is.shortcut",
|
||||
"me.craftsapp.nlauncher",
|
||||
"com.ss.squarehome2"
|
||||
};
|
||||
|
||||
private readonly IAppSettingsService _appSettings;
|
||||
private long _lastNotificationTime = 0;
|
||||
private string _lastNotificationUri = null;
|
||||
private HashSet<string> _launcherPackageNames = null;
|
||||
private DateTime? _lastLauncherSetBuilt = null;
|
||||
private TimeSpan _rebuildLauncherSpan = TimeSpan.FromHours(1);
|
||||
|
||||
public AutofillService()
|
||||
{
|
||||
@@ -73,29 +105,31 @@ namespace Bit.Android
|
||||
|
||||
public override void OnAccessibilityEvent(AccessibilityEvent e)
|
||||
{
|
||||
var powerManager = (PowerManager)GetSystemService(PowerService);
|
||||
if(Build.VERSION.SdkInt > BuildVersionCodes.KitkatWatch && !powerManager.IsInteractive)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if(Build.VERSION.SdkInt < BuildVersionCodes.Lollipop && !powerManager.IsScreenOn)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var powerManager = (PowerManager)GetSystemService(PowerService);
|
||||
if(Build.VERSION.SdkInt > BuildVersionCodes.KitkatWatch && !powerManager.IsInteractive)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if(Build.VERSION.SdkInt < BuildVersionCodes.Lollipop && !powerManager.IsScreenOn)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(SkipPackage(e?.PackageName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var root = RootInActiveWindow;
|
||||
if(e == null || root == null || string.IsNullOrWhiteSpace(e.PackageName) ||
|
||||
e.PackageName == SystemUiPackage || e.PackageName.Contains("launcher") ||
|
||||
root.PackageName != e.PackageName)
|
||||
if(root == null || root.PackageName != e.PackageName)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//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 });
|
||||
//testNodes.Dispose();
|
||||
|
||||
var notificationManager = (NotificationManager)GetSystemService(NotificationService);
|
||||
var cancelNotification = true;
|
||||
@@ -103,7 +137,7 @@ namespace Bit.Android
|
||||
switch(e.EventType)
|
||||
{
|
||||
case EventTypes.ViewFocused:
|
||||
if(!e.Source.Password || !_appSettings.AutofillPasswordField)
|
||||
if(e.Source == null || !e.Source.Password || !_appSettings.AutofillPasswordField)
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -410,16 +444,17 @@ namespace Bit.Android
|
||||
}
|
||||
|
||||
private NodeList GetWindowNodes(AccessibilityNodeInfo n, AccessibilityEvent e,
|
||||
Func<AccessibilityNodeInfo, bool> condition, bool disposeIfUnused, NodeList nodes = null)
|
||||
Func<AccessibilityNodeInfo, bool> condition, bool disposeIfUnused, NodeList nodes = null,
|
||||
int recursionDepth = 0)
|
||||
{
|
||||
if(nodes == null)
|
||||
{
|
||||
nodes = new NodeList();
|
||||
}
|
||||
|
||||
if(n != null)
|
||||
var dispose = disposeIfUnused;
|
||||
if(n != null && recursionDepth < 50)
|
||||
{
|
||||
var dispose = disposeIfUnused;
|
||||
if(n.WindowId == e.WindowId && !(n.ViewIdResourceName?.StartsWith(SystemUiPackage) ?? false) && condition(n))
|
||||
{
|
||||
dispose = false;
|
||||
@@ -428,18 +463,54 @@ namespace Bit.Android
|
||||
|
||||
for(var i = 0; i < n.ChildCount; i++)
|
||||
{
|
||||
GetWindowNodes(n.GetChild(i), e, condition, true, nodes);
|
||||
}
|
||||
|
||||
if(dispose)
|
||||
{
|
||||
n.Dispose();
|
||||
var childNode = n.GetChild(i);
|
||||
if(i > 100)
|
||||
{
|
||||
global::Android.Util.Log.Info(BitwardenTag, "Too many child iterations.");
|
||||
break;
|
||||
}
|
||||
else if(childNode.GetHashCode() == n.GetHashCode())
|
||||
{
|
||||
global::Android.Util.Log.Info(BitwardenTag,
|
||||
"Child node is the same as parent for some reason.");
|
||||
}
|
||||
else
|
||||
{
|
||||
GetWindowNodes(childNode, e, condition, true, nodes, recursionDepth++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(dispose)
|
||||
{
|
||||
n?.Dispose();
|
||||
}
|
||||
|
||||
return nodes;
|
||||
}
|
||||
|
||||
private bool SkipPackage(string eventPackageName)
|
||||
{
|
||||
if(string.IsNullOrWhiteSpace(eventPackageName) || FilteredPackageNames.Contains(eventPackageName)
|
||||
|| eventPackageName.Contains("launcher"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if(_launcherPackageNames == null || _lastLauncherSetBuilt == null ||
|
||||
(DateTime.Now - _lastLauncherSetBuilt.Value) > _rebuildLauncherSpan)
|
||||
{
|
||||
// refresh launcher list every now and then
|
||||
_lastLauncherSetBuilt = DateTime.Now;
|
||||
var intent = new Intent(Intent.ActionMain);
|
||||
intent.AddCategory(Intent.CategoryHome);
|
||||
var resolveInfo = PackageManager.QueryIntentActivities(intent, 0);
|
||||
_launcherPackageNames = resolveInfo.Select(ri => ri.ActivityInfo.PackageName).ToHashSet();
|
||||
}
|
||||
|
||||
return _launcherPackageNames.Contains(eventPackageName);
|
||||
}
|
||||
|
||||
public class Browser
|
||||
{
|
||||
public Browser(string packageName, string uriViewId)
|
||||
|
||||
@@ -112,7 +112,7 @@ namespace Bit.Android.Controls
|
||||
|
||||
private void Control_EditorAction(object sender, TextView.EditorActionEventArgs e)
|
||||
{
|
||||
if(_view.ReturnType != ReturnType.Next)
|
||||
if(_view.TargetReturnType != Bit.App.Enums.ReturnType.Next)
|
||||
{
|
||||
_view.Unfocus();
|
||||
}
|
||||
@@ -165,23 +165,23 @@ namespace Bit.Android.Controls
|
||||
|
||||
private void SetReturnType(ExtendedEntry view)
|
||||
{
|
||||
if(view.ReturnType.HasValue)
|
||||
if(view.TargetReturnType.HasValue)
|
||||
{
|
||||
switch(view.ReturnType.Value)
|
||||
switch(view.TargetReturnType.Value)
|
||||
{
|
||||
case ReturnType.Go:
|
||||
case App.Enums.ReturnType.Go:
|
||||
Control.ImeOptions = ImeAction.Go;
|
||||
Control.SetImeActionLabel("Go", ImeAction.Go);
|
||||
break;
|
||||
case ReturnType.Next:
|
||||
case App.Enums.ReturnType.Next:
|
||||
Control.ImeOptions = ImeAction.Next;
|
||||
Control.SetImeActionLabel("Next", ImeAction.Next);
|
||||
break;
|
||||
case ReturnType.Search:
|
||||
case App.Enums.ReturnType.Search:
|
||||
Control.ImeOptions = ImeAction.Search;
|
||||
Control.SetImeActionLabel("Search", ImeAction.Search);
|
||||
break;
|
||||
case ReturnType.Send:
|
||||
case App.Enums.ReturnType.Send:
|
||||
Control.ImeOptions = ImeAction.Send;
|
||||
Control.SetImeActionLabel("Send", ImeAction.Send);
|
||||
break;
|
||||
@@ -206,7 +206,7 @@ namespace Bit.Android.Controls
|
||||
|
||||
private void SetMaxLength(ExtendedEntry view)
|
||||
{
|
||||
Control.SetFilters(new IInputFilter[] { new InputFilterLengthFilter(view.MaxLength) });
|
||||
Control.SetFilters(new IInputFilter[] { new InputFilterLengthFilter(view.TargetMaxLength) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,13 +97,18 @@ namespace Bit.Android.Controls
|
||||
|
||||
bool isHeader, nextIsHeader;
|
||||
var cell = GetCellForPosition(position, out isHeader, out nextIsHeader);
|
||||
var cellView = CellFactory.GetCell(cell, convertView, parent, Context, _view);
|
||||
if(layout.ChildCount > 0)
|
||||
{
|
||||
layout.RemoveViewAt(0);
|
||||
var cellView = CellFactory.GetCell(cell, convertView, parent, Context, _view);
|
||||
layout.AddView(cellView, 0);
|
||||
}
|
||||
|
||||
if(cellView.HasFocus)
|
||||
{
|
||||
cellView.ClearFocus();
|
||||
}
|
||||
|
||||
if(isHeader)
|
||||
{
|
||||
var textCell = layout.GetChildAt(0) as BaseCellView;
|
||||
|
||||
@@ -7,7 +7,6 @@ using Android.Webkit;
|
||||
using AWebkit = Android.Webkit;
|
||||
using Java.Interop;
|
||||
using Android.Content;
|
||||
using Plugin.CurrentActivity;
|
||||
|
||||
[assembly: ExportRenderer(typeof(HybridWebView), typeof(HybridWebViewRenderer))]
|
||||
namespace Bit.Android.Controls
|
||||
@@ -16,9 +15,13 @@ namespace Bit.Android.Controls
|
||||
{
|
||||
private const string JSFunction = "function invokeCSharpAction(data){jsBridge.invokeAction(data);}";
|
||||
|
||||
private readonly Context _context;
|
||||
|
||||
public HybridWebViewRenderer(Context context)
|
||||
: base(context)
|
||||
{ }
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
protected override void OnElementChanged(ElementChangedEventArgs<HybridWebView> e)
|
||||
{
|
||||
@@ -26,8 +29,9 @@ namespace Bit.Android.Controls
|
||||
|
||||
if(Control == null)
|
||||
{
|
||||
var webView = new AWebkit.WebView(CrossCurrentActivity.Current.Activity);
|
||||
var webView = new AWebkit.WebView(_context);
|
||||
webView.Settings.JavaScriptEnabled = true;
|
||||
webView.SetWebViewClient(new JSWebViewClient(string.Format("javascript: {0}", JSFunction)));
|
||||
SetNativeControl(webView);
|
||||
}
|
||||
|
||||
@@ -42,15 +46,6 @@ namespace Bit.Android.Controls
|
||||
{
|
||||
Control.AddJavascriptInterface(new JSBridge(this), "jsBridge");
|
||||
Control.LoadUrl(Element.Uri);
|
||||
InjectJS(JSFunction);
|
||||
}
|
||||
}
|
||||
|
||||
private void InjectJS(string script)
|
||||
{
|
||||
if(Control != null)
|
||||
{
|
||||
Control.LoadUrl(string.Format("javascript: {0}", script));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,5 +69,21 @@ namespace Bit.Android.Controls
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class JSWebViewClient : WebViewClient
|
||||
{
|
||||
private readonly string _javascript;
|
||||
|
||||
public JSWebViewClient(string javascript)
|
||||
{
|
||||
_javascript = javascript;
|
||||
|
||||
}
|
||||
public override void OnPageFinished(AWebkit.WebView view, string url)
|
||||
{
|
||||
base.OnPageFinished(view, url);
|
||||
view.EvaluateJavascript(_javascript, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#if !FDROID
|
||||
using System;
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
@@ -21,3 +22,4 @@ namespace Bit.Android
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#if !FDROID
|
||||
using System;
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
@@ -40,3 +41,4 @@ namespace Bit.Android
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#if !FDROID
|
||||
using HockeyApp.Android;
|
||||
using Bit.App.Abstractions;
|
||||
using Newtonsoft.Json;
|
||||
@@ -51,4 +52,5 @@ namespace Bit.Android
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -21,15 +21,14 @@ using Bit.App.Enums;
|
||||
|
||||
namespace Bit.Android
|
||||
{
|
||||
[Activity(Label = "bitwarden",
|
||||
Icon = "@drawable/icon",
|
||||
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation,
|
||||
Exported = false)]
|
||||
[Activity(ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation, Exported = false)]
|
||||
public class MainActivity : FormsAppCompatActivity
|
||||
{
|
||||
private const string HockeyAppId = "d3834185b4a643479047b86c65293d42";
|
||||
private Java.Util.Regex.Pattern _otpPattern = Java.Util.Regex.Pattern.Compile("^.*?([cbdefghijklnrtuv]{32,64})$");
|
||||
private IDeviceActionService _deviceActionService;
|
||||
private IDeviceInfoService _deviceInfoService;
|
||||
private IAppSettingsService _appSettingsService;
|
||||
private ISettings _settings;
|
||||
private AppOptions _appOptions;
|
||||
|
||||
@@ -61,8 +60,10 @@ namespace Bit.Android
|
||||
var appIdService = Resolver.Resolve<IAppIdService>();
|
||||
var authService = Resolver.Resolve<IAuthService>();
|
||||
|
||||
#if !FDROID
|
||||
HockeyApp.Android.CrashManager.Register(this, HockeyAppId,
|
||||
new HockeyAppCrashManagerListener(appIdService, authService));
|
||||
#endif
|
||||
|
||||
Forms.Init(this, bundle);
|
||||
|
||||
@@ -70,6 +71,8 @@ namespace Bit.Android
|
||||
.SetValue(null, Color.FromHex("d2d6de"));
|
||||
|
||||
_deviceActionService = Resolver.Resolve<IDeviceActionService>();
|
||||
_deviceInfoService = Resolver.Resolve<IDeviceInfoService>();
|
||||
_appSettingsService = Resolver.Resolve<IAppSettingsService>();
|
||||
_settings = Resolver.Resolve<ISettings>();
|
||||
_appOptions = GetOptions();
|
||||
LoadApplication(new App.App(
|
||||
@@ -82,7 +85,7 @@ namespace Bit.Android
|
||||
Resolver.Resolve<ILockService>(),
|
||||
Resolver.Resolve<ILocalizeService>(),
|
||||
Resolver.Resolve<IAppInfoService>(),
|
||||
Resolver.Resolve<IAppSettingsService>(),
|
||||
_appSettingsService,
|
||||
_deviceActionService));
|
||||
|
||||
if(_appOptions?.Uri == null)
|
||||
@@ -135,9 +138,21 @@ namespace Bit.Android
|
||||
// ref https://bugzilla.xamarin.com/show_bug.cgi?id=36907
|
||||
Task.Delay(10).Wait();
|
||||
|
||||
if(Utilities.NfcEnabled())
|
||||
if(_deviceInfoService.NfcEnabled)
|
||||
{
|
||||
MessagingCenter.Send(Xamarin.Forms.Application.Current, "ResumeYubiKey");
|
||||
try
|
||||
{
|
||||
MessagingCenter.Send(Xamarin.Forms.Application.Current, "ResumeYubiKey");
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(e);
|
||||
}
|
||||
}
|
||||
|
||||
if(_appSettingsService.Locked)
|
||||
{
|
||||
MessagingCenter.Send(Xamarin.Forms.Application.Current, "Resumed", false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,7 +215,7 @@ namespace Bit.Android
|
||||
|
||||
private void ListenYubiKey(bool listen)
|
||||
{
|
||||
if(!Utilities.NfcEnabled())
|
||||
if(!_deviceInfoService.NfcEnabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -218,8 +233,12 @@ namespace Bit.Android
|
||||
ndef.AddDataScheme("https");
|
||||
var filters = new IntentFilter[] { ndef };
|
||||
|
||||
// register for foreground dispatch so we'll receive tags according to our intent filters
|
||||
adapter.EnableForegroundDispatch(this, pendingIntent, filters, null);
|
||||
try
|
||||
{
|
||||
// register for foreground dispatch so we'll receive tags according to our intent filters
|
||||
adapter.EnableForegroundDispatch(this, pendingIntent, filters, null);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -13,10 +13,9 @@ using Plugin.Fingerprint;
|
||||
using Plugin.Settings;
|
||||
using XLabs.Ioc;
|
||||
using System.Threading.Tasks;
|
||||
using Plugin.Settings.Abstractions;
|
||||
using FFImageLoading.Forms.Droid;
|
||||
using XLabs.Ioc.SimpleInjectorContainer;
|
||||
using SimpleInjector;
|
||||
using Android.Gms.Security;
|
||||
|
||||
namespace Bit.Android
|
||||
{
|
||||
@@ -25,13 +24,8 @@ namespace Bit.Android
|
||||
#else
|
||||
[Application(Debuggable = false)]
|
||||
#endif
|
||||
public class MainApplication : Application, Application.IActivityLifecycleCallbacks
|
||||
public class MainApplication : Application, ProviderInstaller.IProviderInstallListener
|
||||
{
|
||||
private const string FirstLaunchKey = "firstLaunch";
|
||||
private const string LastVersionCodeKey = "lastVersionCode";
|
||||
|
||||
public static Context AppContext;
|
||||
|
||||
public MainApplication(IntPtr handle, JniHandleOwnership transer)
|
||||
: base(handle, transer)
|
||||
{
|
||||
@@ -41,6 +35,11 @@ namespace Bit.Android
|
||||
{
|
||||
SetIoc(this);
|
||||
}
|
||||
|
||||
if(Build.VERSION.SdkInt <= BuildVersionCodes.Kitkat)
|
||||
{
|
||||
ProviderInstaller.InstallIfNeededAsync(ApplicationContext, this);
|
||||
}
|
||||
}
|
||||
|
||||
private void AndroidEnvironment_UnhandledExceptionRaiser(object sender, RaiseThrowableEventArgs e)
|
||||
@@ -57,52 +56,13 @@ namespace Bit.Android
|
||||
// workaround for app compat bug
|
||||
// ref https://forums.xamarin.com/discussion/62414/app-resuming-results-in-crash-with-formsappcompatactivity
|
||||
Task.Delay(10).Wait();
|
||||
|
||||
RegisterActivityLifecycleCallbacks(this);
|
||||
AppContext = ApplicationContext;
|
||||
}
|
||||
|
||||
public override void OnTerminate()
|
||||
{
|
||||
base.OnTerminate();
|
||||
UnregisterActivityLifecycleCallbacks(this);
|
||||
}
|
||||
|
||||
public void OnActivityCreated(Activity activity, Bundle savedInstanceState)
|
||||
{
|
||||
CrossCurrentActivity.Current.Activity = activity;
|
||||
}
|
||||
|
||||
public void OnActivityDestroyed(Activity activity)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnActivityPaused(Activity activity)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnActivityResumed(Activity activity)
|
||||
{
|
||||
CrossCurrentActivity.Current.Activity = activity;
|
||||
}
|
||||
|
||||
public void OnActivitySaveInstanceState(Activity activity, Bundle outState)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnActivityStarted(Activity activity)
|
||||
{
|
||||
CrossCurrentActivity.Current.Activity = activity;
|
||||
}
|
||||
|
||||
public void OnActivityStopped(Activity activity)
|
||||
{
|
||||
CrossCurrentActivity.Current.Init(this);
|
||||
}
|
||||
|
||||
public static void SetIoc(Application application)
|
||||
{
|
||||
Refractored.FabControl.Droid.FloatingActionButtonViewRenderer.Init();
|
||||
CachedImageRenderer.Init();
|
||||
FFImageLoading.Forms.Platform.CachedImageRenderer.Init(true);
|
||||
ZXing.Net.Mobile.Forms.Android.Platform.Init();
|
||||
CrossFingerprint.SetCurrentActivityResolver(() => CrossCurrentActivity.Current.Activity);
|
||||
|
||||
@@ -110,8 +70,8 @@ namespace Bit.Android
|
||||
var container = new Container();
|
||||
|
||||
// Android Stuff
|
||||
container.RegisterSingleton(application.ApplicationContext);
|
||||
container.RegisterSingleton<Application>(application);
|
||||
container.RegisterInstance(application.ApplicationContext);
|
||||
container.RegisterInstance<Application>(application);
|
||||
|
||||
// Services
|
||||
container.RegisterSingleton<IDatabaseService, DatabaseService>();
|
||||
@@ -127,17 +87,19 @@ namespace Bit.Android
|
||||
container.RegisterSingleton<IDeviceActionService, DeviceActionService>();
|
||||
container.RegisterSingleton<IAppIdService, AppIdService>();
|
||||
container.RegisterSingleton<IPasswordGenerationService, PasswordGenerationService>();
|
||||
container.RegisterSingleton<IReflectionService, ReflectionService>();
|
||||
container.RegisterSingleton<ILockService, LockService>();
|
||||
container.RegisterSingleton<IAppInfoService, AppInfoService>();
|
||||
#if FDROID
|
||||
container.RegisterSingleton<IGoogleAnalyticsService, NoopGoogleAnalyticsService>();
|
||||
#else
|
||||
container.RegisterSingleton<IGoogleAnalyticsService, GoogleAnalyticsService>();
|
||||
#endif
|
||||
container.RegisterSingleton<IDeviceInfoService, DeviceInfoService>();
|
||||
container.RegisterSingleton<ILocalizeService, LocalizeService>();
|
||||
container.RegisterSingleton<ILogService, LogService>();
|
||||
container.RegisterSingleton<IHttpService, HttpService>();
|
||||
container.RegisterSingleton<ITokenService, TokenService>();
|
||||
container.RegisterSingleton<ISettingsService, SettingsService>();
|
||||
container.RegisterSingleton<IMemoryService, MemoryService>();
|
||||
container.RegisterSingleton<IAppSettingsService, AppSettingsService>();
|
||||
|
||||
// Repositories
|
||||
@@ -157,16 +119,29 @@ namespace Bit.Android
|
||||
container.RegisterSingleton<ICipherCollectionRepository, CipherCollectionRepository>();
|
||||
|
||||
// Other
|
||||
container.RegisterSingleton(CrossSettings.Current);
|
||||
container.RegisterSingleton(CrossConnectivity.Current);
|
||||
container.RegisterSingleton(CrossFingerprint.Current);
|
||||
container.RegisterInstance(CrossSettings.Current);
|
||||
container.RegisterInstance(CrossConnectivity.Current);
|
||||
container.RegisterInstance(CrossFingerprint.Current);
|
||||
|
||||
// Push
|
||||
#if FDROID
|
||||
container.RegisterSingleton<IPushNotificationListener, NoopPushNotificationListener>();
|
||||
container.RegisterSingleton<IPushNotificationService, NoopPushNotificationService>();
|
||||
#else
|
||||
container.RegisterSingleton<IPushNotificationListener, PushNotificationListener>();
|
||||
container.RegisterSingleton<IPushNotificationService, AndroidPushNotificationService>();
|
||||
#endif
|
||||
|
||||
container.Verify();
|
||||
Resolver.SetResolver(new SimpleInjectorResolver(container));
|
||||
}
|
||||
|
||||
public void OnProviderInstallFailed(int errorCode, Intent recoveryIntent)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnProviderInstalled()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.x8bit.bitwarden" android:versionName="1.14.0" android:installLocation="auto" android:versionCode="502" xmlns:tools="http://schemas.android.com/tools">
|
||||
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="23" />
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.x8bit.bitwarden" android:versionName="1.21.0" android:installLocation="auto" android:versionCode="502" xmlns:tools="http://schemas.android.com/tools">
|
||||
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="26" />
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.NFC" />
|
||||
@@ -12,7 +12,9 @@
|
||||
<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/BitwardenTheme" android:allowBackup="false">
|
||||
<application android:label="Bitwarden" android:theme="@style/BitwardenTheme" android:allowBackup="false"
|
||||
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"
|
||||
@@ -30,10 +32,11 @@
|
||||
<intent-filter>
|
||||
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
|
||||
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
|
||||
<category android:name="${applicationId}" />
|
||||
<category android:name="com.x8bit.bitwarden" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<activity android:name="net.hockeyapp.android.UpdateActivity" android:exported="false" android:icon="@drawable/icon" />
|
||||
<activity android:name="net.hockeyapp.android.UpdateActivity" android:exported="false" />
|
||||
<meta-data android:name="android.max_aspect" android:value="2.1" />
|
||||
</application>
|
||||
</manifest>
|
||||
|
||||
@@ -10,7 +10,7 @@ using Android.App;
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("8bit Solutions LLC")]
|
||||
[assembly: AssemblyProduct("bitwarden")]
|
||||
[assembly: AssemblyProduct("Bitwarden")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2016")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
8376
src/Android/Resources/Resource.Designer.cs
generated
BIN
src/Android/Resources/drawable-hdpi/cog_alt.png
Normal file
|
After Width: | Height: | Size: 738 B |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.3 KiB |
BIN
src/Android/Resources/drawable-hdpi/refresh_alt.png
Normal file
|
After Width: | Height: | Size: 804 B |
BIN
src/Android/Resources/drawable-hdpi/upload2.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/Android/Resources/drawable-xhdpi/cog_alt.png
Normal file
|
After Width: | Height: | Size: 1005 B |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 1.7 KiB |
BIN
src/Android/Resources/drawable-xhdpi/refresh_alt.png
Normal file
|
After Width: | Height: | Size: 1017 B |
BIN
src/Android/Resources/drawable-xhdpi/upload2.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
src/Android/Resources/drawable-xxhdpi/cog_alt.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 2.7 KiB |
BIN
src/Android/Resources/drawable-xxhdpi/refresh_alt.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
src/Android/Resources/drawable-xxhdpi/upload2.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
src/Android/Resources/drawable-xxxhdpi/cog_alt.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 3.6 KiB |
BIN
src/Android/Resources/drawable-xxxhdpi/refresh_alt.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
src/Android/Resources/drawable-xxxhdpi/upload2.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
src/Android/Resources/drawable/cog_alt.png
Normal file
|
After Width: | Height: | Size: 590 B |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 941 B |
BIN
src/Android/Resources/drawable/refresh_alt.png
Normal file
|
After Width: | Height: | Size: 583 B |
BIN
src/Android/Resources/drawable/upload2.png
Normal file
|
After Width: | Height: | Size: 689 B |
@@ -7,9 +7,5 @@
|
||||
android:background="?attr/colorPrimary"
|
||||
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
|
||||
app:tabIndicatorColor="@android:color/white"
|
||||
app:tabMaxWidth="0dp"
|
||||
app:tabGravity="fill"
|
||||
app:tabTextAppearance="@android:style/TextAppearance.Widget.TabWidget"
|
||||
app:tabTextColor="@color/tabtext"
|
||||
app:tabSelectedTextColor="@android:color/white"
|
||||
app:tabMode="fixed" />
|
||||
@@ -1,11 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:minHeight="?attr/actionBarSize"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/colorPrimary"
|
||||
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
|
||||
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
|
||||
app:layout_scrollFlags="scroll|enterAlways" />
|
||||
android:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
|
||||
5
src/Android/Resources/mipmap-anydpi-v26/ic_launcher.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/ic_launcher_background"/>
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||
</adaptive-icon>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/ic_launcher_background"/>
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||
</adaptive-icon>
|
||||
BIN
src/Android/Resources/mipmap-hdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
src/Android/Resources/mipmap-hdpi/ic_launcher_foreground.png
Normal file
|
After Width: | Height: | Size: 941 B |
BIN
src/Android/Resources/mipmap-hdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
src/Android/Resources/mipmap-mdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 896 B |
BIN
src/Android/Resources/mipmap-mdpi/ic_launcher_foreground.png
Normal file
|
After Width: | Height: | Size: 608 B |
BIN
src/Android/Resources/mipmap-mdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
src/Android/Resources/mipmap-xhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
src/Android/Resources/mipmap-xhdpi/ic_launcher_foreground.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
src/Android/Resources/mipmap-xhdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
src/Android/Resources/mipmap-xxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
src/Android/Resources/mipmap-xxhdpi/ic_launcher_foreground.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
src/Android/Resources/mipmap-xxhdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 8.6 KiB |
BIN
src/Android/Resources/mipmap-xxxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
src/Android/Resources/mipmap-xxxhdpi/ic_launcher_foreground.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
src/Android/Resources/mipmap-xxxhdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
4
src/Android/Resources/values/ic_launcher_background.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="ic_launcher_background">#3C8DBC</color>
|
||||
</resources>
|
||||
@@ -5,9 +5,9 @@
|
||||
</string>
|
||||
<string name="AutoFillServiceDescription">
|
||||
It can be difficult and insecure for users to switch between apps to copy/paste username and password information
|
||||
from their bitwarden vault.\n\nUsing this accessibility service allows bitwarden to detect and read input fields on
|
||||
your device\'s screen. Whenever bitwarden detects a password field on the screen a notification will appear that allows
|
||||
you to quickly access your bitwarden vault and automatically fill (auto-fill) the correct login information into the
|
||||
from their Bitwarden vault.\n\nUsing this accessibility service allows Bitwarden to detect and read input fields on
|
||||
your device\'s screen. Whenever Bitwarden detects a password field on the screen a notification will appear that allows
|
||||
you to quickly access your Bitwarden vault and automatically fill (auto-fill) the correct login information into the
|
||||
necessary fields.
|
||||
</string>
|
||||
<string name="MyVault">
|
||||
|
||||
@@ -13,5 +13,6 @@
|
||||
<item name="android:windowBackground">@color/lightgray</item>
|
||||
<item name="windowActionModeOverlay">true</item>
|
||||
<item name="android:navigationBarColor">@color/darkaccent</item>
|
||||
<item name="android:actionModeBackground">@color/darkaccent</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
||||
@@ -1,3 +1,78 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<autofill-service
|
||||
xmlns:android="http://schemas.android.com/apk/res/android" />
|
||||
<autofill-service xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<compatibility-package
|
||||
android:name="com.android.chrome"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
<compatibility-package
|
||||
android:name="com.chrome.beta"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
<compatibility-package
|
||||
android:name="com.chrome.dev"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
<compatibility-package
|
||||
android:name="com.chrome.canary"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
<compatibility-package
|
||||
android:name="com.microsoft.emmx"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
<compatibility-package
|
||||
android:name="com.opera.browser"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
<compatibility-package
|
||||
android:name="com.opera.browser.beta"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
<compatibility-package
|
||||
android:name="com.opera.mini.native"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
<compatibility-package
|
||||
android:name="com.opera.mini.native.beta"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
<compatibility-package
|
||||
android:name="com.sec.android.app.sbrowser"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
<compatibility-package
|
||||
android:name="com.sec.android.app.sbrowser.beta"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
<compatibility-package
|
||||
android:name="org.mozilla.fennec_aurora"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
<compatibility-package
|
||||
android:name="org.mozilla.firefox"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
<compatibility-package
|
||||
android:name="org.mozilla.firefox_beta"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
<compatibility-package
|
||||
android:name="com.brave.browser"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
<compatibility-package
|
||||
android:name="com.google.android.apps.chrome"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
<compatibility-package
|
||||
android:name="com.google.android.apps.chrome_dev"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
<compatibility-package
|
||||
android:name="com.yandex.browser"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
<compatibility-package
|
||||
android:name="org.codeaurora.swe.browser"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
<compatibility-package
|
||||
android:name="com.amazon.cloud9"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
<compatibility-package
|
||||
android:name="mark.via.gp"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
<compatibility-package
|
||||
android:name="org.bromite.bromite"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
<compatibility-package
|
||||
android:name="org.chromium.chrome"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
<compatibility-package
|
||||
android:name="com.kiwibrowser.browser"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
<compatibility-package
|
||||
android:name="com.ecosia.android"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
</autofill-service>
|
||||
|
||||
17
src/Android/Resources/xml/network_security_config.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<network-security-config>
|
||||
<base-config>
|
||||
<trust-anchors>
|
||||
<!-- Trust pre-installed CAs -->
|
||||
<certificates src="system" />
|
||||
<!-- Additionally trust user added CAs -->
|
||||
<certificates src="user" />
|
||||
</trust-anchors>
|
||||
</base-config>
|
||||
<domain-config cleartextTrafficPermitted="false">
|
||||
<domain includeSubdomains="true">bitwarden.com</domain>
|
||||
<trust-anchors>
|
||||
<!-- Only trust pre-installed CAs for Bitwarden.com and all subdomains -->
|
||||
<certificates src="system" />
|
||||
</trust-anchors>
|
||||
</domain-config>
|
||||
</network-security-config>
|
||||
@@ -44,7 +44,15 @@ namespace Bit.Android.Services
|
||||
_keyStore = KeyStore.GetInstance(AndroidKeyStore);
|
||||
_keyStore.Load(null);
|
||||
|
||||
GenerateStoreKey();
|
||||
try
|
||||
{
|
||||
GenerateStoreKey(true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
GenerateStoreKey(false);
|
||||
}
|
||||
|
||||
GenerateAesKey();
|
||||
}
|
||||
|
||||
@@ -128,7 +136,7 @@ namespace Bit.Android.Services
|
||||
}
|
||||
}
|
||||
|
||||
private void GenerateStoreKey()
|
||||
private void GenerateStoreKey(bool withDate)
|
||||
{
|
||||
if(_keyStore.ContainsAlias(KeyAlias))
|
||||
{
|
||||
@@ -144,27 +152,33 @@ namespace Bit.Android.Services
|
||||
{
|
||||
var subject = new X500Principal($"CN={KeyAlias}");
|
||||
|
||||
var spec = new KeyPairGeneratorSpec.Builder(Application.Context)
|
||||
var builder = new KeyPairGeneratorSpec.Builder(Application.Context)
|
||||
.SetAlias(KeyAlias)
|
||||
.SetSubject(subject)
|
||||
.SetSerialNumber(BigInteger.Ten)
|
||||
.SetStartDate(new Date(0))
|
||||
.SetEndDate(end.Time)
|
||||
.Build();
|
||||
.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 spec = new KeyGenParameterSpec.Builder(KeyAlias, KeyStorePurpose.Decrypt | KeyStorePurpose.Encrypt)
|
||||
var builder = new KeyGenParameterSpec.Builder(KeyAlias, KeyStorePurpose.Decrypt | KeyStorePurpose.Encrypt)
|
||||
.SetBlockModes(KeyProperties.BlockModeGcm)
|
||||
.SetEncryptionPaddings(KeyProperties.EncryptionPaddingNone)
|
||||
.SetKeyValidityStart(new Date(0))
|
||||
.SetKeyValidityEnd(end.Time)
|
||||
.Build();
|
||||
.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();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
#if !FDROID
|
||||
using System;
|
||||
using Bit.App;
|
||||
using Bit.App.Abstractions;
|
||||
using Plugin.Settings.Abstractions;
|
||||
@@ -40,3 +41,4 @@ namespace Bit.Android.Services
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -24,6 +24,8 @@ using Bit.Android.Autofill;
|
||||
using System.Linq;
|
||||
using Plugin.Settings.Abstractions;
|
||||
using Android.Views.InputMethods;
|
||||
using Android.Widget;
|
||||
using Bit.App.Utilities;
|
||||
|
||||
namespace Bit.Android.Services
|
||||
{
|
||||
@@ -239,10 +241,9 @@ namespace Bit.Android.Services
|
||||
}
|
||||
else
|
||||
{
|
||||
var isPremium = Resolver.Resolve<ITokenService>()?.TokenPremium ?? false;
|
||||
var settings = Resolver.Resolve<ISettings>();
|
||||
var autoCopyEnabled = !settings.GetValueOrDefault(Constants.SettingDisableTotpCopy, false);
|
||||
if(isPremium && autoCopyEnabled && cipher.LoginTotp?.Value != null)
|
||||
if(Helpers.CanAccessPremium() && autoCopyEnabled && cipher.LoginTotp?.Value != null)
|
||||
{
|
||||
CopyToClipboard(App.Utilities.Crypto.Totp(cipher.LoginTotp.Value));
|
||||
}
|
||||
@@ -302,9 +303,9 @@ namespace Bit.Android.Services
|
||||
|
||||
public void DismissKeyboard()
|
||||
{
|
||||
var activity = (MainActivity)CurrentContext;
|
||||
try
|
||||
{
|
||||
var activity = (MainActivity)CurrentContext;
|
||||
var imm = (InputMethodManager)activity.GetSystemService(Context.InputMethodService);
|
||||
imm.HideSoftInputFromWindow(activity.CurrentFocus.WindowToken, 0);
|
||||
}
|
||||
@@ -424,36 +425,167 @@ namespace Bit.Android.Services
|
||||
|
||||
public void OpenAutofillSettings()
|
||||
{
|
||||
var activity = (MainActivity)CurrentContext;
|
||||
var intent = new Intent(Settings.ActionRequestSetAutofillService);
|
||||
intent.SetData(global::Android.Net.Uri.Parse("package:com.x8bit.bitwarden"));
|
||||
activity.StartActivity(intent);
|
||||
try
|
||||
{
|
||||
var activity = (MainActivity)CurrentContext;
|
||||
var intent = new Intent(Settings.ActionRequestSetAutofillService);
|
||||
intent.SetData(global::Android.Net.Uri.Parse("package:com.x8bit.bitwarden"));
|
||||
activity.StartActivity(intent);
|
||||
}
|
||||
catch(ActivityNotFoundException)
|
||||
{
|
||||
var alertBuilder = new AlertDialog.Builder((MainActivity)CurrentContext);
|
||||
alertBuilder.SetMessage(AppResources.BitwardenAutofillGoToSettings);
|
||||
alertBuilder.SetCancelable(true);
|
||||
alertBuilder.SetPositiveButton(AppResources.Ok, (sender, args) =>
|
||||
{
|
||||
(sender as AlertDialog)?.Cancel();
|
||||
});
|
||||
alertBuilder.Create().Show();
|
||||
}
|
||||
}
|
||||
|
||||
public void ShowLoading(string text)
|
||||
public async Task ShowLoadingAsync(string text)
|
||||
{
|
||||
if(_progressDialog != null)
|
||||
{
|
||||
HideLoading();
|
||||
await HideLoadingAsync();
|
||||
}
|
||||
|
||||
var activity = (MainActivity)CurrentContext;
|
||||
_progressDialog = new ProgressDialog(activity);
|
||||
_progressDialog.SetMessage(text);
|
||||
_progressDialog.SetCancelable(true);
|
||||
_progressDialog.SetCancelable(false);
|
||||
_progressDialog.Show();
|
||||
}
|
||||
|
||||
public void HideLoading()
|
||||
public Task HideLoadingAsync()
|
||||
{
|
||||
if(_progressDialog == null)
|
||||
if(_progressDialog != null)
|
||||
{
|
||||
return;
|
||||
_progressDialog.Dismiss();
|
||||
_progressDialog.Dispose();
|
||||
_progressDialog = null;
|
||||
}
|
||||
|
||||
_progressDialog.Dismiss();
|
||||
_progressDialog.Dispose();
|
||||
_progressDialog = null;
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public Task<string> DisplayPromptAync(string title = null, string description = null, string text = null)
|
||||
{
|
||||
var activity = (MainActivity)CurrentContext;
|
||||
if(activity == null)
|
||||
{
|
||||
return Task.FromResult<string>(null);
|
||||
}
|
||||
|
||||
var alertBuilder = new AlertDialog.Builder(activity);
|
||||
alertBuilder.SetTitle(title);
|
||||
alertBuilder.SetMessage(description);
|
||||
|
||||
var input = new EditText(activity)
|
||||
{
|
||||
InputType = global::Android.Text.InputTypes.ClassText
|
||||
};
|
||||
|
||||
if(text == null)
|
||||
{
|
||||
text = string.Empty;
|
||||
}
|
||||
|
||||
input.Text = text;
|
||||
input.SetSelection(text.Length);
|
||||
|
||||
alertBuilder.SetView(input);
|
||||
|
||||
var result = new TaskCompletionSource<string>();
|
||||
alertBuilder.SetPositiveButton(AppResources.Ok, (sender, args) =>
|
||||
{
|
||||
result.TrySetResult(input.Text ?? string.Empty);
|
||||
});
|
||||
|
||||
alertBuilder.SetNegativeButton(AppResources.Cancel, (sender, args) =>
|
||||
{
|
||||
result.TrySetResult(null);
|
||||
});
|
||||
|
||||
var alert = alertBuilder.Create();
|
||||
alert.Window.SetSoftInputMode(global::Android.Views.SoftInput.StateVisible);
|
||||
alert.Show();
|
||||
return result.Task;
|
||||
}
|
||||
|
||||
public Task<string> DisplayAlertAsync(string title, string message, string cancel, params string[] buttons)
|
||||
{
|
||||
var activity = (MainActivity)CurrentContext;
|
||||
if(activity == null)
|
||||
{
|
||||
return Task.FromResult<string>(null);
|
||||
}
|
||||
|
||||
var result = new TaskCompletionSource<string>();
|
||||
var alertBuilder = new AlertDialog.Builder(activity);
|
||||
alertBuilder.SetTitle(title);
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(message))
|
||||
{
|
||||
if(buttons != null && buttons.Length > 2)
|
||||
{
|
||||
if(!string.IsNullOrWhiteSpace(title))
|
||||
{
|
||||
alertBuilder.SetTitle($"{title}: {message}");
|
||||
}
|
||||
else
|
||||
{
|
||||
alertBuilder.SetTitle(message);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
alertBuilder.SetMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
if(buttons != null)
|
||||
{
|
||||
if(buttons.Length > 2)
|
||||
{
|
||||
alertBuilder.SetItems(buttons, (sender, args) =>
|
||||
{
|
||||
result.TrySetResult(buttons[args.Which]);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
if(buttons.Length > 0)
|
||||
{
|
||||
alertBuilder.SetPositiveButton(buttons[0], (sender, args) =>
|
||||
{
|
||||
result.TrySetResult(buttons[0]);
|
||||
});
|
||||
}
|
||||
if(buttons.Length > 1)
|
||||
{
|
||||
alertBuilder.SetNeutralButton(buttons[1], (sender, args) =>
|
||||
{
|
||||
result.TrySetResult(buttons[1]);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(cancel))
|
||||
{
|
||||
alertBuilder.SetNegativeButton(cancel, (sender, args) =>
|
||||
{
|
||||
result.TrySetResult(cancel);
|
||||
});
|
||||
}
|
||||
|
||||
var alert = alertBuilder.Create();
|
||||
alert.CancelEvent += (o, args) => { result.TrySetResult(null); };
|
||||
alert.Show();
|
||||
return result.Task;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.Content.PM;
|
||||
using Android.Nfc;
|
||||
using Android.OS;
|
||||
using Android.Views.Autofill;
|
||||
using Bit.App.Abstractions;
|
||||
@@ -45,7 +47,7 @@ namespace Bit.Android.Services
|
||||
return 1f;
|
||||
}
|
||||
}
|
||||
public bool NfcEnabled => Utilities.NfcEnabled();
|
||||
public bool NfcEnabled => NfcIsEnabled();
|
||||
public bool HasCamera => CrossCurrentActivity.Current.Activity.PackageManager.HasSystemFeature(
|
||||
PackageManager.FeatureCamera);
|
||||
public bool AutofillServiceSupported => AutofillSupported();
|
||||
@@ -56,10 +58,18 @@ namespace Bit.Android.Services
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
var afm = (AutofillManager)CrossCurrentActivity.Current.Activity.GetSystemService(
|
||||
Java.Lang.Class.FromType(typeof(AutofillManager)));
|
||||
return afm.IsAutofillSupported;
|
||||
}
|
||||
public bool NfcIsEnabled()
|
||||
{
|
||||
var activity = CrossCurrentActivity.Current.Activity;
|
||||
var manager = (NfcManager)activity.GetSystemService(Context.NfcService);
|
||||
var adapter = manager.DefaultAdapter;
|
||||
return adapter != null && adapter.IsEnabled;
|
||||
}
|
||||
public bool IsExtension => false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
#if !FDROID
|
||||
using System;
|
||||
using Bit.App;
|
||||
using Bit.App.Abstractions;
|
||||
using Plugin.Settings.Abstractions;
|
||||
@@ -40,6 +41,11 @@ namespace Bit.Android.Services
|
||||
TrackEvent("AutofillService", eventName, label);
|
||||
}
|
||||
|
||||
public void TrackAutofillExtensionEvent(string eventName, string label = null)
|
||||
{
|
||||
TrackExtensionEvent(eventName, label);
|
||||
}
|
||||
|
||||
public void TrackEvent(string category, string eventName, string label = null)
|
||||
{
|
||||
var builder = new HitBuilders.EventBuilder();
|
||||
@@ -80,3 +86,4 @@ namespace Bit.Android.Services
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -54,7 +54,8 @@ namespace Bit.Android.Services
|
||||
|
||||
if(androidLanguage.StartsWith("zh"))
|
||||
{
|
||||
if(androidLanguage.Contains("Hant") || androidLanguage.Contains("TW"))
|
||||
if(androidLanguage.Contains("Hant") || androidLanguage.Contains("TW") ||
|
||||
androidLanguage.Contains("HK") || androidLanguage.Contains("MO"))
|
||||
{
|
||||
netLanguage = "zh-Hant";
|
||||
}
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
using System;
|
||||
using Android.Content;
|
||||
using Bit.App.Abstractions;
|
||||
using Plugin.CurrentActivity;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.Android.Services
|
||||
{
|
||||
public class MemoryService : IMemoryService
|
||||
{
|
||||
public MemoryInfo GetInfo()
|
||||
{
|
||||
return MemoryHelper.GetMemoryInfo(CrossCurrentActivity.Current.Activity);
|
||||
}
|
||||
|
||||
public void Check()
|
||||
{
|
||||
MemoryHelper.MemoryCheck(CrossCurrentActivity.Current.Activity);
|
||||
}
|
||||
|
||||
public static class MemoryHelper
|
||||
{
|
||||
public static void MemoryCheck(Context context)
|
||||
{
|
||||
Console.WriteLine("MemoryHelper.MemoryCheck.{0} - {1}", "Start", context.ToString());
|
||||
var maxMemory = Java.Lang.Runtime.GetRuntime().MaxMemory();
|
||||
var freeMemory = Java.Lang.Runtime.GetRuntime().FreeMemory();
|
||||
var percentUsed = (maxMemory - freeMemory) / (double)maxMemory;
|
||||
Console.WriteLine("Free memory: {0:N}", freeMemory);
|
||||
Console.WriteLine("Max memory: {0:N}", maxMemory);
|
||||
Console.WriteLine("% used: {0:P}", percentUsed);
|
||||
Console.WriteLine("MemoryHelper.MemoryCheck.{0} {3:P} {1} out of {2}", "End", freeMemory, maxMemory, percentUsed);
|
||||
}
|
||||
|
||||
public static MemoryInfo GetMemoryInfo(Context context)
|
||||
{
|
||||
var retVal = new MemoryInfo();
|
||||
retVal.MaxMemory = Java.Lang.Runtime.GetRuntime().MaxMemory();
|
||||
retVal.FreeMemory = Java.Lang.Runtime.GetRuntime().FreeMemory();
|
||||
retVal.TotalMemory = Java.Lang.Runtime.GetRuntime().TotalMemory();
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Controls;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.Android.Services
|
||||
{
|
||||
public class ReflectionService : IReflectionService
|
||||
{
|
||||
public Func<double, double, SizeRequest> GetVisualElementOnSizeRequest(ExtendedTableView tableView)
|
||||
{
|
||||
var handle = typeof(VisualElement).GetMethod(
|
||||
"OnSizeRequest",
|
||||
BindingFlags.Instance | BindingFlags.NonPublic,
|
||||
null,
|
||||
new Type[] { typeof(double), typeof(double) },
|
||||
null)?.MethodHandle;
|
||||
|
||||
if(!handle.HasValue)
|
||||
{
|
||||
throw new ArgumentNullException("handle could not be found.");
|
||||
}
|
||||
|
||||
var pointer = handle.Value.GetFunctionPointer();
|
||||
if(pointer == null)
|
||||
{
|
||||
throw new ArgumentNullException("pointer could not be found.");
|
||||
}
|
||||
|
||||
return (Func<double, double, SizeRequest>)Activator.CreateInstance(typeof(Func<double, double, SizeRequest>), tableView, pointer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,20 +3,12 @@ using Android.App;
|
||||
using Android.Content;
|
||||
using Java.Security;
|
||||
using System.IO;
|
||||
using Android.Nfc;
|
||||
using Android.Provider;
|
||||
|
||||
namespace Bit.Android
|
||||
{
|
||||
public static class Utilities
|
||||
{
|
||||
public static bool NfcEnabled()
|
||||
{
|
||||
var manager = (NfcManager)Application.Context.GetSystemService("nfc");
|
||||
var adapter = manager.DefaultAdapter;
|
||||
return adapter != null && adapter.IsEnabled;
|
||||
}
|
||||
|
||||
public static void SendCrashEmail(Exception e, bool includeSecurityProviders = true)
|
||||
{
|
||||
SendCrashEmail(e.Message + "\n\n" + e.StackTrace, includeSecurityProviders);
|
||||
@@ -38,7 +30,7 @@ namespace Bit.Android
|
||||
|
||||
emailIntent.SetType("plain/text");
|
||||
emailIntent.PutExtra(Intent.ExtraEmail, new String[] { "hello@bitwarden.com" });
|
||||
emailIntent.PutExtra(Intent.ExtraSubject, "bitwarden Crash Report");
|
||||
emailIntent.PutExtra(Intent.ExtraSubject, "Bitwarden Crash Report");
|
||||
emailIntent.PutExtra(Intent.ExtraText, FormatText(text, includeSecurityProviders));
|
||||
|
||||
Application.Context.StartActivity(Intent.CreateChooser(emailIntent, "Send mail..."));
|
||||
@@ -50,7 +42,7 @@ namespace Bit.Android
|
||||
|
||||
emailIntent.SetType("plain/text");
|
||||
emailIntent.PutExtra(Intent.ExtraEmail, new String[] { "hello@bitwarden.com" });
|
||||
emailIntent.PutExtra(Intent.ExtraSubject, "bitwarden Crash Report");
|
||||
emailIntent.PutExtra(Intent.ExtraSubject, "Bitwarden Crash Report");
|
||||
emailIntent.PutExtra(Intent.ExtraText, FormatText(text, includeSecurityProviders));
|
||||
|
||||
act.StartActivity(Intent.CreateChooser(emailIntent, "Send mail..."));
|
||||
@@ -68,7 +60,7 @@ namespace Bit.Android
|
||||
|
||||
private static string FormatText(string text, bool includeSecurityProviders = true)
|
||||
{
|
||||
var crashMessage = "bitwarden has crashed. Please send this email to our support team so that we can help " +
|
||||
var crashMessage = "Bitwarden has crashed. Please send this email to our support team so that we can help " +
|
||||
"resolve the problem for you. Thank you.";
|
||||
|
||||
text = crashMessage + "\n\n =============================================== \n\n" + text;
|
||||
|
||||
90
src/Android/ci-build-apks.ps1
Normal file
@@ -0,0 +1,90 @@
|
||||
$rootPath = $env:APPVEYOR_BUILD_FOLDER;
|
||||
|
||||
$androidPath = $($rootPath + "\src\Android\Android.csproj");
|
||||
$appPath = $($rootPath + "\src\App\App.csproj");
|
||||
|
||||
echo "##### Increment Version"
|
||||
|
||||
$androidManifest = $($rootPath + "\src\Android\Properties\AndroidManifest.xml");
|
||||
|
||||
$xml=New-Object XML;
|
||||
$xml.Load($androidManifest);
|
||||
|
||||
$node=$xml.SelectNodes("/manifest");
|
||||
$node.SetAttribute("android:versionCode", $env:APPVEYOR_BUILD_NUMBER);
|
||||
|
||||
$xml.Save($androidManifest);
|
||||
|
||||
echo "##### Decrypt Keystore"
|
||||
|
||||
$encKeystorePath = $($rootPath + "\src\Android\8bit.keystore.enc");
|
||||
$secureFilePath = $($rootPath + "\secure-file\tools\secure-file.exe");
|
||||
|
||||
Invoke-Expression "& `"$secureFilePath`" -decrypt $($encKeystorePath) -secret $($env:keystore_dec_secret)"
|
||||
|
||||
echo "##### Sign Release Configuration"
|
||||
|
||||
msbuild "$($androidPath)" "/t:SignAndroidPackage" "/p:Configuration=Release" "/p:AndroidKeyStore=true" "/p:AndroidSigningKeyAlias=bitwarden" "/p:AndroidSigningKeyPass=$($env:keystore_password)" "/p:AndroidSigningKeyStore=8bit.keystore" "/p:AndroidSigningStorePass=$($env:keystore_password)" "/v:quiet"
|
||||
|
||||
echo "##### Copy Release apk to project root"
|
||||
|
||||
$signedApkPath = $($rootPath + "\src\Android\bin\Release\com.x8bit.bitwarden-Signed.apk");
|
||||
$signedApkDestPath = $($rootPath + "\com.x8bit.bitwarden-" + $env:APPVEYOR_BUILD_NUMBER + ".apk");
|
||||
|
||||
Copy-Item $signedApkPath $signedApkDestPath
|
||||
|
||||
echo "##### Clean Android and App"
|
||||
|
||||
msbuild "$($androidPath)" "/t:Clean" "/p:Configuration=FDroid"
|
||||
msbuild "$($appPath)" "/t:Clean" "/p:Configuration=FDroid"
|
||||
|
||||
echo "##### Backup project files"
|
||||
|
||||
Copy-Item $androidPath $($androidPath + ".original");
|
||||
Copy-Item $appPath $($appPath + ".original");
|
||||
|
||||
echo "##### Uninstall from Android.csproj"
|
||||
|
||||
$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);
|
||||
|
||||
$playServiceNode=$xml.SelectSingleNode("/ns:Project/ns:ItemGroup/ns:PackageReference[@Include='Xamarin.GooglePlayServices.Analytics']", $ns);
|
||||
$playServiceNode.ParentNode.RemoveChild($playServiceNode);
|
||||
|
||||
$xml.Save($androidPath);
|
||||
|
||||
echo "##### Uninstall from App.csproj"
|
||||
|
||||
$xml=New-Object XML;
|
||||
$xml.Load($appPath);
|
||||
|
||||
$hockeyNode=$xml.SelectSingleNode("/Project/ItemGroup/PackageReference[@Include='HockeySDK.Xamarin']");
|
||||
$hockeyNode.ParentNode.RemoveChild($hockeyNode);
|
||||
|
||||
$xml.Save($appPath);
|
||||
|
||||
echo "##### Restore NuGet"
|
||||
|
||||
$nugetPath = $($rootPath + "\nuget.exe");
|
||||
|
||||
Invoke-Expression "& `"$nugetPath`" restore"
|
||||
|
||||
echo "##### Build and Sign FDroid Configuration"
|
||||
|
||||
msbuild "$($androidPath)" "/logger:C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" "/p:Configuration=FDroid"
|
||||
msbuild "$($androidPath)" "/t:SignAndroidPackage" "/p:Configuration=FDroid" "/p:AndroidKeyStore=true" "/p:AndroidSigningKeyAlias=bitwarden" "/p:AndroidSigningKeyPass=$($env:keystore_password)" "/p:AndroidSigningKeyStore=8bit.keystore" "/p:AndroidSigningStorePass=$($env:keystore_password)" "/v:quiet"
|
||||
|
||||
echo "##### Copy FDroid apk to project root"
|
||||
|
||||
$signedApkPath = $($rootPath + "\src\Android\bin\FDroid\com.x8bit.bitwarden-Signed.apk");
|
||||
$signedApkDestPath = $($rootPath + "\com.x8bit.bitwarden-fdroid-" + $env:APPVEYOR_BUILD_NUMBER + ".apk");
|
||||
|
||||
Copy-Item $signedApkPath $signedApkDestPath
|
||||
|
||||
echo "##### Done"
|
||||
@@ -1,8 +0,0 @@
|
||||
$rootPath = $args[0];
|
||||
$newVersionCode = $args[1];
|
||||
|
||||
$xml=New-Object XML;
|
||||
$xml.Load($rootPath + "\src\Android\Properties\AndroidManifest.xml");
|
||||
$node=$xml.SelectNodes("/manifest");
|
||||
$node.SetAttribute("android:versionCode", $newVersionCode);
|
||||
$xml.Save($rootPath + "\src\Android\Properties\AndroidManifest.xml");
|
||||
13
src/Android/update-android.ps1
Normal file
@@ -0,0 +1,13 @@
|
||||
dir "${env:ProgramFiles(x86)}\Android\android-sdk\platforms"
|
||||
dir "${env:ProgramFiles(x86)}\Android\android-sdk\build-tools"
|
||||
|
||||
$pwd = Get-Location
|
||||
cd "${env:ProgramFiles(x86)}\Android\android-sdk\tools\bin"
|
||||
.\sdkmanager --list
|
||||
Echo 'y' | .\sdkmanager "platforms;android-28" "build-tools;28.0.2" | Out-Null
|
||||
Echo 'y' | .\sdkmanager --update | Out-Null
|
||||
|
||||
dir "${env:ProgramFiles(x86)}\Android\android-sdk\platforms"
|
||||
dir "${env:ProgramFiles(x86)}\Android\android-sdk\build-tools"
|
||||
|
||||
cd $pwd
|
||||
8
src/App/Abstractions/ITreeNodeObject.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace Bit.App.Abstractions
|
||||
{
|
||||
public interface ITreeNodeObject
|
||||
{
|
||||
string Id { get; set; }
|
||||
string Name { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ namespace Bit.App.Abstractions
|
||||
{
|
||||
public interface IAccountsApiRepository
|
||||
{
|
||||
Task<ApiResult<PreloginResponse>> PostPreloginAsync(PreloginRequest requestObj);
|
||||
Task<ApiResult> PostRegisterAsync(RegisterRequest requestObj);
|
||||
Task<ApiResult> PostPasswordHintAsync(PasswordHintRequest requestObj);
|
||||
Task<ApiResult<DateTime?>> GetAccountRevisionDateAsync();
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace Bit.App.Abstractions
|
||||
{
|
||||
public interface ICipherApiRepository : IApiRepository<CipherRequest, CipherResponse, string>
|
||||
{
|
||||
Task<ApiResult<CipherResponse>> PostAttachmentAsync(string cipherId, byte[] data, string fileName);
|
||||
Task<ApiResult<CipherResponse>> PostAttachmentAsync(string cipherId, byte[] data, string key, string fileName);
|
||||
Task<ApiResult> DeleteAttachmentAsync(string cipherId, string attachmentId);
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ namespace Bit.App.Abstractions
|
||||
public interface IAppSettingsService
|
||||
{
|
||||
bool Locked { get; set; }
|
||||
int FailedPinAttempts { get; set; }
|
||||
DateTime LastActivity { get; set; }
|
||||
DateTime LastCacheClear { get; set; }
|
||||
bool AutofillPersistNotification { get; set; }
|
||||
@@ -16,5 +17,8 @@ namespace Bit.App.Abstractions
|
||||
string ApiUrl { get; set; }
|
||||
string IdentityUrl { get; set; }
|
||||
string IconsUrl { get; set; }
|
||||
bool ClearCiphersCache { get; set; }
|
||||
bool ClearExtensionCiphersCache { get; set; }
|
||||
bool OrganizationGivesPremium { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,8 @@ namespace Bit.App.Abstractions
|
||||
string PreviousUserId { get; }
|
||||
bool UserIdChanged { get; }
|
||||
string Email { get; set; }
|
||||
KdfType Kdf { get; set; }
|
||||
int KdfIterations { get; set; }
|
||||
string PIN { get; set; }
|
||||
bool BelongsToOrganization(string orgId);
|
||||
void LogOut(string logoutMessage = null);
|
||||
|
||||
@@ -16,10 +16,10 @@ namespace Bit.App.Abstractions
|
||||
Task<IEnumerable<Cipher>> GetAllByCollectionAsync(string collectionId);
|
||||
Task<Tuple<IEnumerable<Cipher>, IEnumerable<Cipher>, IEnumerable<Cipher>>> GetAllAsync(string uriString);
|
||||
Task<ApiResult<CipherResponse>> SaveAsync(Cipher cipher);
|
||||
Task UpsertDataAsync(CipherData cipher);
|
||||
Task UpsertDataAsync(CipherData cipher, bool sendMessage, bool created);
|
||||
Task<ApiResult> DeleteAsync(string id);
|
||||
Task DeleteDataAsync(string id);
|
||||
Task<byte[]> DownloadAndDecryptAttachmentAsync(string url, string orgId = null);
|
||||
Task DeleteDataAsync(string id, bool sendMessage);
|
||||
Task<byte[]> DownloadAndDecryptAttachmentAsync(string url, CipherString key, string orgId = null);
|
||||
Task<ApiResult<CipherResponse>> EncryptAndSaveAttachmentAsync(Cipher cipher, byte[] data, string fileName);
|
||||
Task UpsertAttachmentDataAsync(IEnumerable<AttachmentData> attachments);
|
||||
Task<ApiResult> DeleteAttachmentAsync(Cipher cipher, string attachmentId);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Bit.App.Models;
|
||||
using Bit.App.Enums;
|
||||
using Bit.App.Models;
|
||||
using Bit.App.Models.Api;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -23,10 +24,9 @@ namespace Bit.App.Abstractions
|
||||
byte[] RsaDecryptToBytes(CipherString encyptedValue, byte[] privateKey);
|
||||
CipherString Encrypt(string plaintextValue, SymmetricCryptoKey key = null);
|
||||
byte[] EncryptToBytes(byte[] plainBytes, SymmetricCryptoKey key = null);
|
||||
SymmetricCryptoKey MakeKeyFromPassword(string password, string salt);
|
||||
string MakeKeyFromPasswordBase64(string password, string salt);
|
||||
SymmetricCryptoKey MakeKeyFromPassword(string password, string salt, KdfType kdf, int kdfIterations);
|
||||
byte[] HashPassword(SymmetricCryptoKey key, string password);
|
||||
string HashPasswordBase64(SymmetricCryptoKey key, string password);
|
||||
CipherString MakeEncKey(SymmetricCryptoKey key);
|
||||
Tuple<SymmetricCryptoKey, CipherString> MakeEncKey(SymmetricCryptoKey key);
|
||||
}
|
||||
}
|
||||
@@ -6,8 +6,8 @@ namespace Bit.App.Abstractions
|
||||
{
|
||||
public interface IDeviceActionService
|
||||
{
|
||||
void ShowLoading(string text);
|
||||
void HideLoading();
|
||||
Task ShowLoadingAsync(string text);
|
||||
Task HideLoadingAsync();
|
||||
void Toast(string text, bool longDuration = false);
|
||||
void CopyToClipboard(string text);
|
||||
bool OpenFile(byte[] fileData, string id, string fileName);
|
||||
@@ -22,5 +22,7 @@ namespace Bit.App.Abstractions
|
||||
void OpenAccessibilitySettings();
|
||||
void OpenAutofillSettings();
|
||||
Task LaunchAppAsync(string appName, Page page);
|
||||
Task<string> DisplayPromptAync(string title = null, string description = null, string text = null);
|
||||
Task<string> DisplayAlertAsync(string title, string message, string cancel, params string[] buttons);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,5 +10,6 @@
|
||||
bool HasCamera { get; }
|
||||
bool AutofillServiceSupported { get; }
|
||||
bool HasFaceIdSupport { get; }
|
||||
bool IsExtension { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace Bit.App.Abstractions
|
||||
void TrackPage(string pageName);
|
||||
void TrackAppEvent(string eventName, string label = null);
|
||||
void TrackExtensionEvent(string eventName, string label = null);
|
||||
void TrackAutofillExtensionEvent(string eventName, string label = null);
|
||||
void TrackEvent(string category, string eventName, string label = null);
|
||||
void TrackException(string message, bool fatal);
|
||||
void Dispatch(Action completionHandler = null);
|
||||
|
||||
@@ -7,8 +7,8 @@ namespace Bit.App.Abstractions
|
||||
public interface ILockService
|
||||
{
|
||||
void UpdateLastActivity();
|
||||
Task<LockType> GetLockTypeAsync(bool forceLock);
|
||||
Task CheckLockAsync(bool forceLock);
|
||||
Task<LockType> GetLockTypeAsync(bool forceLock, bool onlyIfAlreadyLocked = false);
|
||||
Task CheckLockAsync(bool forceLock, bool onlyIfAlreadyLocked = false);
|
||||
bool TopPageIsLock();
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
namespace Bit.App.Abstractions
|
||||
{
|
||||
public interface IMemoryService
|
||||
{
|
||||
MemoryInfo GetInfo();
|
||||
void Check();
|
||||
}
|
||||
|
||||
public class MemoryInfo
|
||||
{
|
||||
public long FreeMemory { get; set; }
|
||||
public long MaxMemory { get; set; }
|
||||
public long TotalMemory { get; set; }
|
||||
public long UsedMemory => TotalMemory - FreeMemory;
|
||||
|
||||
public double HeapUsage()
|
||||
{
|
||||
return UsedMemory / (double)TotalMemory;
|
||||
}
|
||||
|
||||
public double Usage()
|
||||
{
|
||||
return UsedMemory / (double)MaxMemory;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
using System;
|
||||
using Bit.App.Controls;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Abstractions
|
||||
{
|
||||
public interface IReflectionService
|
||||
{
|
||||
Func<double, double, SizeRequest> GetVisualElementOnSizeRequest(ExtendedTableView tableView);
|
||||
}
|
||||
}
|
||||
@@ -78,14 +78,14 @@ namespace Bit.App
|
||||
MainPage = new ExtendedNavigationPage(new HomePage());
|
||||
}
|
||||
|
||||
if(Device.RuntimePlatform == Device.iOS)
|
||||
MessagingCenter.Subscribe<Application, bool>(Current, "Resumed", async (sender, forceLock) =>
|
||||
{
|
||||
MessagingCenter.Subscribe<Application, bool>(Current, "Resumed", async (sender, forceLock) =>
|
||||
Device.BeginInvokeOnMainThread(async () => await _lockService.CheckLockAsync(forceLock));
|
||||
if(Device.RuntimePlatform == Device.iOS)
|
||||
{
|
||||
Device.BeginInvokeOnMainThread(async () => await _lockService.CheckLockAsync(forceLock));
|
||||
await Task.Run(() => FullSyncAsync()).ConfigureAwait(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected async override void OnStart()
|
||||
@@ -317,6 +317,11 @@ namespace Bit.App
|
||||
AppResources.Culture = ci;
|
||||
_localizeService.SetLocale(ci);
|
||||
}
|
||||
|
||||
// Calendars are removed by linker. ref https://bugzilla.xamarin.com/show_bug.cgi?id=59077
|
||||
new System.Globalization.ThaiBuddhistCalendar();
|
||||
new System.Globalization.HijriCalendar();
|
||||
new System.Globalization.UmAlQuraCalendar();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,15 @@
|
||||
<RootNamespace>Bit.App</RootNamespace>
|
||||
<AssemblyName>BitwardenApp</AssemblyName>
|
||||
<NeutralLanguage>en-US</NeutralLanguage>
|
||||
<Configurations>Debug;Release;FDroid</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)' == 'FDroid|netstandard2.0|AnyCPU'">
|
||||
<DefineConstants>TRACE;FDROID;NETSTANDARD2_0</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)' == 'FDroid|net471|AnyCPU'">
|
||||
<DefineConstants>TRACE;FDROID;NET471</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -16,17 +25,17 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="HockeySDK.Xamarin" Version="5.0.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
|
||||
<PackageReference Include="HockeySDK.Xamarin" Version="5.1.2" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
||||
<PackageReference Include="PCLCrypto" Version="2.0.147" />
|
||||
<PackageReference Include="Plugin.Fingerprint" Version="1.4.6-beta4" />
|
||||
<PackageReference Include="Plugin.Fingerprint" Version="1.4.9" />
|
||||
<PackageReference Include="Refractored.FloatingActionButtonForms" Version="2.1.0" />
|
||||
<PackageReference Include="sqlite-net-pcl" Version="1.5.166-beta" />
|
||||
<PackageReference Include="System.Net.Http" Version="4.3.3" />
|
||||
<PackageReference Include="Xam.Plugin.Connectivity" Version="3.0.3" />
|
||||
<PackageReference Include="sqlite-net-pcl" Version="1.5.231" />
|
||||
<PackageReference Include="System.Net.Http" Version="4.3.4" />
|
||||
<PackageReference Include="Xam.Plugin.Connectivity" Version="3.2.0" />
|
||||
<PackageReference Include="Xam.Plugins.Settings" Version="3.1.1" />
|
||||
<PackageReference Include="Xamarin.FFImageLoading.Forms" Version="2.2.9" />
|
||||
<PackageReference Include="Xamarin.Forms" Version="2.5.0.121934" />
|
||||
<PackageReference Include="Xamarin.FFImageLoading.Forms" Version="2.4.4.859" />
|
||||
<PackageReference Include="Xamarin.Forms" Version="3.4.0.1008975" />
|
||||
<PackageReference Include="XLabs.IoC" Version="2.0.5782" />
|
||||
<PackageReference Include="ZXing.Net.Mobile.Forms" Version="2.1.47" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -45,6 +45,10 @@
|
||||
public const string ApiUrl = "other:apiUrl";
|
||||
public const string IdentityUrl = "other:identityUrl";
|
||||
public const string IconsUrl = "other:iconsUrl";
|
||||
public const string FailedPinAttempts = "other:failedPinAttempts";
|
||||
public const string ClearCiphersCache = "other:clearCiphersCache";
|
||||
public const string ClearExtensionCiphersCache = "other:clearExtensionCiphersCache";
|
||||
public const string OrgGivesPremium = "other:orgGivesPremium";
|
||||
|
||||
public const int SelectFileRequestCode = 42;
|
||||
public const int SelectFilePermissionRequestCode = 43;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Pages;
|
||||
using Xamarin.Forms;
|
||||
using XLabs.Ioc;
|
||||
|
||||
@@ -10,23 +11,33 @@ namespace Bit.App.Controls
|
||||
private IGoogleAnalyticsService _googleAnalyticsService;
|
||||
private ILockService _lockService;
|
||||
private IDeviceActionService _deviceActionService;
|
||||
private IAuthService _authService;
|
||||
private bool _syncIndicator;
|
||||
private bool _updateActivity;
|
||||
private bool _requireAuth;
|
||||
|
||||
public ExtendedContentPage(bool syncIndicator = false, bool updateActivity = true)
|
||||
public ExtendedContentPage(bool syncIndicator = false, bool updateActivity = true, bool requireAuth = true)
|
||||
{
|
||||
_syncIndicator = syncIndicator;
|
||||
_updateActivity = updateActivity;
|
||||
_requireAuth = requireAuth;
|
||||
_syncService = Resolver.Resolve<ISyncService>();
|
||||
_googleAnalyticsService = Resolver.Resolve<IGoogleAnalyticsService>();
|
||||
_lockService = Resolver.Resolve<ILockService>();
|
||||
_deviceActionService = Resolver.Resolve<IDeviceActionService>();
|
||||
_authService = Resolver.Resolve<IAuthService>();
|
||||
|
||||
BackgroundColor = Color.FromHex("efeff4");
|
||||
}
|
||||
|
||||
protected override void OnAppearing()
|
||||
protected async override void OnAppearing()
|
||||
{
|
||||
if(_requireAuth && !_authService.IsAuthenticated)
|
||||
{
|
||||
Device.BeginInvokeOnMainThread(
|
||||
() => Application.Current.MainPage = new ExtendedNavigationPage(new HomePage()));
|
||||
}
|
||||
|
||||
if(_syncIndicator)
|
||||
{
|
||||
MessagingCenter.Subscribe<Application, bool>(Application.Current, "SyncCompleted",
|
||||
@@ -41,6 +52,7 @@ namespace Bit.App.Controls
|
||||
}
|
||||
|
||||
_googleAnalyticsService.TrackPage(GetType().Name);
|
||||
await _lockService.CheckLockAsync(false, true);
|
||||
base.OnAppearing();
|
||||
}
|
||||
|
||||
|
||||