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

Compare commits

...

179 Commits

Author SHA1 Message Date
kspearrin
b732b2ffa7 remove password debug code 2018-04-20 20:14:39 -04:00
Kyle Spearrin
617a7be4f3 version bump 2018-04-17 11:28:23 -04:00
Kyle Spearrin
5c5e368d6b comment out password debug 2018-04-17 11:03:36 -04:00
Kyle Spearrin
ff9f49416a track with node id + hash code 2018-04-16 11:01:32 -04:00
Kyle Spearrin
93cae0e9cc dont check ids 2018-04-16 09:00:51 -04:00
Kyle Spearrin
61e75ce747 remove UWP projects so CI will work 2018-04-16 08:28:17 -04:00
Kyle Spearrin
50affe26c5 update resources 2018-04-16 08:18:54 -04:00
kspearrin
8566362607 no need to update vs anymore 2018-04-15 22:00:21 -04:00
kspearrin
36925770d0 show ut8 password alert 2018-04-15 21:45:05 -04:00
kspearrin
d17ca1686e ignore recipient search fields 2018-04-15 21:02:55 -04:00
kspearrin
2ad709dae4 fix ipad crash on doc picker 2018-04-07 12:15:59 -04:00
kspearrin
5a3d86a12a Only adjust insets on phone devices 2018-04-07 11:32:01 -04:00
Kyle Spearrin
1a4ba36820 add support for via browser 2018-04-03 16:08:11 -04:00
Kyle Spearrin
ddeae3b5ba add support for Duo Organization 2FA 2018-04-03 15:59:58 -04:00
Kyle Spearrin
10df9e7cd5 multibutton alert, autofill and save new uri 2018-04-02 13:37:46 -04:00
Kyle Spearrin
be11933c60 remove persian language until further verification 2018-03-29 11:46:09 -04:00
Kyle Spearrin
d2db68b781 New Crowdin translations (#299)
* New translations AppResources.resx (Bulgarian)

* New translations copy.resx (Persian)

* New translations AppResources.resx (Vietnamese)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Thai)

* New translations copy.resx (Portuguese, Brazilian)

* New translations copy.resx (Portuguese)

* New translations copy.resx (Polish)

* New translations AppResources.resx (Polish)

* New translations copy.resx (Persian)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Persian)

* New translations copy.resx (Italian)

* New translations copy.resx (German)

* New translations copy.resx (German)

* New translations AppResources.resx (German)

* New translations copy.resx (French)

* New translations copy.resx (Danish)

* New translations copy.resx (Danish)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Croatian)

* New translations copy.resx (Vietnamese)
2018-03-29 11:42:49 -04:00
Kyle Spearrin
da6e271584 refactor ignoresearch and password terms detection 2018-03-28 11:48:49 -04:00
Kyle Spearrin
5103c80e1e set default uri on add cipher 2018-03-26 17:06:58 -04:00
Kyle Spearrin
b5c80ea267 version bump 2018-03-22 12:01:17 -04:00
Kyle Spearrin
b5747fbb44 show/hide loading are async now 2018-03-22 11:07:41 -04:00
Kyle Spearrin
215ded8a77 fixes for match detection selection 2018-03-22 09:08:19 -04:00
Kyle Spearrin
e7ab6da068 fix param names for arg null exceptions 2018-03-21 07:35:27 -04:00
Kyle Spearrin
ee881f67ee version bump 2018-03-20 20:21:11 -04:00
Kyle Spearrin
f33248aa4f crash fixes 2018-03-20 20:19:44 -04:00
Kyle Spearrin
c6a40bac03 null checks on dialogs 2018-03-19 21:07:27 -04:00
Kyle Spearrin
aa38e79d08 resource update 2018-03-19 15:57:19 -04:00
Kyle Spearrin
9cac10e559 version bump 2018-03-19 10:24:54 -04:00
Kyle Spearrin
efbd418f56 New Crowdin translations (#296)
* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Estonian)

* New translations copy.resx (Estonian)

* New translations AppResources.resx (French)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Ukrainian)
2018-03-19 10:15:52 -04:00
Kyle Spearrin
4ff3464abd new ic_launcher for adaptive icons 2018-03-17 17:26:10 -04:00
Kyle Spearrin
907ddbf903 collapse no folder listing if more than 99 items 2018-03-16 10:59:54 -04:00
Kyle Spearrin
7041991d5a android dialog is not cancelable 2018-03-16 10:42:07 -04:00
Kyle Spearrin
b26067e5da domain search term must be at least 3 characters 2018-03-16 10:41:53 -04:00
Kyle Spearrin
e519b13533 extension add login adjustments 2018-03-15 19:57:18 -04:00
Kyle Spearrin
30bc3867bf New Crowdin translations (#295)
* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Romanian)

* New translations copy.resx (Portuguese, Brazilian)

* New translations copy.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations copy.resx (Portuguese)

* New translations copy.resx (Portuguese)

* New translations copy.resx (Polish)

* New translations copy.resx (Russian)

* New translations copy.resx (Polish)

* New translations AppResources.resx (Polish)

* New translations copy.resx (Persian)

* New translations copy.resx (Persian)

* New translations AppResources.resx (Persian)

* New translations copy.resx (Norwegian Bokmal)

* New translations copy.resx (Norwegian Bokmal)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (Russian)

* New translations copy.resx (Russian)

* New translations copy.resx (Japanese)

* New translations AppResources.resx (Vietnamese)

* New translations copy.resx (Ukrainian)

* New translations copy.resx (Ukrainian)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Thai)

* New translations copy.resx (Swedish)

* New translations copy.resx (Swedish)

* New translations AppResources.resx (Swedish)

* New translations copy.resx (Spanish)

* New translations copy.resx (Spanish)

* New translations AppResources.resx (Spanish)

* New translations copy.resx (Japanese)

* New translations AppResources.resx (Japanese)

* New translations copy.resx (Bulgarian)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Danish)

* New translations copy.resx (Croatian)

* New translations copy.resx (Estonian)

* New translations copy.resx (Croatian)

* New translations AppResources.resx (Croatian)

* New translations copy.resx (Chinese Traditional)

* New translations copy.resx (Chinese Traditional)

* New translations AppResources.resx (Chinese Traditional)

* New translations copy.resx (Chinese Simplified)

* New translations copy.resx (Chinese Simplified)

* New translations AppResources.resx (Chinese Simplified)

* New translations copy.resx (Bulgarian)

* New translations AppResources.resx (Estonian)

* New translations copy.resx (Estonian)

* New translations AppResources.resx (Italian)

* New translations copy.resx (Indonesian)

* New translations copy.resx (Indonesian)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (Hindi)

* New translations copy.resx (German)

* New translations copy.resx (German)

* New translations AppResources.resx (German)

* New translations copy.resx (French)

* New translations copy.resx (French)

* New translations AppResources.resx (French)

* New translations copy.resx (Finnish)

* New translations copy.resx (Finnish)
2018-03-15 12:41:09 -04:00
Kyle Spearrin
5326c3aecc Match detection string 2018-03-15 10:37:08 -04:00
Kyle Spearrin
c95251c903 switch cell for fields, btn widths on ios too 2018-03-14 22:59:31 -04:00
Kyle Spearrin
e08a0a0938 cog alt buttons 2018-03-14 18:26:07 -04:00
Kyle Spearrin
fcb072c37d fix null ref when no uri 2018-03-14 17:41:18 -04:00
Kyle Spearrin
262c19b194 Change context options to action sheet w/ button 2018-03-13 17:33:45 -04:00
Kyle Spearrin
1031ddcd83 proper class on ExtendedViewCell 2018-03-12 22:46:46 -04:00
Kyle Spearrin
aaee0212f0 ios fixes 2018-03-12 15:42:53 -04:00
Kyle Spearrin
8fc95759ba support login uris from app extension 2018-03-12 13:29:12 -04:00
Kyle Spearrin
b6a3a0a54f noop on ios 2018-03-12 13:18:35 -04:00
Kyle Spearrin
e3091be314 Update ISSUE_TEMPLATE.md 2018-03-10 16:36:40 -05:00
Kyle Spearrin
045d0678b3 Create ISSUE_TEMPLATE.md 2018-03-10 09:47:52 -05:00
Kyle Spearrin
e3eeaddb3e normalize passwords 2018-03-09 22:29:59 -05:00
Kyle Spearrin
f2b202c714 only ignore vault.bitwarden.com 2018-03-08 10:34:07 -05:00
Kyle Spearrin
e6f3ad60ef move fields above attachments on view 2018-03-06 13:32:58 -05:00
Kyle Spearrin
fb6e0c9eb8 moved password generation link to button 2018-03-06 12:40:42 -05:00
Kyle Spearrin
fb6e488339 select URI match option from action sheet 2018-03-06 11:58:02 -05:00
Kyle Spearrin
0bccc8f0d5 loginUri no longer used 2018-03-06 08:51:05 -05:00
Kyle Spearrin
560d831e92 masked password string constant 2018-03-06 07:41:40 -05:00
Mark Cohen
7c8f6a1cc7 Don't leak password length through mask (#293) 2018-03-06 07:37:46 -05:00
Kyle Spearrin
deb1ead4ea trim Uri proper from stored json on save 2018-03-05 23:49:48 -05:00
Kyle Spearrin
005b2a4fb6 add support for uri match rules detection 2018-03-05 23:37:02 -05:00
Kyle Spearrin
4c8204f29a view/add/edit login uris 2018-03-05 22:39:56 -05:00
Kyle Spearrin
83fd19784a refactor for cipher model changes and multi-uris 2018-03-05 17:18:18 -05:00
Kyle Spearrin
1f21a2ecc7 add/edit/delete custom fields. remove field page. 2018-03-05 15:15:20 -05:00
Kyle Spearrin
c3f4d56d1e New Crowdin translations (#288)
* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations copy.resx (Russian)

* New translations AppResources.resx (Russian)

* New translations copy.resx (Romanian)

* New translations AppResources.resx (Romanian)

* New translations copy.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Slovak)

* New translations copy.resx (Portuguese)

* New translations AppResources.resx (Portuguese)

* New translations copy.resx (Polish)

* New translations AppResources.resx (Polish)

* New translations copy.resx (Norwegian Bokmal)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations copy.resx (Russian)

* New translations copy.resx (Slovak)

* New translations copy.resx (Japanese)

* New translations AppResources.resx (Turkish)

* New translations copy.resx (Vietnamese)

* New translations AppResources.resx (Vietnamese)

* New translations copy.resx (Ukrainian)

* New translations AppResources.resx (Ukrainian)

* New translations copy.resx (Turkish)

* New translations copy.resx (Thai)

* New translations copy.resx (Thai)

* New translations AppResources.resx (Thai)

* New translations copy.resx (Swedish)

* New translations AppResources.resx (Swedish)

* New translations copy.resx (Spanish)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Japanese)

* New translations copy.resx (Chinese Simplified)

* New translations AppResources.resx (Estonian)

* New translations copy.resx (Dutch)

* New translations AppResources.resx (Dutch)

* New translations copy.resx (Danish)

* New translations AppResources.resx (Danish)

* New translations copy.resx (Czech)

* New translations copy.resx (Estonian)

* New translations AppResources.resx (Czech)

* New translations copy.resx (Croatian)

* New translations AppResources.resx (Croatian)

* New translations copy.resx (Chinese Traditional)

* New translations copy.resx (Chinese Traditional)

* New translations AppResources.resx (Chinese Traditional)

* New translations copy.resx (Estonian)

* New translations AppResources.resx (Finnish)

* New translations copy.resx (Italian)

* New translations AppResources.resx (Italian)

* New translations copy.resx (Indonesian)

* New translations AppResources.resx (Indonesian)

* New translations copy.resx (Hungarian)

* New translations AppResources.resx (Hungarian)

* New translations copy.resx (Hindi)

* New translations copy.resx (Finnish)

* New translations AppResources.resx (Hindi)

* New translations copy.resx (German)

* New translations AppResources.resx (German)

* New translations copy.resx (French)

* New translations AppResources.resx (French)

* New translations copy.resx (Finnish)

* New translations copy.resx (Vietnamese)
2018-02-27 23:49:47 -05:00
Kyle Spearrin
7e4f79bacb uppercase Bitwarden 2018-02-27 13:37:46 -05:00
Kyle Spearrin
b8267d4329 Uppercase Bitwarden 2018-02-27 13:27:07 -05:00
Kyle Spearrin
205ca693b3 crowdin update_option: update_as_unapproved 2018-02-20 16:17:15 -05:00
Kyle Spearrin
23159c2201 catch ActivityNotFoundException with alert 2018-02-14 17:11:27 -05:00
Kyle Spearrin
884521ced0 premium message on attachments edit page 2018-02-12 08:54:31 -05:00
Kyle Spearrin
aeb01ba292 break if too many iterations 2018-02-10 09:39:45 -05:00
Kyle Spearrin
2b1a556e9e re-enable vs update 2018-02-10 09:38:12 -05:00
Kyle Spearrin
d5c3ae3d19 guard against infinite recursion and loops 2018-02-10 09:35:14 -05:00
Kyle Spearrin
7654bb7088 check if child is same as parent 2018-02-10 00:38:52 -05:00
Kyle Spearrin
64c301caeb password gen fixes 2018-02-09 22:02:56 -05:00
Kyle Spearrin
e875b530b1 bail out if recursiveIterations >= 100 2018-02-09 16:23:51 -05:00
Kyle Spearrin
ee8c2b5272 thread sleeps 2018-02-09 15:00:54 -05:00
Kyle Spearrin
9b8bdb0639 remove log spam 2018-02-09 14:02:17 -05:00
Kyle Spearrin
1a99bbb040 more log info 2018-02-08 22:08:00 -05:00
Kyle Spearrin
0982b45473 more log spam 2018-02-08 17:44:48 -05:00
Kyle Spearrin
bcd210d504 log spam 2018-02-08 17:27:56 -05:00
Kyle Spearrin
c71608824b fix null ref with e.source 2018-02-08 17:07:01 -05:00
Kyle Spearrin
170876ac16 event info logs 2018-02-08 16:36:49 -05:00
Kyle Spearrin
a6b172c445 log and throw accessibility exceptions 2018-02-08 16:33:52 -05:00
Kyle Spearrin
e625450100 disable vs update 2018-02-08 16:00:11 -05:00
Kyle Spearrin
fca5447094 revert accessibility throttling 2018-02-03 09:47:16 -05:00
Kyle Spearrin
89f32beec5 throttle accessibility events 2018-02-03 09:21:27 -05:00
Kyle Spearrin
65eb7662ad remove appveyor debugging. just update vs 2018-02-03 00:00:05 -05:00
Kyle Spearrin
ea090dbe18 just update 2018-02-02 23:48:46 -05:00
Kyle Spearrin
5750817620 quiet update with echos 2018-02-02 22:30:00 -05:00
Kyle Spearrin
93386d0e8b passive update 2018-02-02 22:23:39 -05:00
Kyle Spearrin
e9dd7b8f98 update vs 2018-02-02 22:19:36 -05:00
Kyle Spearrin
5010e7cb7a update visual studio manually 2018-02-02 22:00:58 -05:00
Kyle Spearrin
fb35f4fbca Previous Visual Studio 2017 2018-02-02 13:49:44 -05:00
Kyle Spearrin
00c0a93a6b revert preview image 2018-02-02 13:45:26 -05:00
Kyle Spearrin
cd9a312e0b use VS preview image 2018-02-02 13:38:49 -05:00
Kyle Spearrin
8cdb27fe43 check modal stack before popping 2018-02-01 23:38:18 -05:00
Kyle Spearrin
d84d11d064 update xamarin forms 2018-02-01 23:38:06 -05:00
Kyle Spearrin
5d646a6112 various android crash fixes 2018-02-01 23:25:48 -05:00
Kyle Spearrin
dd334858ff add timeout on timers 2018-02-01 21:20:35 -05:00
Kyle Spearrin
dfd39ebc95 check installed launchers to skip 2018-02-01 21:20:28 -05:00
Kyle Spearrin
9dbb1f15a4 filter nova prime 2018-02-01 17:26:41 -05:00
Kyle Spearrin
32fd04a7d9 more filters 2018-02-01 17:23:41 -05:00
Kyle Spearrin
3a33ff375d turn back on autofill stuff 2018-02-01 17:17:18 -05:00
Kyle Spearrin
8877e71bd2 add back SystemUiPackage 2018-02-01 17:01:37 -05:00
Kyle Spearrin
5b5385c01d add FilteredPackageNames 2018-02-01 16:56:54 -05:00
Kyle Spearrin
9c365ecc48 log events 2018-02-01 16:27:08 -05:00
Kyle Spearrin
99d1a6d043 read RootInActiveWindow after launcher checks 2018-02-01 16:12:30 -05:00
Kyle Spearrin
854ef7e645 log any exceptions 2018-02-01 15:54:39 -05:00
Kyle Spearrin
a8eeb12325 just read RootInActiveWindow 2018-02-01 15:42:07 -05:00
Kyle Spearrin
86a3f516b1 test: start processing some event info 2018-02-01 15:29:41 -05:00
Kyle Spearrin
d6818939b3 test: turn some things back on 2018-02-01 15:21:22 -05:00
Kyle Spearrin
c51449e607 test: dont even init appsettings 2018-02-01 15:03:44 -05:00
Kyle Spearrin
333894ddeb test: do nothing for autofill service 2018-02-01 15:00:43 -05:00
Kyle Spearrin
052e227b65 comment out test nodes 2018-02-01 14:31:53 -05:00
Kyle Spearrin
4dd6df5bbe set package and website independently 2018-01-26 12:15:54 -05:00
Kyle Spearrin
8847991bba show attachments properly if an organization 2018-01-26 11:48:43 -05:00
Kyle Spearrin
0ffc6e4a1a show attachments if premium or org item 2018-01-26 11:02:35 -05:00
Kyle Spearrin
9a399e06f3 decrypt attachment with org id 2018-01-26 09:13:30 -05:00
Kyle Spearrin
6afccc2aea add duckduckgo support 2018-01-26 08:56:43 -05:00
Kyle Spearrin
8cd3a21468 null and length check on name when sorting 2018-01-25 21:20:45 -05:00
Kyle Spearrin
8b6d2d2b83 comment typo 2018-01-25 09:07:19 -05:00
Kyle Spearrin
a39f4d5987 split by no-break space for yandex 2018-01-25 09:06:01 -05:00
Kyle Spearrin
e236d045b0 use MasterPasswordConfirmationValMessage 2018-01-24 20:21:54 -05:00
Alistair Francis
592c7951df UWP: Add a ExtendedTableViewRenderer (#260)
Add a base ExtendedTableViewRenderer we can use.

Signed-off-by: Alistair Francis <alistair@alistair23.me>
2018-01-19 14:04:58 -05:00
Kyle Spearrin
41efa96291 unsub from yubikey events on disappearing 2018-01-18 13:24:23 -05:00
Kyle Spearrin
53f406a267 log out after 5 failed pin attempts 2018-01-18 13:18:08 -05:00
Kyle Spearrin
1390df48b6 use random key for double hmac comparisons 2018-01-18 09:31:22 -05:00
Kyle Spearrin
01878ef00c check that mac always exists if key has MacKey 2018-01-18 08:39:34 -05:00
Kyle Spearrin
6f119f25f4 missing props on TokenCell 2018-01-18 08:09:18 -05:00
Alistair Francis
3f31d78db1 Add YubiKey keyboard support (#248)
* App: Pages: Fix the YubiKey image source

Signed-off-by: Alistair Francis <alistair@alistair23.me>

* App: Allow YubiKey keyboard output on apps

On Android and UWP it's possible to use the YubiKey to enter text
instead of using the NFC. Allow people to do that.

Signed-off-by: Alistair Francis <alistair@alistair23.me>

* App: Pages: Enable YubiKey support on Windows platforms

Windows platforms should always have YubiKey support.

Signed-off-by: Alistair Francis <alistair@alistair23.me>
2018-01-18 07:55:06 -05:00
Alistair Francis
014bf7777b Update some images (#257)
* UWP.Images: Update the launch.png image size

Signed-off-by: Alistair Francis <alistair@alistair23.me>

* App: Pages: Update login toolbar button

Signed-off-by: Alistair Francis <alistair@alistair23.me>
2018-01-17 08:29:59 -05:00
Kyle Spearrin
7191969e9c Update README.md 2018-01-14 21:43:25 -05:00
Kyle Spearrin
0950510526 scope if shorthand 2018-01-11 12:07:13 -05:00
Kyle Spearrin
9eba3064a7 formatting 2018-01-11 12:02:03 -05:00
Kyle Spearrin
a4d785258e build for configuration release 2018-01-11 09:04:58 -05:00
Kyle Spearrin
efef49f976 Revert "choose/when fdroid conditional on packages"
This reverts commit b3573f9482.
2018-01-11 09:03:05 -05:00
Kyle Spearrin
32a7b5bafb Revert "clean and rebuild FDroid"
This reverts commit 5fa080063c.
2018-01-11 09:00:29 -05:00
Kyle Spearrin
5fa080063c clean and rebuild FDroid 2018-01-11 08:52:47 -05:00
Kyle Spearrin
b3573f9482 choose/when fdroid conditional on packages 2018-01-11 08:36:37 -05:00
Kyle Spearrin
916b7ee46b reenc keystore 2018-01-10 23:26:44 -05:00
Kyle Spearrin
bfe8ad2034 quiet output 2018-01-10 23:00:10 -05:00
Kyle Spearrin
bb9db7bf9d full android project path 2018-01-10 22:36:51 -05:00
Kyle Spearrin
d7f7c8c568 build script fixes 2018-01-10 22:30:30 -05:00
Kyle Spearrin
10839588dd Invoke-Expression 2018-01-10 22:20:22 -05:00
Kyle Spearrin
12cd2b67cd ci build apks script 2018-01-10 22:10:32 -05:00
Kyle Spearrin
9a13036f4e fdroid-build script 2018-01-10 18:32:57 -05:00
Kyle Spearrin
2f025d51ff remove rdp from appveyor 2018-01-10 18:01:48 -05:00
Kyle Spearrin
6cb6d3a358 run nuget restore 2018-01-10 17:19:56 -05:00
Kyle Spearrin
0bb01d14bd clean fdroid 2018-01-10 16:53:09 -05:00
Kyle Spearrin
2229c4e4d1 enable rdp for appveyor debugging 2018-01-10 16:37:05 -05:00
Kyle Spearrin
5c90c62378 msbuild android proj only 2018-01-10 16:10:47 -05:00
Kyle Spearrin
b7ed0a29fe clean with msbuild 2018-01-10 15:55:07 -05:00
Kyle Spearrin
796c2ed58c build solution again for fdroid 2018-01-10 15:40:17 -05:00
Kyle Spearrin
39bd573d9d backup original csproj files and clean bin folders 2018-01-10 15:26:27 -05:00
Kyle Spearrin
d4aaa547a7 remove libs for fdroid build 2018-01-10 14:55:18 -05:00
Kyle Spearrin
f7e2382847 AndroidApkSigningAlgorithm of SHA1withRSA 2018-01-10 13:38:08 -05:00
Kyle Spearrin
4bb16e7d93 version bump 2018-01-10 12:18:48 -05:00
Kyle Spearrin
e7e00e4ebf add target framework to PropertyGroup conditional 2018-01-10 11:52:53 -05:00
Kyle Spearrin
55d050fca7 fdroid artifacts for build 2018-01-10 09:35:47 -05:00
Kyle Spearrin
98d4fef0ee fdroid builds without Google and Hockey services 2018-01-10 09:28:30 -05:00
Kyle Spearrin
5521892736 secure note option handled 2018-01-10 08:47:20 -05:00
Kyle Spearrin
8f0fd0dfef F-Droid build configuration 2018-01-10 00:41:29 -05:00
Kyle Spearrin
514eab0b98 Merge branch 'master' of github.com:bitwarden/mobile 2018-01-09 11:31:14 -05:00
Kyle Spearrin
e35c84245d added org.mozilla.klar to whitelist 2018-01-09 11:31:00 -05:00
Kyle Spearrin
4a2391eb1b New Crowdin translations (#247)
* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (French)

* New translations AppResources.resx (German)

* New translations copy.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Estonian)
2018-01-08 21:19:45 -05:00
Kyle Spearrin
04eb497e10 version bump 2018-01-08 21:17:05 -05:00
Kyle Spearrin
a9a5da6dc6 update ffimageloading lib 2018-01-08 11:51:23 -05:00
Kyle Spearrin
3f1aab27d6 android back on main pages goes to vault first 2018-01-08 11:33:51 -05:00
Kyle Spearrin
8f77df4ebb Don't animate loading alert 2018-01-08 09:10:58 -05:00
Alistair Francis
65a8b3fcd4 UWP.Images: Reduce the size of the camera icon (#245)
Signed-off-by: Alistair Francis <alistair@alistair23.me>
2018-01-05 16:33:34 -05:00
Alistair Francis
71dd4e512e App: Pages: Add a null check in OnSelectTemplate() (#243)
To avoid accessing a null poiter add a null check in OnSelectTemplate().

Signed-off-by: Alistair Francis <alistair@alistair23.me>
2018-01-04 23:33:10 -05:00
Alistair Francis
ca03a5ecf4 App: Controls: Improve the vault view images (#240)
* App: Controls: Improve the vault view images

Make the buttons smaller and ensure the background is transparent.

Signed-off-by: Alistair Francis <alistair@alistair23.me>

* UWP.Images: Use smaller size images

Signed-off-by: Alistair Francis <alistair@alistair23.me>

* UWP.Images: Remove unused image

Signed-off-by: Alistair Francis <alistair@alistair23.me>
2018-01-04 23:32:50 -05:00
Kyle Spearrin
694efb9508 unit FFImageLoading with fast renderer; TLS 1.2 2018-01-04 13:07:50 -05:00
Kyle Spearrin
c60a112039 update FFImageLoading and disable gifs on ios 2018-01-04 12:46:29 -05:00
Alistair Francis
c3570dd07a Improve the UWP toast notification colours (#239)
* UWP: Services: Improve the toast notifcation colours

This commit improves the toast notification colours and makes the
notification slightly transparent.

Signed-off-by: Alistair Francis <alistair@alistair23.me>

* UWP: Services: Remove the unused Alignment options

These Alignment options don't have an effect on UWP, so just remove
them.

Signed-off-by: Alistair Francis <alistair@alistair23.me>
2018-01-04 08:32:18 -05:00
Kyle Spearrin
b680b190d4 update app store screenshots 2018-01-03 17:07:47 -05:00
Kyle Spearrin
310d51d859 handle null conditions from action sheet 2018-01-03 17:07:33 -05:00
Kyle Spearrin
cf9e820227 version bump 2018-01-03 14:15:45 -05:00
Kyle Spearrin
b91d2f4fb1 always use CustomTableViewModelRenderer 2018-01-03 13:37:04 -05:00
Kyle Spearrin
9456f5dc31 redraw stack layouts on ios tableviews 2018-01-03 12:18:15 -05:00
Kyle Spearrin
fa9e22730a get rid of old refection and memory services 2018-01-02 16:41:06 -05:00
Kyle Spearrin
7261fd7ed9 version bump 2018-01-02 10:44:59 -05:00
Kyle Spearrin
ad9e5fbf07 appcompat fixes for android 4.4 2018-01-02 10:41:11 -05:00
300 changed files with 12969 additions and 6453 deletions

View File

@@ -6,7 +6,7 @@ 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).

5
ISSUE_TEMPLATE.md Normal file
View 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
-->

View File

@@ -2,24 +2,28 @@
[![Crowdin](https://d322cqt584bo4o.cloudfront.net/bitwarden-mobile/localized.svg)](https://crowdin.com/project/bitwarden-mobile)
[![Join the chat at https://gitter.im/bitwarden/Lobby](https://badges.gitter.im/bitwarden/Lobby.svg)](https://gitter.im/bitwarden/Lobby)
# 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://i.imgur.com/R7H2tkQ.png" alt="" width="300" height="533" /> <img src="https://i.imgur.com/3BO1Wcg.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

View File

@@ -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!

View File

@@ -1,21 +1,22 @@
install:
- appveyor DownloadFile https://dist.nuget.org/win-x86-commandline/latest/nuget.exe
#install:
# - 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"
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

View File

@@ -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
@@ -39,10 +35,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProjectSection
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 +54,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 +108,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 +165,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 +214,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 +261,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 +314,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 +336,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 +372,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 +432,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
@@ -439,8 +467,6 @@ 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}
EndGlobalSection

View File

@@ -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

Binary file not shown.

View File

@@ -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,8 @@
<ItemGroup>
<None Include="8bit.keystore.enc" />
<GoogleServicesJson Include="google-services.json" />
<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 +472,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,15 +857,18 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="SimpleInjector">
<Version>4.0.12</Version>
</PackageReference>
<PackageReference Include="Xamarin.Firebase.Messaging">
<Version>42.1021.1</Version>
</PackageReference>
<PackageReference Include="Xamarin.GooglePlayServices.Analytics">
<Version>42.1021.1</Version>
</PackageReference>
<PackageReference Include="SimpleInjector">
<Version>4.0.12</Version>
</PackageReference>
<PackageReference Include="Xamarin.Android.Support.v7.AppCompat">
<Version>25.4.0.2</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" />
@@ -884,5 +891,104 @@
<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>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
</Project>

View File

@@ -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")]

View File

@@ -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; }

View File

@@ -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" };
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,31 @@ 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);
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));
}
}
}

View File

@@ -14,7 +14,12 @@ namespace Bit.Android.Autofill
"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"
"com.amazon.cloud9","org.mozilla.klar", "com.duckduckgo.mobile.android"
};
public static HashSet<string> ExcludedPackageIds = new HashSet<string>
{
"android"
};
private readonly AssistStructure _structure;
@@ -87,32 +92,24 @@ namespace Bit.Android.Autofill
var node = _structure.GetWindowNodeAt(i);
ParseNode(node.RootViewNode);
}
if(!TrustedBrowsers.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 +118,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;
}
}
}
}

View File

@@ -6,10 +6,7 @@ using Android.Views;
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 string _lastQueriedUri;

View File

@@ -12,17 +12,18 @@ 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>
{
@@ -42,10 +43,11 @@ 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.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 +61,37 @@ 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")
}.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()
{
@@ -85,17 +112,20 @@ namespace Bit.Android
try
{
var root = RootInActiveWindow;
if(e == null || root == null || string.IsNullOrWhiteSpace(e.PackageName) ||
e.PackageName == SystemUiPackage || e.PackageName.Contains("launcher") ||
root.PackageName != e.PackageName)
if(SkipPackage(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 root = RootInActiveWindow;
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 +133,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 +440,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 +459,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)

View File

@@ -1,3 +1,4 @@
#if !FDROID
using System;
using Android.App;
using Android.Content;
@@ -21,3 +22,4 @@ namespace Bit.Android
}
}
}
#endif

View File

@@ -1,3 +1,4 @@
#if !FDROID
using System;
using Android.App;
using Android.Content;
@@ -40,3 +41,4 @@ namespace Bit.Android
}
}
}
#endif

View File

@@ -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

View File

@@ -21,10 +21,7 @@ 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";
@@ -61,8 +58,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);
@@ -137,7 +136,14 @@ namespace Bit.Android
if(Utilities.NfcEnabled())
{
MessagingCenter.Send(Xamarin.Forms.Application.Current, "ResumeYubiKey");
try
{
MessagingCenter.Send(Xamarin.Forms.Application.Current, "ResumeYubiKey");
}
catch(Exception e)
{
System.Diagnostics.Debug.WriteLine(e);
}
}
}

View File

@@ -13,7 +13,6 @@ 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;
@@ -102,7 +101,7 @@ namespace Bit.Android
public static void SetIoc(Application application)
{
Refractored.FabControl.Droid.FloatingActionButtonViewRenderer.Init();
CachedImageRenderer.Init();
CachedImageRenderer.Init(true);
ZXing.Net.Mobile.Forms.Android.Platform.Init();
CrossFingerprint.SetCurrentActivityResolver(() => CrossCurrentActivity.Current.Activity);
@@ -127,17 +126,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
@@ -162,8 +163,13 @@ namespace Bit.Android
container.RegisterSingleton(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));

View File

@@ -1,5 +1,5 @@
<?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">
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.x8bit.bitwarden" android:versionName="1.16.0" android:installLocation="auto" android:versionCode="502" xmlns:tools="http://schemas.android.com/tools">
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="23" />
<uses-permission android:name="android.permission.INTERNET" />
@@ -12,7 +12,8 @@
<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">
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.x8bit.bitwarden.fileprovider"
@@ -34,6 +35,6 @@
</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" />
</application>
</manifest>

View File

@@ -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("")]

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 738 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 804 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1005 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1017 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 590 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 941 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 583 B

View File

@@ -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" />

View File

@@ -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" />

View 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>

View 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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 941 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 896 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 608 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#3C8DBC</color>
</resources>

View File

@@ -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">

View File

@@ -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>

View File

@@ -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

View File

@@ -24,6 +24,7 @@ using Bit.Android.Autofill;
using System.Linq;
using Plugin.Settings.Abstractions;
using Android.Views.InputMethods;
using Android.Widget;
namespace Bit.Android.Services
{
@@ -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;
}
}
}

View File

@@ -1,4 +1,5 @@
using System;
#if !FDROID
using System;
using Bit.App;
using Bit.App.Abstractions;
using Plugin.Settings.Abstractions;
@@ -80,3 +81,4 @@ namespace Bit.Android.Services
}
}
}
#endif

View File

@@ -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;
}
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -38,7 +38,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 +50,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 +68,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;

View 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"

View File

@@ -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");

View File

@@ -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; }

View File

@@ -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);
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}

View File

@@ -5,8 +5,21 @@
<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>
<EmbeddedResource Remove="Resources\AppResources.fa.resx" />
</ItemGroup>
<ItemGroup>
<None Remove="Resources\public_suffix_list.dat" />
</ItemGroup>
@@ -25,8 +38,8 @@
<PackageReference Include="System.Net.Http" Version="4.3.3" />
<PackageReference Include="Xam.Plugin.Connectivity" Version="3.0.3" />
<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.3.4" />
<PackageReference Include="Xamarin.Forms" Version="2.5.0.122203" />
<PackageReference Include="XLabs.IoC" Version="2.0.5782" />
<PackageReference Include="ZXing.Net.Mobile.Forms" Version="2.1.47" />
</ItemGroup>

View File

@@ -45,6 +45,7 @@
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 int SelectFileRequestCode = 42;
public const int SelectFilePermissionRequestCode = 43;

View File

@@ -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()
{
if(_requireAuth && !_authService.IsAuthenticated)
{
Device.BeginInvokeOnMainThread(
() => Application.Current.MainPage = new ExtendedNavigationPage(new HomePage()));
}
if(_syncIndicator)
{
MessagingCenter.Subscribe<Application, bool>(Application.Current, "SyncCompleted",

View File

@@ -1,6 +1,6 @@
using Xamarin.Forms;
using XLabs.Ioc;
using Bit.App.Abstractions;
using System;
using System.Reflection;
namespace Bit.App.Controls
{
@@ -40,17 +40,41 @@ namespace Bit.App.Controls
public bool NoHeader { get; set; }
public bool NoFooter { get; set; }
public int BottomPadding { get; set; }
public Func<RedrawableStackLayout> WrappingStackLayout { get; set; }
protected override SizeRequest OnSizeRequest(double widthConstraint, double heightConstraint)
{
if(!VerticalOptions.Expands && Device.RuntimePlatform != Device.UWP)
{
var reflectionService = Resolver.Resolve<IReflectionService>();
var baseBaseOnSizeRequest = reflectionService.GetVisualElementOnSizeRequest(this);
return baseBaseOnSizeRequest(widthConstraint, heightConstraint);
var baseOnSizeRequest = GetVisualElementOnSizeRequest();
return baseOnSizeRequest(widthConstraint, heightConstraint);
}
return base.OnSizeRequest(widthConstraint, heightConstraint);
}
private Func<double, double, SizeRequest> GetVisualElementOnSizeRequest()
{
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>), this, pointer);
}
}
}

View File

@@ -6,10 +6,10 @@ namespace Bit.App.Controls
public class ExtendedViewCell : ViewCell
{
public static readonly BindableProperty BackgroundColorProperty =
BindableProperty.Create(nameof(BackgroundColor), typeof(Color), typeof(ExtendedTextCell), Color.White);
BindableProperty.Create(nameof(BackgroundColor), typeof(Color), typeof(ExtendedViewCell), Color.White);
public static readonly BindableProperty ShowDisclousureProperty =
BindableProperty.Create(nameof(ShowDisclousure), typeof(bool), typeof(ExtendedTextCell), false);
BindableProperty.Create(nameof(ShowDisclousure), typeof(bool), typeof(ExtendedViewCell), false);
public Color BackgroundColor
{

View File

@@ -1,6 +1,7 @@
using Bit.App.Abstractions;
using FFImageLoading.Forms;
using System;
using System.Collections.Generic;
using Xamarin.Forms;
using XLabs.Ioc;
@@ -10,6 +11,7 @@ namespace Bit.App.Controls
{
private VisualElement _nextElement;
private TapGestureRecognizer _tgr;
private StackLayout _buttonStackLayout = null;
public FormEntryCell(
string labelText,
@@ -19,7 +21,8 @@ namespace Bit.App.Controls
bool useLabelAsPlaceholder = false,
string imageSource = null,
Thickness? containerPadding = null,
bool useButton = false)
string button1 = null,
string button2 = null)
{
if(!useLabelAsPlaceholder)
{
@@ -82,6 +85,45 @@ namespace Bit.App.Controls
VerticalOptions = LayoutOptions.CenterAndExpand
};
if(!useLabelAsPlaceholder)
{
formStackLayout.Children.Add(Label);
}
formStackLayout.Children.Add(Entry);
imageStackLayout.Children.Add(formStackLayout);
if(!string.IsNullOrWhiteSpace(button1) || !string.IsNullOrWhiteSpace(button2))
{
_buttonStackLayout = new StackLayout
{
Orientation = StackOrientation.Horizontal,
VerticalOptions = LayoutOptions.CenterAndExpand,
Spacing = 5
};
imageStackLayout.Children.Add(_buttonStackLayout);
if(!string.IsNullOrWhiteSpace(button1))
{
Button1 = new ExtendedButton { Image = button1 };
_buttonStackLayout.Children.Add(Button1);
Button1.Padding = new Thickness(0);
Button1.BackgroundColor = Color.Transparent;
Button1.WidthRequest = 40;
Button1.VerticalOptions = LayoutOptions.FillAndExpand;
}
if(!string.IsNullOrWhiteSpace(button2))
{
Button2 = new ExtendedButton { Image = button2 };
_buttonStackLayout.Children.Add(Button2);
Button2.Padding = new Thickness(0);
Button2.BackgroundColor = Color.Transparent;
Button2.WidthRequest = 40;
Button2.VerticalOptions = LayoutOptions.FillAndExpand;
}
}
if(Device.RuntimePlatform == Device.Android)
{
var deviceInfo = Resolver.Resolve<IDeviceInfoService>();
@@ -106,25 +148,11 @@ namespace Bit.App.Controls
imageStackLayout.AdjustPaddingForDevice();
}
}
if(!useLabelAsPlaceholder)
else if(Device.RuntimePlatform == Device.UWP)
{
formStackLayout.Children.Add(Label);
}
formStackLayout.Children.Add(Entry);
imageStackLayout.Children.Add(formStackLayout);
if(useButton)
{
Button = new ExtendedButton();
imageStackLayout.Children.Add(Button);
if(Device.RuntimePlatform == Device.Android)
if(_buttonStackLayout != null)
{
Button.Padding = new Thickness(0);
Button.BackgroundColor = Color.Transparent;
Button.WidthRequest = 40;
_buttonStackLayout.Spacing = 0;
}
}
@@ -133,7 +161,8 @@ namespace Bit.App.Controls
public Label Label { get; private set; }
public ExtendedEntry Entry { get; private set; }
public ExtendedButton Button { get; private set; }
public ExtendedButton Button1 { get; private set; }
public ExtendedButton Button2 { get; private set; }
public VisualElement NextElement
{
get => _nextElement;
@@ -150,6 +179,7 @@ namespace Bit.App.Controls
}
}
}
public Dictionary<string, object> MetaData { get; set; }
public void InitEvents()
{

View File

@@ -0,0 +1,47 @@
using Xamarin.Forms;
namespace Bit.App.Controls
{
public class FormSwitchCell : ExtendedViewCell
{
public FormSwitchCell(string labelText, string button1 = null)
{
Label = new Label
{
Text = labelText,
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalTextAlignment = TextAlignment.Center,
TextColor = Color.Black,
FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label)),
};
Switch = new Switch
{
VerticalOptions = LayoutOptions.Center
};
var stackLayout = new StackLayout
{
Padding = new Thickness(15, 5),
Orientation = StackOrientation.Horizontal,
Children = { Label, Switch }
};
stackLayout.AdjustPaddingForDevice();
if(!string.IsNullOrWhiteSpace(button1))
{
Button1 = new ExtendedButton { Image = button1 };
stackLayout.Children.Add(Button1);
Button1.BackgroundColor = Color.Transparent;
Button1.Padding = new Thickness(0);
Button1.WidthRequest = 40;
Button1.VerticalOptions = LayoutOptions.FillAndExpand;
}
View = stackLayout;
}
public Switch Switch { get; private set; }
public Label Label { get; set; }
public ExtendedButton Button1 { get; set; }
}
}

View File

@@ -54,7 +54,8 @@ namespace Bit.App.Controls
var buttonStackLayout = new StackLayout
{
Orientation = StackOrientation.Horizontal,
VerticalOptions = LayoutOptions.CenterAndExpand
VerticalOptions = LayoutOptions.CenterAndExpand,
Spacing = 5
};
if(subText != null)
@@ -75,8 +76,11 @@ namespace Bit.App.Controls
{
Image = button1Image,
HorizontalOptions = LayoutOptions.End,
VerticalOptions = LayoutOptions.Center,
Margin = new Thickness(0)
VerticalOptions = LayoutOptions.FillAndExpand,
Margin = new Thickness(0),
Padding = new Thickness(0),
BackgroundColor = Color.Transparent,
WidthRequest = 40
};
buttonStackLayout.Children.Add(Button1);
@@ -88,8 +92,11 @@ namespace Bit.App.Controls
{
Image = button2Image,
HorizontalOptions = LayoutOptions.End,
VerticalOptions = LayoutOptions.Center,
Margin = new Thickness(0)
VerticalOptions = LayoutOptions.FillAndExpand,
Margin = new Thickness(0),
Padding = new Thickness(0),
BackgroundColor = Color.Transparent,
WidthRequest = 40
};
buttonStackLayout.Children.Add(Button2);
@@ -97,22 +104,20 @@ namespace Bit.App.Controls
if(Device.RuntimePlatform == Device.Android)
{
buttonStackLayout.Spacing = 5;
containerStackLayout.AdjustPaddingForDevice();
}
else if(Device.RuntimePlatform == Device.UWP)
{
buttonStackLayout.Spacing = 0;
if(Button1 != null)
{
Button1.Padding = new Thickness(0);
Button1.BackgroundColor = Color.Transparent;
Button1.WidthRequest = 40;
}
if(Button2 != null)
{
Button2.Padding = new Thickness(0);
Button2.BackgroundColor = Color.Transparent;
Button2.WidthRequest = 40;
}
containerStackLayout.AdjustPaddingForDevice();
}
if(Sub != null && Button1 != null)

View File

@@ -1,108 +0,0 @@
using Bit.App.Abstractions;
using System;
using Xamarin.Forms;
using XLabs.Ioc;
namespace Bit.App.Controls
{
public class MemoryContentView : ContentView
{
private readonly IMemoryService _memoryService;
public MemoryContentView()
{
_memoryService = Resolver.Resolve<IMemoryService>();
var grid = new Grid
{
Padding = 5,
BackgroundColor = Color.White,
RowDefinitions = new RowDefinitionCollection
{
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Auto }
},
ColumnDefinitions = new ColumnDefinitionCollection
{
new ColumnDefinition { Width = GridLength.Star },
new ColumnDefinition { Width = GridLength.Star }
}
};
grid.Children.Add(new Label { Text = "Used Memory:" }, 0, 0);
grid.Children.Add(new Label { Text = "Free Memory:" }, 0, 1);
grid.Children.Add(new Label { Text = "Heap Memory:" }, 0, 2);
grid.Children.Add(new Label { Text = "Max Memory:" }, 0, 3);
grid.Children.Add(new Label { Text = "% Used Heap:" }, 0, 4);
grid.Children.Add(new Label { Text = "% Used Max:" }, 0, 5);
UsedMemory = new Label { Text = "Used Memory:", HorizontalTextAlignment = TextAlignment.End };
FreeMemory = new Label { Text = "Free Memory:", HorizontalTextAlignment = TextAlignment.End };
HeapMemory = new Label { Text = "Heap Memory:", HorizontalTextAlignment = TextAlignment.End };
MaxMemory = new Label { Text = "Max Memory:", HorizontalTextAlignment = TextAlignment.End };
HeapUsage = new Label { Text = "% Used Heap:", HorizontalTextAlignment = TextAlignment.End };
TotalUsage = new Label { Text = "% Used Max:", HorizontalTextAlignment = TextAlignment.End };
grid.Children.Add(UsedMemory, 1, 0);
grid.Children.Add(FreeMemory, 1, 1);
grid.Children.Add(HeapMemory, 1, 2);
grid.Children.Add(MaxMemory, 1, 3);
grid.Children.Add(HeapUsage, 1, 4);
grid.Children.Add(TotalUsage, 1, 5);
var button = new ExtendedButton { Text = "Refresh", BackgroundColor = Color.Transparent };
button.Clicked += Button_Clicked;
grid.Children.Add(button, 0, 6);
Grid.SetColumnSpan(button, 2);
Content = grid;
RefreshScreen();
}
private void Button_Clicked(object sender, EventArgs e)
{
RefreshScreen();
}
public Label UsedMemory { get; set; }
public Label FreeMemory { get; set; }
public Label HeapMemory { get; set; }
public Label MaxMemory { get; set; }
public Label HeapUsage { get; set; }
public Label TotalUsage { get; set; }
void RefreshScreen()
{
UsedMemory.Text = FreeMemory.Text = HeapMemory.Text = MaxMemory.Text =
HeapUsage.Text = TotalUsage.Text = string.Empty;
UsedMemory.TextColor = FreeMemory.TextColor = HeapMemory.TextColor =
MaxMemory.TextColor = HeapUsage.TextColor = TotalUsage.TextColor = Color.Black;
if(_memoryService != null)
{
var info = _memoryService.GetInfo();
if(info != null)
{
UsedMemory.Text = string.Format("{0:N} mb", Math.Round(info.UsedMemory / 1024 / 1024D, 2));
FreeMemory.Text = string.Format("{0:N} mb", Math.Round(info.FreeMemory / 1024 / 1024D, 2));
HeapMemory.Text = string.Format("{0:N} mb", Math.Round(info.TotalMemory / 1024 / 1024D, 2));
MaxMemory.Text = string.Format("{0:N} mb", Math.Round(info.MaxMemory / 1024 / 1024D, 2));
HeapUsage.Text = string.Format("{0:P}", info.HeapUsage());
TotalUsage.Text = string.Format("{0:P}", info.Usage());
if(info.Usage() > 0.8)
{
FreeMemory.TextColor = UsedMemory.TextColor = TotalUsage.TextColor = Color.Red;
}
}
}
}
}
}

View File

@@ -0,0 +1,27 @@
using System;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace Bit.App.Controls
{
public class RedrawableStackLayout : StackLayout
{
private DateTime _lastRedraw = DateTime.MinValue;
private TimeSpan _redrawThreshold = TimeSpan.FromMilliseconds(1000);
public async Task RedrawIfNeededAsync(int delay = 0, bool force = false)
{
var now = DateTime.UtcNow;
if(Device.RuntimePlatform == Device.iOS && (force || (now - _lastRedraw) > _redrawThreshold))
{
_lastRedraw = now;
if(delay > 0)
{
await Task.Delay(delay);
}
InvalidateLayout();
}
}
}
}

View File

@@ -7,6 +7,7 @@
Duo = 2,
YubiKey = 3,
U2f = 4,
Remember = 5
Remember = 5,
OrganizationDuo = 6
}
}

View File

@@ -0,0 +1,12 @@
namespace Bit.App.Enums
{
public enum UriMatchType : byte
{
Domain = 0,
Host = 1,
StartsWith = 2,
Exact = 3,
RegularExpression = 4,
Never = 5
}
}

View File

@@ -1,12 +0,0 @@
namespace Bit.App.Models.Api
{
public class CardDataModel : CipherDataModel
{
public string CardholderName { get; set; }
public string Brand { get; set; }
public string Number { get; set; }
public string ExpMonth { get; set; }
public string ExpYear { get; set; }
public string Code { get; set; }
}
}

View File

@@ -0,0 +1,24 @@
namespace Bit.App.Models.Api
{
public class CardType
{
public CardType() { }
public CardType(Cipher cipher)
{
CardholderName = cipher.Card.CardholderName?.EncryptedString;
Brand = cipher.Card.Brand?.EncryptedString;
Number = cipher.Card.Number?.EncryptedString;
ExpMonth = cipher.Card.ExpMonth?.EncryptedString;
ExpYear = cipher.Card.ExpYear?.EncryptedString;
Code = cipher.Card.Code?.EncryptedString;
}
public string CardholderName { get; set; }
public string Brand { get; set; }
public string Number { get; set; }
public string ExpMonth { get; set; }
public string ExpYear { get; set; }
public string Code { get; set; }
}
}

View File

@@ -1,11 +0,0 @@
using System.Collections.Generic;
namespace Bit.App.Models.Api
{
public abstract class CipherDataModel
{
public string Name { get; set; }
public string Notes { get; set; }
public IEnumerable<FieldDataModel> Fields { get; set; }
}
}

View File

@@ -1,11 +0,0 @@
using Bit.App.Enums;
namespace Bit.App.Models.Api
{
public class FieldDataModel
{
public FieldType Type { get; set; }
public string Name { get; set; }
public string Value { get; set; }
}
}

View File

@@ -0,0 +1,18 @@
namespace Bit.App.Models.Api
{
public class FieldType
{
public FieldType() { }
public FieldType(Field field)
{
Type = field.Type;
Name = field.Name?.EncryptedString;
Value = field.Value?.EncryptedString;
}
public Enums.FieldType Type { get; set; }
public string Name { get; set; }
public string Value { get; set; }
}
}

View File

@@ -1,24 +0,0 @@
namespace Bit.App.Models.Api
{
public class IdentityDataModel : CipherDataModel
{
public string Title { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string Address3 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string PostalCode { get; set; }
public string Country { get; set; }
public string Company { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public string SSN { get; set; }
public string Username { get; set; }
public string PassportNumber { get; set; }
public string LicenseNumber { get; set; }
}
}

View File

@@ -0,0 +1,48 @@
namespace Bit.App.Models.Api
{
public class IdentityType
{
public IdentityType() { }
public IdentityType(Cipher cipher)
{
Title = cipher.Identity.Title?.EncryptedString;
FirstName = cipher.Identity.FirstName?.EncryptedString;
MiddleName = cipher.Identity.MiddleName?.EncryptedString;
LastName = cipher.Identity.LastName?.EncryptedString;
Address1 = cipher.Identity.Address1?.EncryptedString;
Address2 = cipher.Identity.Address2?.EncryptedString;
Address3 = cipher.Identity.Address3?.EncryptedString;
City = cipher.Identity.City?.EncryptedString;
State = cipher.Identity.State?.EncryptedString;
PostalCode = cipher.Identity.PostalCode?.EncryptedString;
Country = cipher.Identity.Country?.EncryptedString;
Company = cipher.Identity.Company?.EncryptedString;
Email = cipher.Identity.Email?.EncryptedString;
Phone = cipher.Identity.Phone?.EncryptedString;
SSN = cipher.Identity.SSN?.EncryptedString;
Username = cipher.Identity.Username?.EncryptedString;
PassportNumber = cipher.Identity.PassportNumber?.EncryptedString;
LicenseNumber = cipher.Identity.LicenseNumber?.EncryptedString;
}
public string Title { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string Address3 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string PostalCode { get; set; }
public string Country { get; set; }
public string Company { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public string SSN { get; set; }
public string Username { get; set; }
public string PassportNumber { get; set; }
public string LicenseNumber { get; set; }
}
}

View File

@@ -1,10 +0,0 @@
namespace Bit.App.Models.Api
{
public class LoginDataModel : CipherDataModel
{
public string Uri { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string Totp { get; set; }
}
}

View File

@@ -0,0 +1,24 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace Bit.App.Models.Api
{
public class LoginType
{
public LoginType() { }
public LoginType(Cipher cipher)
{
Uris = cipher.Login.Uris?.Select(u => new LoginUriType(u));
Username = cipher.Login.Username?.EncryptedString;
Password = cipher.Login.Password?.EncryptedString;
Totp = cipher.Login.Totp?.EncryptedString;
}
public IEnumerable<LoginUriType> Uris { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string Totp { get; set; }
}
}

View File

@@ -0,0 +1,18 @@
using Bit.App.Enums;
namespace Bit.App.Models.Api
{
public class LoginUriType
{
public LoginUriType() { }
public LoginUriType(LoginUri u)
{
Uri = u.Uri?.EncryptedString;
Match = u.Match;
}
public string Uri { get; set; }
public UriMatchType? Match { get; set; }
}
}

View File

@@ -17,12 +17,7 @@ namespace Bit.App.Models.Api
if(cipher.Fields != null)
{
Fields = cipher.Fields.Select(f => new FieldDataModel
{
Name = f.Name?.EncryptedString,
Value = f.Value?.EncryptedString,
Type = f.Type
});
Fields = cipher.Fields.Select(f => new FieldType(f));
}
switch(Type)
@@ -50,101 +45,11 @@ namespace Bit.App.Models.Api
public bool Favorite { get; set; }
public string Name { get; set; }
public string Notes { get; set; }
public IEnumerable<FieldDataModel> Fields { get; set; }
public IEnumerable<FieldType> Fields { get; set; }
public LoginType Login { get; set; }
public CardType Card { get; set; }
public IdentityType Identity { get; set; }
public SecureNoteType SecureNote { get; set; }
public class LoginType
{
public LoginType(Cipher cipher)
{
Uri = cipher.Login.Uri?.EncryptedString;
Username = cipher.Login.Username?.EncryptedString;
Password = cipher.Login.Password?.EncryptedString;
Totp = cipher.Login.Totp?.EncryptedString;
}
public string Uri { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string Totp { get; set; }
}
public class CardType
{
public CardType(Cipher cipher)
{
CardholderName = cipher.Card.CardholderName?.EncryptedString;
Brand = cipher.Card.Brand?.EncryptedString;
Number = cipher.Card.Number?.EncryptedString;
ExpMonth = cipher.Card.ExpMonth?.EncryptedString;
ExpYear = cipher.Card.ExpYear?.EncryptedString;
Code = cipher.Card.Code?.EncryptedString;
}
public string CardholderName { get; set; }
public string Brand { get; set; }
public string Number { get; set; }
public string ExpMonth { get; set; }
public string ExpYear { get; set; }
public string Code { get; set; }
}
public class IdentityType
{
public IdentityType(Cipher cipher)
{
Title = cipher.Identity.Title?.EncryptedString;
FirstName = cipher.Identity.FirstName?.EncryptedString;
MiddleName = cipher.Identity.MiddleName?.EncryptedString;
LastName = cipher.Identity.LastName?.EncryptedString;
Address1 = cipher.Identity.Address1?.EncryptedString;
Address2 = cipher.Identity.Address2?.EncryptedString;
Address3 = cipher.Identity.Address3?.EncryptedString;
City = cipher.Identity.City?.EncryptedString;
State = cipher.Identity.State?.EncryptedString;
PostalCode = cipher.Identity.PostalCode?.EncryptedString;
Country = cipher.Identity.Country?.EncryptedString;
Company = cipher.Identity.Company?.EncryptedString;
Email = cipher.Identity.Email?.EncryptedString;
Phone = cipher.Identity.Phone?.EncryptedString;
SSN = cipher.Identity.SSN?.EncryptedString;
Username = cipher.Identity.Username?.EncryptedString;
PassportNumber = cipher.Identity.PassportNumber?.EncryptedString;
LicenseNumber = cipher.Identity.LicenseNumber?.EncryptedString;
}
public string Title { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string Address3 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string PostalCode { get; set; }
public string Country { get; set; }
public string Company { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public string SSN { get; set; }
public string Username { get; set; }
public string PassportNumber { get; set; }
public string LicenseNumber { get; set; }
}
public class SecureNoteType
{
public SecureNoteType(Cipher cipher)
{
Type = cipher.SecureNote.Type;
}
public Enums.SecureNoteType Type { get; set; }
}
}
}

View File

@@ -1,6 +1,5 @@
using Bit.App.Enums;
using System;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
namespace Bit.App.Models.Api
@@ -15,7 +14,13 @@ namespace Bit.App.Models.Api
public bool Favorite { get; set; }
public bool Edit { get; set; }
public bool OrganizationUseTotp { get; set; }
public JObject Data { get; set; }
public string Name { get; set; }
public string Notes { get; set; }
public LoginType Login { get; set; }
public CardType Card { get; set; }
public IdentityType Identity { get; set; }
public SecureNoteType SecureNote { get; set; }
public IEnumerable<FieldType> Fields { get; set; }
public IEnumerable<AttachmentResponse> Attachments { get; set; }
public IEnumerable<string> CollectionIds { get; set; }
public DateTime RevisionDate { get; set; }

View File

@@ -1,9 +0,0 @@
using Bit.App.Enums;
namespace Bit.App.Models.Api
{
public class SecureNoteDataModel : CipherDataModel
{
public SecureNoteType Type { get; set; }
}
}

View File

@@ -0,0 +1,14 @@
namespace Bit.App.Models.Api
{
public class SecureNoteType
{
public SecureNoteType() { }
public SecureNoteType(Cipher cipher)
{
Type = cipher.SecureNote.Type;
}
public Enums.SecureNoteType Type { get; set; }
}
}

View File

@@ -1,6 +1,6 @@
using Bit.App.Models.Api;
using Bit.App.Models.Data;
using Bit.App.Models.Data;
using Newtonsoft.Json;
using System;
namespace Bit.App.Models
{
@@ -10,7 +10,19 @@ namespace Bit.App.Models
public Card(CipherData data)
{
var deserializedData = JsonConvert.DeserializeObject<CardDataModel>(data.Data);
CardDataModel deserializedData;
if(data.Card != null)
{
deserializedData = JsonConvert.DeserializeObject<CardDataModel>(data.Card);
}
else if(data.Data != null)
{
deserializedData = JsonConvert.DeserializeObject<CardDataModel>(data.Data);
}
else
{
throw new ArgumentNullException(nameof(data.Card));
}
CardholderName = deserializedData.CardholderName != null ?
new CipherString(deserializedData.CardholderName) : null;

View File

@@ -1,5 +1,4 @@
using Bit.App.Enums;
using Bit.App.Models.Api;
using Bit.App.Models.Data;
using Newtonsoft.Json;
using System.Collections.Generic;

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