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

Compare commits

...

1979 Commits

Author SHA1 Message Date
Todd Martin
3e9d3787d8 Removed check for OS type before setting current push token on state. 2022-11-13 10:42:18 -05:00
Todd Martin
5b53c0c48f Added code to update PushToken that is used on login.
(cherry picked from commit 264b6791372b6a5d6c8c4f9e3c7e393b3ec4392b)
2022-11-13 10:27:29 -05:00
André Bispo
7e8e86a77a [SG-813] Not You? crashes app after vault logout timeout (#2184)
* Merge branch 'master' into feature/SG-174-login-with-device

* [SG-813] Fix merge

* [SG-813] rename HomePage parameter name

* [SG-813] Added NavParams for home page on account switching.

* [SG-813] Remove account showing when adding new account.

* [SG-813] Add account switch pop up if email already exists

* [SG-813] Add default account avatar to HomePage

* [SG-813] Code format

* [SG-813] Remove unused import

* [SG-813] Renamed checkNavigateLogin to shouldCheckRememberEmail

* [SG-813] Move prompt account switch to account manager service

* [SG-813] Remove Account button appears if email is the same as the ActiveUser

* [SG-813] Fix code duplicate

* [SG-813] Fix for android RemoveAccount button

* [SG-813] Code format
2022-11-11 18:14:30 +00:00
Robyn MacCallum
20c1e2d7f2 Add syncCompleted to check to get passwordless requests (#2186) 2022-11-11 12:33:17 -05:00
github-actions[bot]
7870c2706b Autosync the updated translations (#2185)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2022-11-11 12:34:15 +01:00
Patrick
5a5f50605b Update AppResources.resx (#2181) 2022-11-10 13:44:18 -05:00
Robyn MacCallum
0106732cbd [SG-808] Only show 'remove account' option if user is in Accounts list (#2179)
* Only show 'remove account' option if user is in Accounts list

* Condense existing email logic

* Add line break

* Condense to local variable

* Cleanup spacing
2022-11-10 07:06:17 -05:00
André Bispo
9ae269dd57 [SG-174] Login with Device Request - Mobile (#2167)
* [SG-174] Add new login request services to Api

* [SG-174] Fix typo

* [SG-174] Enable login with device button.

* [SG-174] Add new login request page and viewmodel

* [SG-174] Add new text resources

* [SG-174] Add new RSA Decrypt method with string param

* [SG-174] Change create login request method

* [SG-174] Add new method to auth service to login passwordless

* [SG-174] Refactor login helper method to work with passwordless

* [SG-174] Fix service registration

* [SG-174] Update token request to support passwordless

* [SG-174] Update Api service with passwordless methods

* [SG-174] Fix App csproj references

* [SG-174] Remove unnecessary argument

* [SG-174] dotnet format

* [SG-174] Fixed iOS Extensions

* [SG-174] Change Command to ICommand

* [SG-174] Change Gesture Recognizer to Command

* [SG-174] Fix close action

* [SG-174] Code format

* [SG-174] Fix android frame shadow bug

* [SG-174] PR fixes
2022-11-09 16:25:48 +00:00
Opeyemi
04ed47d545 Devops 1039 update release flow dry run step names (#2177) 2022-11-08 22:44:50 +00:00
Opeyemi
6160535c03 add run-name for release to include workflow trigger (#2174) 2022-11-08 20:27:22 +00:00
André Bispo
8d92373c88 [SG-806] add try catch on initAsync (#2173) 2022-11-07 13:41:02 +00:00
André Bispo
6bfc8f7d49 [SG-802] Add if check on notification tap. (#2172) 2022-11-07 13:40:48 +00:00
André Bispo
69f02eef82 [SG-800] Selecting notification for inactive account on iOS while app is open does not display the request (#2166)
* [SG-800] Remove await from ActionSheet
If the user never answers the pop up, the lock is never released.

* [SG-800] Add try catch
2022-11-04 16:54:16 +00:00
github-actions[bot]
02b8e54988 Autosync the updated translations (#2165)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2022-11-04 08:11:43 +01:00
Álison Fernandes
99472d2548 [EC-655] Adds build variants to the mobile codebase using a CAKE script (#2161)
* Implemented CAKE build script

* cake script now deals with all of iOS's .plists

* cake now updates iOS bundleid's / Android packagename in codefiles

* iOS Bundle ID / Name should be correctly handled now + refactor

* tabs -> spaces

* Additional code files are now handled by cake

* Additional iOS codefile changes required

* Android's Autofill Label is now changed

* Removed dash from packagenames / bundleIDs

* Fixed CFBundleURLName set

* Added google-services.json to cake preprocessing

* Add CAKE to build workflow
- Android

* Add debug

* Updated cake's GitVersion.Tool

* AndroidManifest manual parsing needs to happen first

* Added Android Constants to build.cake

* [SG-747] Add Android QA build to mobile build pipeline (#2144)

* Add checkout depth

* Build and upload QA artifacts

* Remove missing .aab

* Update build.yml

* Update paths

* Update var names

* Build and upload QA artifacts

* Add in matrix to path.

* Lets not fail all the jobs if something pukes

* Add in some flow logic for QA

* We need strings in pwsh

* Remove extra quotes

* Testing, remove uneeded runs

* Test folder items

* [SG-747] Added more debug info to find problem

* [SG-747] copy signed apk to correct file name for each app variant

* [SG-747] try to fix if statement

* [SG-747] separate decrypt google services into another step with condition.

* [SG-747] fixed typo and line break

* [SG-747] added debug to check output path

* [SG-747] fix package name

* [SG-747] Fixed condition of step execution

* [SG-747] test if cases

* [SG-747] Code clean up

* [SG-747] Added FDroid and iOS steps.

* [SG-747] Removed test step

* [SG-747] Step name changes

* Update condition to be more inclusive

Co-authored-by: Álison Fernandes <vvolkgang@users.noreply.github.com>

* [SG-747] Expand if condition to allow more build types other than QA

* [SG-747] removed execution condition

Co-authored-by: mimartin12 <77340197+mimartin12@users.noreply.github.com>

* Apply suggestions from code review

Linter suggestions

Co-authored-by: mimartin12 <77340197+mimartin12@users.noreply.github.com>
Co-authored-by: Micaiah Martin <mmartin@bitwarden.com>
Co-authored-by: mimartin12 <77340197+mimartin12@users.noreply.github.com>
Co-authored-by: Álison Fernandes <vvolkgang@users.noreply.github.com>
Co-authored-by: Todd Martin <106564991+trmartin4@users.noreply.github.com>

* Base bundle ID refactor and cleaned up TODOs

- Added base vars for the bundle IDs
- Removed a TODO and explained the remaining ones
- Commented a unused var, keeping it in the code as this might be useful later

Co-authored-by: Micaiah Martin <mmartin@bitwarden.com>
Co-authored-by: Federico Andrés Maccaroni <fedemkr@gmail.com>
Co-authored-by: Todd Martin <tmartin@bitwarden.com>
Co-authored-by: André Bispo <abispo@bitwarden.com>
Co-authored-by: mimartin12 <77340197+mimartin12@users.noreply.github.com>
Co-authored-by: Todd Martin <106564991+trmartin4@users.noreply.github.com>
2022-11-01 22:14:49 +00:00
Carlos Gonçalves
5a4c81bd75 SG-769 - Ensured token for decoding is refreshed before use (#2150) 2022-10-31 15:46:10 -04:00
Carlos Gonçalves
ee09c0abda SG-786 - Fix 400 error code log outs without invalid_grant (#2156)
* SG-786 - Added validation to check if the 400 error is invalid grant

* SG 786 - Improved code quality
2022-10-31 13:40:26 -04:00
André Bispo
9baa79e10b [SG-773][SG-775] Duplicate passwordless login requests (#2160)
* [SG-773] Change method call to message send

* [SG-773] Introduce lock to avoid concurrent executions of login requests

* [SG-773][SG-775] add comment

* [SSG-773][SG-775] Refactor passwordlessLoginRequest string to constant
2022-10-31 15:57:09 +00:00
André Bispo
a8909a3ce6 [SG-765] Add cancel button to passwordless login modal on android (#2159) 2022-10-31 15:06:37 +00:00
André Bispo
b9b9c2e5ff [SG-166] Two Step Login - Feature Branch (#2157)
* [SG-166] Update fonts to have necessary icons

* [SG-166] Add new custom view to hold a button with a font icon and a label.

* [SG-166] Two Step login flow - Mobile (#2153)

* [SG-166] Add UI elements to Home and Login pages. Change VMs to function with new UI. Add new string resources.

* [SG-166] Pass email parameter from Home to Login page.

* [SG-166] Pass email to password hint page.

* [SG-166] Remove remembered email from account switching.

* [SG-166] Add GetKnownDevice endpoint to ApiService

* [SG-166] Fix GetKnownDevice string uri

* [SG-166] Add Renderer for IconLabel control. Add RemoveFontPadding bool property.

* [SG-166] include IconLabelRenderer in Android csproj file

* [SG-166] Add new control. Add styles for the control.

* [SG-166] Add verification to start login if email is remembered

* [SG-166] Pass default email to hint page

* [SG-166] Login with device button only shows if it is a known device.

* [SG-166] Change Remember Email to Remember me. Change Check to Switch control.

* [SG-166] Add command to button for SSO Login

* Revert "[SG-166] Update fonts to have necessary icons"

This reverts commit 472b541cef.

* [SG-166] Remove IconLabel Android renderer. Add RemoveFontPadding effect.

* [SG-166] Update font with new device and suitcase icon

* [SG-166] Fix RemoveFontPadding effect

* [SG-166] Remove unused property in IconLabel

* [SG-166] Fix formatting on IconLabelButton.xaml

* [SG-166] Update padding effect to IconLabel

* [SG-166] Add control variable to run code once on create

* [SG-166] Add email validation before continue

* [SG-166] Refactor icons

* [SG-166] Update iOS Extension font

* [SG-166] Remove HomePage login btn step

* [SG-166] Make clickable area smaller

* [SG-166] Fix hint filled by default

* [SG-166] Fix IconButton font issue

* [SG-166] Fix iOS extension

* [SG-166] Move style to Base instead of platforms

* [SG-166] Fix layout for IconLabelButton

* [SG-166] Switched EventHandler for Command

* [SG-166] Removed event handler

* [SG-166] Fix LoginPage layout options

* [SG-166] Fix extensions Login null email

* [SG-166] Move remembered email logic to viewmodel

* [SG-166] Protect method and show dialog in case of error

* [SG-166] Rename of GetKnownDevice api method

* [SG-166] rename text resource key name

* [SG-166] Add close button to iOS extension

* [SG-166] Switch event handlers for commands

* [SG-166] Change commands UI thread invocation.

* [SG-166] Remove Login with device button from the UI

* [SG-166] Fixed appOptions and close button on iOS Extensions
2022-10-28 23:10:41 +01:00
github-actions[bot]
89adab6784 Autosync the updated translations (#2155)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2022-10-28 02:40:47 +02:00
mp-bw
77d8afcfe6 added missing id check to obj comparison (#2154) 2022-10-27 12:09:33 -04:00
Michał Chęciński
4fcb063190 Move renovate.json to .github folder (#2152) 2022-10-27 15:49:29 +02:00
mp-bw
5deba15373 Updated avatar color selection logic (#2151)
* updated avatar color selection logic

* tweaks

* more tweaks

* formatting
2022-10-26 12:34:54 -04:00
Carlos Gonçalves
505426cd6a [SG 547] Mobile username generator iOS.Extension UI changes (#2140)
* [SG-547] - Added button to generate username when using iOS extension

* [SG-547] - Missing changes from last commit

* SG-547 - Added missing interface method

* SG-547 - Added token renovation for iOS.Extension flow

* SG-547 Replaced generate buttons for icons

* SG-547 Removed unnecessary validation

* SG-547 - Fixed PR comments

* SG 547 - Missing file from last commit

* SG-547 - Fixed PR comments

* SG-547 - Renamed method
2022-10-25 21:05:15 +01:00
github-actions[bot]
3cb9f37997 Autosync the updated translations (#2146)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2022-10-21 12:18:18 +02:00
aj-rosado
4c2f5c05e5 [PS-1188] Add new Solarized Dark Theme (#2141)
* PS-1188 Add new Solarized Dark Theme
2022-10-19 10:57:01 +01:00
André Bispo
eefc9bd239 [SG-705] Popup when a request for authentication comes in on a logged-in account that is not active (#2135)
* [SG-705] Added pop up to perform account switching if the user receives a login request from another account.

* [SG-705] missing resource designer

* [SG-705] Fixed wrong key for state service variable.

* [SG-705] Fix formatting of account switch alert.

* [SG-705] dotnet format run

* [SG-705] Removed async

* [SG-705] Refactor on App
2022-10-18 17:21:45 +01:00
sneakernuts
d18efdea73 updated version bump + crowdin-pull workflows (#2119)
* updated version bump + crowdin-pull workflows

* updated retrieve secrets step and changed gpg vars to reference kv secrets

* Removed duplicate step

Co-authored-by: Vince Grassia <593223+vgrassia@users.noreply.github.com>
2022-10-17 15:19:06 +00:00
Michał Chęciński
a72a0ec0ce Fix autobump workflow (#2138) 2022-10-17 11:50:38 +02:00
André Bispo
c7e9f30a9a [SG-703] Login request is not removed after dismissing push notification (#2134)
* [SG-703] Added category to iOS notifications in order to be able to receive dismiss actions

* [SG-703] PR Fix
2022-10-14 17:35:17 +01:00
mp-bw
6c404c8229 Testing removal of Xamarin.Forms dependency from iOS.ShareExtension (#2137) 2022-10-14 15:53:18 +01:00
github-actions[bot]
e5de530c2c Autosync the updated translations (#2133)
Co-authored-by: github-actions <>
2022-10-14 14:00:38 +02:00
github-actions[bot]
3a87378847 Bumped version to 2022.10.1 (#2132)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-10-13 12:43:48 -07:00
Danielle Flinn
6048a10d6d [PS-1543]Sentence case mobile (#2095)
* transitioned to sentence case
* removed unnecessary punctuation
* other small content improvements
2022-10-13 12:31:03 -07:00
github-actions[bot]
a5ad43b134 Bumped version to 2022.10.0 (#2130)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-10-12 17:42:14 +01:00
André Bispo
539f8fe5b5 [SG-690] Timeout fix (#2129)
[SG-690] Updated server times to utc
2022-10-12 15:55:38 +01:00
André Bispo
569922805f [SG-703] Login request is not removed after dismissing push notification (#2125)
* [SG-703] Handle iOS dismiss notification action. Added core logic to remove passwordless notification from local storage.

* [SG-702] Added broadcast receiver to catch dismiss notfication events on android.

* [SG-703] PR fixes.

* [SG-703] Fix constants namespaces. Lazyloading services on broadcast receiver.

* [SG-703] Change services to use lazy loading

* [SG-703] Change lazy loading to be parameterless.
2022-10-12 15:55:01 +01:00
github-actions[bot]
3972e3de8a Autosync the updated translations (#2118)
Co-authored-by: github-actions <>
2022-10-12 15:14:24 +02:00
Federico Maccaroni
ba677a96aa [EC-519] Refactor Split DeviceActionService (#2081)
* EC-519 Refactored IDeviceActionService to be split into IFileService and IAutofillManager also some cleanups were made

* EC-519 Fix format

* EC-519 Fix merge to use the new AutofillHandler
2022-10-11 18:19:32 -03:00
Federico Maccaroni
d800e9a43e EC-602 Constants namespace fix (#2127) 2022-10-11 16:47:52 -04:00
Federico Maccaroni
2d35a00caa EC-602 added droid constants file with the package name constant (#2126) 2022-10-11 16:08:36 -04:00
Michał Chęciński
dc5698b353 [DEVOPS-1014] Fix version auto bump workflow (#2121)
* Fix autobump

* Fix regex

* Use tag name

* DEVOPS-1014 - Review (#2123)

Co-authored-by: Vince Grassia <593223+vgrassia@users.noreply.github.com>
2022-10-11 16:27:07 +02:00
André Bispo
abada481b7 [SG-702] Tapping Push Notification does not open the account the request is for (#2112)
* [SG-702] Tap notification now switches accounts if it is a passwordless notification.

* [SG-702] Fix compilation errors

* [SG-702] Fixed iOS notification tap fix

* [SG-702] Notification data model

* [SG-702] Change method signature with object containing properties. PR fixes.
2022-10-07 12:06:57 +01:00
André Bispo
1e5eab0574 [SG-690] DateTime to Utc fix (#2115)
* [SG-690] DateTime to Utc fix

* [SG-690] Removed Utc from server side datetime.
2022-10-04 20:40:28 -04:00
André Bispo
c1101af582 [SG-687] added try catch to cancellation token disposal. (#2114) 2022-10-04 20:25:52 +01:00
André Bispo
1db4c4fc8b SG-687 Request time not updating (#2108)
* [SG-687] request updates text with timer task and expires after 15 mins.

* [SG-697] PR Fixes

* [SG-687] Ran code format

* [SG-687] PR Fixes

* [SG-687] missed constant replacement

* [SG-687] PR fixes
2022-10-03 17:42:33 +01:00
André Bispo
bc949fe87a [SG-691] Login request is not displayed after changing accounts (#2111)
* [SG-691] Added new message to be broadcasted when account is switched to trigger a check for login requests.

* [SG-691] PR fixes
2022-10-03 17:11:38 +01:00
Carlos Gonçalves
a890ee6612 [SG-666][SG-667] Email is not prefilled and username isn't generated automatically (#2109)
* SG-666 SG-667 - Email is now prefilled for plus addressed email username type
* Username is auto generated upon navigation

* SG-666 - Fixed PR comments
* Added missing property initialization
2022-10-03 16:51:22 +01:00
André Bispo
90e0b5dcf0 [SG-690] Login Request does not disappear after 15 minutes (#2106)
* [SG-690] Add timeout of 15 for android notifications. Add condition to not prompt login requests if 15mins have passed. Add constant for timeout time.

* [SG-690] Added dialog on click confirm/deny if the request is expired.

* [SG-690] PR fixes

* [SG-690] PR fixes
2022-09-30 20:44:56 +01:00
mp-bw
9631988fc2 remove duplicate/older community toolkit dependency (#2107) 2022-09-30 15:44:18 -03:00
André Bispo
b5f80da28d [SG-696] Android notification icon blank (#2105)
* [SG-696] Added new icon for android notifications. Changed notification intent flags to use helper.

* [SG-696] PR fix. Min version was already 21.
2022-09-30 14:47:03 +01:00
github-actions[bot]
7e0b943b70 Autosync the updated translations (#2104)
Co-authored-by: github-actions <>
2022-09-30 13:10:59 +02:00
mp-bw
425be32c15 added a11y disclosure prompt for Android (#2102) 2022-09-27 15:03:06 -03:00
André Bispo
f9a32e4abc Passwordless feature branch PR (#2100)
* [SG-471] Passwordless device login screen (#2017)

* [SSG-471] Added UI for the device login request response.

* [SG-471] Added text resources and arguments to Page.

* [SG-471] Added properties to speed up page bindings

* [SG-471] Added mock services. Added Accept/reject command binding, navigation and toast messages.

* [SG-471] fixed code styling with dotnet-format

* [SG-471] Fixed back button placement. PR fixes.

* [SG-471] Added new Origin parameter to the page.

* [SG-471] PR Fixes

* [SG-471] PR fixes

* [SG-471] PR Fix: added FireAndForget.

* [SG-471] Moved fire and forget to run on ui thread task.

* [SG-381] Passwordless - Add setting to Mobile (#2037)

* [SG-381] Added settings option to approve passwordless login request. If user has notifications disabled, prompt to go to settings and enable them.

* [SG-381] Update settings pop up texts.

* [SG-381] Added new method to get notifications state on device settings. Added userId to property saved on device to differentiate value between users.

* [SG-381] Added text for the popup on selection.

* [SG-381] PR Fixes

* [SG-408] Implement passwordless api methods (#2055)

* [SG-408] Update notification model.

* [SG-408] removed duplicated resource

* [SG-408] Added implementation to Api Service of new passwordless methods.

* removed qa endpoints

* [SG-408] Changed auth methods implementation, added method call to viewmodel.

* [SG-408] ran code format

* [SG-408] PR fixes

* [SG-472] Add configuration for new notification type (#2056)

* [SG-472] Added methods to present local notification to the user. Configured new notification type for passwordless logins

* [SG-472] Updated code to new api service changes.

* [SG-472] ran dotnet format

* [SG-472] PR Fixes.

* [SG-472] PR Fixes

* [SG-169] End-to-end testing refactor. (#2073)

* [SG-169] Passwordless demo change requests (#2079)

* [SG-169] End-to-end testing refactor.

* [SG-169] Fixed labels. Changed color of Fingerprint phrase. Waited for app to be in foreground to launch passwordless modal to fix Android issues.

* [SG-169] Anchored buttons to the bottom of the screen.

* [SG-169] Changed device type from enum to string.

* [SG-169] PR fixes

* [SG-169] PR fixes

* [SG-169] Added comment on static variable
2022-09-26 18:27:57 +01:00
André Bispo
2f4cd36595 [SG-671] OTP Menu Screen causes Crash on Android (#2097)
* [SG-671] removed unnecessary calc of otpauth period. protected cal of otpauth from crashing the app if url has a wrong format.

* [SG-671] changed logger

* [SG-671] Refactored GetQueryParams code to used HttpUtility.ParseQueryString.

* [SG-671] refactor and null protection.

* [SG-671] code format

* [SG-671] fixed bug where totp circle countdown was fixed to 30.

* [SG-167] added fallback for uri check. Changed all default totp timers to constant.

* [SG-671] missed unsaved file

* [SG-671] simplified code
2022-09-26 17:51:03 +01:00
github-actions[bot]
70ee24d82a Autosync the updated translations (#2099)
Co-authored-by: github-actions <>
2022-09-26 15:58:33 +02:00
github-actions[bot]
28576bbf49 Autosync the updated translations (#2096)
Co-authored-by: github-actions <>
2022-09-23 02:46:20 +02:00
mp-bw
7f9dfd3dae Updated libs to latest stable (#2092)
* updated libs to latest stable

* testing rollback of test dependencies

* testing xunit restore

* bump all test libs except xunit

* remove AndroidX.Migration package
2022-09-22 11:17:17 -04:00
github-actions[bot]
115aee2026 Bump version to 2022.9.2 (#2090)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-09-21 14:23:27 -06:00
aj-rosado
86fee6f04e [PS-1312] Update NFCAdapter mutability flag (#2088)
* PS-1312 - Changed NFC Adapter PendingIntent to mutable
2022-09-21 17:43:48 +01:00
mp-bw
2deab59b35 [Android] Added shadowless version of monochrome launcher icon (#2084)
* Added shadowless version of monochrome launcher icon

* added missing project ref
2022-09-20 10:25:12 -04:00
aj-rosado
b4737457a8 PS-1404 Improved exception handling when saving an attachment (#2078)
* PS-1404 Improved exception handling when saving an attachment

* PS-1404 Reverted unnecessary catch change

* PS-1404 Added missing whitespace

* PS-1404 Improved code formatting

* PS-1404 removed unnecessary whitespace

* PS-1404 Using SubmitAsyncCommand on xaml and removed the click method from the cs file
2022-09-16 18:28:20 +01:00
aj-rosado
305c770c58 [PS-1312] Migration to android12 and new splashscreen (#2063)
* [PS-1312] Updated Android Target and Framework to Android12 and updated new SplashScreen for Android12

* PS-1312 Changed PendingIntents mutability

* PS-1312 Removed unused imports

* PS-1312 Added method to helper to add mutability option according to Android version

* PS-1312 Renamed helper method AddPendingIntentMutability and fixed validation

* PS-1312 Improved PendingIntentMutability method from helper readability and naming
2022-09-16 16:44:15 +01:00
github-actions[bot]
afa9e23707 Autosync the updated translations (#2077)
Co-authored-by: github-actions <>
2022-09-16 03:26:44 +02:00
André Filipe da Silva Bispo
87fb5cf2ae [SG-659] Fixed TOTP not showing for free user with classic plans. (#2071)
* [SG-659] Fixed TOTP not showing for free user with classic plans.

* [SG-659] Ran code format
2022-09-14 14:45:39 +01:00
github-actions[bot]
3f8e00985c Bump version to 2022.9.1 (#2069)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-09-12 11:47:52 -06:00
github-actions[bot]
533928a4f1 Bump version to 2022.9.0 (#2068)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-09-12 10:58:58 -06:00
Federico Maccaroni
b7048de2a1 [EC-528] Refactor Custom Fields into separate components (#1662)
* Refactored CustomFields to stop using RepeaterView and use BindableLayout and divided the different types on different files and added a factory to create them

* Fix formatting
2022-09-09 15:58:11 -03:00
github-actions[bot]
2016eadb0d Autosync the updated translations (#2057)
Co-authored-by: github-actions <>
2022-09-09 20:25:28 +02:00
Federico Maccaroni
68b5bc0964 EC-540 fix AppResources encoding to be UTF-8 with BOM (#2065) 2022-09-09 14:41:16 -03:00
Michał Chęciński
119fc5812b Update deprecated Azure Key Vault in workflows (#2059) 2022-09-05 11:39:22 +02:00
aj-rosado
b628c1990e [PS-191] Improve support for larger fonts Android (#2053)
* PS-191 Removed android native font scaling

* PS-191 Added exception handling when disabling android font scale
2022-08-31 12:08:36 +01:00
Thomas Rittson
183bfa0ab2 Update PR template (#2051) 2022-08-30 10:36:59 +10:00
Carlos Gonçalves
b1fb867b6e [SG-223] Mobile username generator (#2033)
* SG-223 - Changed page title and password title

* SG-223 - Refactored generated field
* Changed position of generated field
* Replaced buttons generate and copy for icons

* SG-223 - Refactor type to passwordType

* SG-223 - Added password or username selector
* Added string for label type selection

* SG-223 - Added logic for different types of username
* Added strings of new types

* [SG-223] - Added UI components for different username types
* Added static strings for new labels
* Added viewmodel properties to support username generation and their respective options

* [SG-223] Added control over type picker visibility

* [SG-223] Refactored username entry on add edit page and added generate icon
* Added GenerateUsername command

* [SG-223] - Implemented service for username generation

* [SG-223] - Added support for username generation for item creation flow
* Implemented cache for username options
* Added exception handling for api calls

* [SG-223] - Remove unused code

* [SG-223] - Added a new display field for username generated and respective command
* Added description label for each type of username
* Changed defautl value of username from string.Empty to -

* [SG-223] - Removed some StackLayouts and refactored some controls

* [SG-223] - Refactored properties name

* [SG-223] - Added visibility toggle icon for api keys of forwarded email username types

* [SG-223] - Refactored nested StackLayouts into grids.

* [SG-223] - Refactor and pr fixing

* [SG-223] - Removed string keys from Resolve
- Added static string to resources

* [SG-223] - Refactored Copy_Clicked as AsyncCommand
- Improved exception handling
- Refactored TypeSelected as GeneratorTypeSelected

* [SG-223] - Renamed PasswordFormatter

* [SG-223] - Refactored VM properties to use UsernameGenerationOptions
* Removed LoadUsernameOptions

* [SG-223] - Refactored added pickers to use SelectedItem instead SelectedIndex
* Deleted PickerIndexToBoolConverter as it isn't needed anymore

* [SG-223] -  Refactored and simplified Grid row and column definitions

* [SG-223] - Refactored Command into async command
* Added exception handling and feedback to the user

* [SG-223] - Refactored GeneratorType picker to use Enum GeneratorType instead of string

* [SG-223] - Changed some resource keys

* [SG-223] - Refactor method name

* [SG-223] - Refactored code and added logs for switch default cases

* [SG-223] - Added flag to control visibility when in edit mode

* [SG-223] - Added suffix Parenthesis to keys to prevent future conflicts

* [SG-223] - Refactored multiple methods into one, GetUsernameFromAsync
* Removed unused Extensions from enums

* [SG-223] - Added exception message

* [SG-223] - Added localizable enum values through LocalizableEnumConverter

* [SG-223] - Fixed space between controls

* [SG-223] - Removed unused code and refactored some variables and methods names

* [SG-223] - Removed unused code and refactored constant name to be more elucidative

* [SG-223] - Removed unused variable
2022-08-26 19:32:02 +01:00
manofthepeace
673ba9f3cc Fix Content Type for file upload (#2031) 2022-08-26 14:58:54 +01:00
github-actions[bot]
cdd9a5ff4d Autosync the updated translations (#2050)
Co-authored-by: github-actions <>
2022-08-26 10:07:32 +02:00
Federico Maccaroni
d204e812e1 EC-487 Added helper to localize enum values and also a converter to use in xaml (#2048) 2022-08-23 12:34:29 -03:00
André Filipe da Silva Bispo
9163b9e4de [SG-599] Cannot read authenticator key if you don't include URI before TOTP Secret. (#2047)
Removed unnecessary code when adding a TOTP auth key secret manually
2022-08-23 15:48:45 +01:00
André Filipe da Silva Bispo
ecd4da08ee [SG-598] Removed space from copied totp code (#2046)
Removed space from copied totp code
2022-08-23 15:04:17 +01:00
github-actions[bot]
525288d804 Autosync the updated translations (#2042)
Co-authored-by: github-actions <>
2022-08-19 12:51:41 +02:00
André Filipe da Silva Bispo
e829279e29 [SG-416] Updates to Bitwarden Authenticator (Feature Branch) (#2041)
* Initial commit of new TOTP page

* Revert config files from previous commit

This reverts commit b02c58e362.

* clear extra code and fix build

* add tab page

* add authentication view cell

* add toolbar icons

* got the countdown working

* enable context loading and vm init

* PS-70 Added toggle to quickly filter TOTP cypher items and show their details, Added new text resource

* PS-70 removed old authentication tab

* removed unnecessary code on vm

* fixed formatting

* PS-70 Added circular progress to the OTP count down

* PS-70 Fixed grid cell width. Added red progress at 20 percent. Refactored circular progress view.

* PS-70 Added new props to custom control.

* PS-70 show toggle only if it's premium

* PS-70 removed unnecessary code

* PS-70 add copy to clipboard.

* PS-70 show upgrade to premium text on details to free user.

* PS-70 added text labels to resource files

* PS-70 Renamed TOTP to Totp to have consistency in naming. Removed a11y text of switch because android was overlapping text.

* PS-70 added new UI to enter code manually in the QR Code scanner screen. Changed existing labels on scanner screen.

* PS-70 Splited totp code to adjust spacing.

* PS-70 Added scanner square corner overlay. Added scanning animation. Added scan success animation.

* PS-70 let zxing scanner camera feed on until screen is closed.

* PS-70 fixed scanner animation for android devices

* PS-70 added vibrate permission to manifest. refactored scanpage code. added manual authentication key feature in scanner.

* PS-70 fixed totp cell title label font

* PS-70 added copy button to totp edit cipher. Added row button when totp is null.

* PS-70 changed labels on manual scanner screen

* PS-70  Added label on top of button to solve UI bug.

* PS-70 Fixed android button overlapping bug by  adding button styling to a Frame view and placing a label inside. Fixed Color on scanner page.

* PS-70 Added frame styling for iOS, since frame view has different base configuration for android and iOS.

* PS-70 fixed font clipping bug on iOS

* PS-70 removed shadow for newer versions of android

* PS-70 code format

* PS-70 removed update to premium uri launch

* PS-70 PR fix for AppResource vs code behind generation.

* PS-70 changed premium required label. fixed bug when to show premium required label.

* [SSG-416] Removed the dashes from free user and just left the Premium subscription required.

* [SSG-416] removed unnecessary changes to the TabsPage file

* [SSG-416] removed unnecessary using.

* [SSG-416] Updated ViewPageViewModel and code refactoring.

* [SG-416] Updated scanner mode toggle text color to be inline with figma designs

* [SSG-416] Mobile PR Fixes

* [SSG-416] Add to remove a11y text from totp toggle because on android it places an helper text next to the switch making it invisible. Also removed from the label because it already reads the text from the label

* [SSG-416] run dotnet tool run dotnet-format

* [SSG-416] PR fixes

* Revert "[SSG-416] PR fixes"

This reverts commit 2f2b90acee.

* [PS-416] Fixed a bug where the item details page was not updating after saving.

* [SG-416] Authenticator toggle remake  (#2027)

* [SG-416] Removed toggle to TOTP. Added on MainPage new entry to go to screen with TOTP codes. Added filter for TOTP codes to be used when searching.

* [SG-416] Removed unnecessary code. Added nav back if there is only 1 cipher with totp code and the user removes it.

* [SG-416] Run dotnet format tool

* [SG-416] PR fixes

* [SG-416] PR Fixes. Manifest formatting. Add try catch. Extracted method and added null protection.

* [SG-416] Make TOTP codes appear above favourites.

* [SG-416] PR fixes. Show error dialog.

Co-authored-by: Carlos J. Muentes <42616259+cmuentes@users.noreply.github.com>
Co-authored-by: Jacob Fink <jfink@bitwarden.com>
2022-08-17 22:10:16 +01:00
aj-rosado
3d9555d420 [PS-1009] Changed keyboard on Passphrase generator to not allow emojis (#2038)
* PS-1009 Added effect to Entry that doesn't allow keyboard with emojis on passphrase separator

* PS-1009 Removed unnecessary ImeOptions setting from NoEmojiKeyboardEffect
Improved code

* PS-1009 Removed unnecessary null validation on Android's NoEmojiKeyboardEffect

Co-authored-by: Federico Maccaroni <fedemkr@gmail.com>
2022-08-16 18:54:28 +01:00
Deividt Gemeli
5f7a1e769a Changed the right margin of the switch at Create Account(#2021) 2022-08-16 18:52:28 +01:00
Joseph Flinn
8b118408fa Add workaround for broken windows 2022 runner (#2040)
* Add workaround for broken windows 2022 runner

* Adding workaround to F-Droid job
2022-08-16 09:46:54 -07:00
github-actions[bot]
de41845e3e Bumped version to 2022.8.1 (#2039)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-08-16 08:01:17 -07:00
aj-rosado
61597585b5 [PS-1219] Crash when login with SSO (#2023)
* PS-1219 Added null checks and improved error handling on SSO Login

* PS-1219 Improved code

* PS-1219 Improved const naming

Co-authored-by: Federico Maccaroni <fedemkr@gmail.com>
2022-08-16 12:05:23 +01:00
Michał Chęciński
e04b250a73 Add renovate config (#2034) 2022-08-12 13:54:57 +02:00
github-actions[bot]
4fbe1b40e3 Autosync the updated translations (#2035)
Co-authored-by: github-actions <>
2022-08-12 11:32:58 +02:00
Federico Maccaroni
3ef5b576ac [EC-371] Fix iOS extensions login more menu (#2016)
* EC-371 fix iOS extensions login more menu and HintPage to display correctly on extensions

* EC-371 fix merge
2022-08-08 11:28:48 -03:00
github-actions[bot]
570b56364a Autosync the updated translations (#2030)
Co-authored-by: github-actions <>
2022-08-05 14:30:57 +02:00
Federico Maccaroni
ae4e8e2d8e [EC-341] Fix show alternative 2FA on iOS extensions (#2011)
* EC-341 Fix show alternative 2FA on iOS extensions

* EC-341 Fix iOS.Core.csproj reference
2022-08-04 16:42:41 -03:00
Todd Martin
2c8406d0ad [ENG-71] Add Github deployment to release pipeline. (#2022)
* Added Github deployment to release pipeline.

* Added explicit expression syntax

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

* Added explicit expression syntax

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

* Added initial-status

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

* Removed in_progress update since it's set on initial status

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

Co-authored-by: Todd Martin <>
Co-authored-by: Vince Grassia <593223+vgrassia@users.noreply.github.com>
2022-08-04 13:47:49 -04:00
Michał Chęciński
94bd5ceed3 Fix Android build (#2029)
Change worker to win-2022 for VS2022
2022-08-04 12:35:17 -04:00
github-actions[bot]
aa6be3d691 Bumped version to 2022.8.0 (#2028)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-08-04 17:28:54 +02:00
Vince Grassia
97fe65647a Update Crowdin action hash (#2025) 2022-08-03 16:51:41 -04:00
Michał Chęciński
ee8b8866e0 Auto bump mobile version after release (#2013)
* Add autobump version number workflow

* Comment pr since not tested

* Update .github/workflows/version-auto-bump.yml

Co-authored-by: Micaiah Martin <77340197+mimartin12@users.noreply.github.com>

* Trigger version bump workflow

* Comment for testing

* add input for testing

* FIx

* Remove testing values

Co-authored-by: Micaiah Martin <77340197+mimartin12@users.noreply.github.com>
2022-08-02 09:34:07 +02:00
Michał Chęciński
3128a4c5c8 Add autobump workflow stub (#2015) 2022-07-29 12:18:57 +02:00
aj-rosado
8ec6545bbc [PS-1116] Improved network error handling (#2007)
* PS-1116 Improved network error handling on ViewPageViewModel and AddEditPageViewModel

* PS-1116 Renamed ViewPage and AddEditPage pages to a more explicit name.
Refactored CheckPassword from the CipherPages to a single Base class.

* PS-1116 Updated variables relative to the AddEditPage and ViewPage refactor to CipherAddEditPage and CipherDetailPage

* Renamed CipherDetailPage to CipherDetailsPage

* Code improvement

* PS-1116 Improved code formatting

* PS-1116 Improved formatting

* PS-1116 Improved code formatting
2022-07-27 17:46:56 +01:00
Federico Maccaroni
90a6850d76 EC-366 Updated AndroidManifest format as what VS4M autoformats (#2014) 2022-07-26 13:08:05 -03:00
Andreas Coroiu
16f70dc0ce [EC-348] change blacklisted to blocked URIs (#2012)
* [EC-348] update blacklisted to blocked URIs

* [EC-348] update variable names
2022-07-26 09:55:16 +02:00
github-actions[bot]
f0ebc5e644 Bumped version to 2022.6.3 (#2005)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-07-22 09:51:35 -07:00
Andreas Coroiu
03c5dd78c1 [EC-353] sentence cases (#2004) 2022-07-22 10:16:50 +02:00
Andreas Coroiu
e2b6e99a0c feat: change to on and off (#2001) 2022-07-21 15:57:08 +02:00
aj-rosado
263aeef030 [PS-1080] Added text alternative to Boolean custom field icon (#2000)
* PS-1080 Added new accessibility text property to the custom field bool icon

* PS-1080 Added BoolValue property to the FieldView and added new AccessibilityProperty to bool icon
2022-07-21 09:53:39 +01:00
Carlos Gonçalves
f809170c51 [SG-467] Fix environment url validations (#1999)
* [SG-467] Fixed url validation so it works with or without http or https

* [SG-467] Validation has been refactored for simplicity.
2022-07-20 16:27:49 +01:00
Vince Grassia
c2fcc0ac52 Update 'Dry Run' path in Release workflow (#1997) 2022-07-19 15:01:03 -04:00
Federico Maccaroni
5e61fb0a14 EC-325 fix format (#1995) 2022-07-15 17:35:21 +01:00
Pedro da Rocha Pires
cf222bd0c3 [EC-325] Settings option to allow screen capture on Android (#1914)
* settings option to allow screen capture on Android

* Improved code on Screen Capture and added prompt to the user to allow screen capture

* EC-325 Removed async on OnCreate of MainActivity given that's not necessary anymore

Co-authored-by: Federico Maccaroni <fedemkr@gmail.com>
2022-07-15 16:13:10 +01:00
Micaiah Martin
cb0c52fb26 Add publish options to release workflow (#1994) 2022-07-15 07:30:14 -06:00
Michał Chęciński
c07c305384 Add version change check in the version bump workflow (#1992) 2022-07-15 11:08:38 +02:00
Federico Maccaroni
d2fbf5bdea EC-312 Fix crash on entering invalid credentials five times on Autofill (#1988) 2022-07-14 23:17:04 +01:00
Federico Maccaroni
2d2a883b96 EC-306 Fix crash happening on vietnamise when trying to go to Password Autofill on iOS given that the string was the same as Autofill Services and the comparison was misleading. Also refactored so that the action is on each item instead of having to compare to act (#1989) 2022-07-14 23:04:13 +01:00
Federico Maccaroni
1f2fb3f796 [EC-324] Added more logging for information on list crash (#1993)
* EC-324 Added more logging for trying to get more information on list out of range crash on AppCenter

* EC-324 Fix include on iOS.Core.csproj on iOS CollectionView files
2022-07-14 22:54:45 +01:00
Federico Maccaroni
8f3a4b98a5 EC-323 sanitize data on get first letters for avatar image creation (#1990) 2022-07-14 21:33:30 +01:00
Donkeykong307
70cf7431f7 Opera GX Autofill Support (#1855)
Added Opera GX Support for autofill
2022-07-14 21:27:53 +01:00
vincentvidal
f2ba86a62b Add support for iodé Browser (#1886) 2022-07-14 21:24:02 +01:00
Federico Maccaroni
292908f53f [EC-259] Added Account Switching to Share extension on iOS (#1971)
* EC-259 Added Account switching on share extension on iOS, also improved performance for this and exception handling

* EC-259 code formatting

* EC-259 Added account switching to Share extension Send view

* EC-259 Fixed navigation on share extension when a forms page is already presented

* EC-259 Fix send text UI update when going from the iOS extension

* EC-259 Improved DateTimeViewModel with helper property to easily setup date and time at the same time and applied on usage
2022-07-12 14:12:23 -03:00
Carlos Gonçalves
d621a5d2f3 [PS 920] Fix selfhosted url validations (#1967)
* PS-920 - Added feedback to user when saving bad formed URLs
* Added feedback to user when trying to perform login with bad formed URL

* PS-920 - Refactor to use AsyncCommand
*(missing file from previous commit)

* PS-920 - Fixed whitespace formatting

* PS-920 - Removed unused method

* PS-920 - Fixed validation
* Added comment for hard coded string

* PS-920 - Removed unused properties
* Fixed url validations
* Refactored method to local function

* PS-920 - Added exception handling and logging
* Added generic error message string to AppResources
2022-07-11 18:02:11 +01:00
Patrick H. Lauke
75e8276784 Use correct icon for checked/unchecked boolean (#1986)
Closes https://github.com/bitwarden/mobile/issues/1985
2022-07-11 10:48:19 -03:00
Andreas Coroiu
67f49a0591 [PS-686] Mobile update negative copy in settings (#1961)
* feat: update auto totp copy setting

* feat: update show icons settings

* feat: update auto add settings

* feat: update settings and options to sentence case

* feat: update translation keys

With the latest changes the translation keys had diverged from their contents.
This commit fixes that.

* fix: revert AndroidManifest changes

* chore: add todo comments to fix negative functions
2022-07-11 08:45:42 +02:00
Rui Tomé
cceded2a0f Updated the wording on the modal warning when deleting the account (#1982) 2022-07-08 09:28:23 +01:00
Federico Maccaroni
846d3a85a2 EC-308 Fix crash produced by creating avatar image on AccountSwitchingOverlayHelper and also added more logging to see when it happens. (#1983) 2022-07-07 20:24:29 +01:00
github-actions[bot]
7802da2b9c Bumped version to 2022.6.2 (#1981)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-07-07 09:07:08 -07:00
Rui Tomé
cd56a124d5 [EC-303] Add warning when vault timeout is set to "Never" (#1976)
* Added to AppResources.resx the message warning the user about setting the lockout option to "Never"

* Added the condition to check the newly selected option on the vault timeout settings

* Changed the wording on the warning as to reflect the mobile version

* Changed the vault timeout modal to have the ability to cancel

* Simplified the reversion of value if the user cancels the change
2022-07-07 16:35:58 +01:00
Matt Gibson
58a3662d0f Add user verification to reset password request (#1980)
We only need master password hash because this is currently
only used for sso password setting after auto-provisioning. Key
Connector is not involved in these accounts
2022-07-06 17:23:20 -05:00
Ben Pearo
6c7413e38c replace link to mobile section of contributing documentation with working link (#1978) 2022-07-06 11:43:07 -03:00
Federico Maccaroni
547e61a66b Fix formatting (#1975) 2022-07-05 17:44:45 -04:00
Federico Maccaroni
d246d1dece EC-297 Fix possible crash when copying password on cipher item view. Also improved a bit the code of copying commands (#1974) 2022-07-05 18:14:46 -03:00
Federico Maccaroni
e2502e2e0c Improved the ServiceContainer to be easier to use and not to have the service name hardcoded to register/resolve a service (#1865) 2022-07-05 18:14:31 -03:00
Federico Maccaroni
448cce38e1 Improved BroadcastService and added try...catch on async void callbacks (#1917) 2022-07-05 18:14:10 -03:00
Federico Maccaroni
dbc1e5ea3e Fix crash when trying to Focus an Entry from a background thread and improved the code so there are fewer direct access from the VM to the View (#1879) 2022-07-05 16:37:06 -04:00
github-actions[bot]
a6ddc2496f Bumped version to 2022.6.1 (#1969)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-06-29 13:25:08 -07:00
github-actions[bot]
d9a818279f Bumped version to 2022.6.0 (#1968)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-06-29 09:11:34 -07:00
Matt Gibson
6e2e613fee Add ssoToken to limit lifetime of SSO redirect (#1965) 2022-06-27 14:53:15 -05:00
mp-bw
109aeb49e4 [BEEEP] [PS-940] Support for dark theme selection while using Default (System) theme (#1959)
* support for dark theme selection while using Default (System) theme

* refinements
2022-06-21 14:59:30 -04:00
Joseph Flinn
c892e9fa57 Pin NuGet version (#1957)
* Pinning the version of NuGet to 5.x

* pinning NuGet verison to 5.9.x

* pinning NuGet to 5.9.0.7134

* pinning NuGet to 5.9.0
2022-06-16 14:48:09 -07:00
Federico Maccaroni
b2500557e7 SG-396 Fix tappable area after hiding account switching (#1956) 2022-06-16 17:09:50 -04:00
mp-bw
7c311fbb55 fix for missing personal items added prior to joining org with personal ownership policy (#1955) 2022-06-16 09:55:09 -04:00
mp-bw
f24388c1b5 separate init and showVaultFilter property set (#1954) 2022-06-15 16:18:30 -03:00
Federico Maccaroni
3aef86bd34 [SG-386] iOS Update user state when coming from background (#1952)
* SG-386 Updated active user when coming from background to the iOS app and the extension had switched users

* Added iOSExtensionActiveUserIdKey to preference keys

* Reorder iOS preference keys
2022-06-15 13:44:25 -03:00
mp-bw
c53a85cd50 [SG-390] Fix for missing org items with single org & personal ownership enabled (#1953)
* fix for missing org items with single org & personal ownership enabled

* fix for ui issue with vault filter state change on pull to refresh
2022-06-15 11:43:54 -03:00
mp-bw
448758a697 Additional logic around filter display (#1951) 2022-06-14 14:02:03 -03:00
Thomas Rittson
e51233bf9b Update README and CONTRIBUTING to use contributing.bitwarden.com (#1932) 2022-06-14 09:55:15 +02:00
Thomas Rittson
f9cbe43627 [PIQ-3] Add Github Actions to help manage issues and PRs (#1948)
* Add automatic responses and stale Github Actions
2022-06-14 10:24:44 +10:00
Joseph Flinn
5579817f9f Updating the release version check to use the new action (#1934)
* Updating the release version check to use the new action

* Update .github/workflows/release.yml

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

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

* adjustments

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

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

* SG-210 Added reference on iOS.Core project

* Fix formatting on AccountManager

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

* formatting

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

* Updated resources keys to match the new value

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

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

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

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

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

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

* Update vault button text after sync

* formatting

* cleanup

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

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

* PS-676 Changed event to command

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

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

* PS-672: refactor code with pr suggestions

* PS-672: removed unnecessary code

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

* PS-672: removed comma

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

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

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

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

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

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

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

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

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

* Text corrections

Correcting title of forum category

* Add 'category' to text change

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

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

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

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

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

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

* establish and set listview height before showing

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

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

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

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

* Account switching

* WIP

* wip

* wip

* updates to send test logic

* fixed Send tests

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

* switch fixes

* fixes

* fixes

* cleanup

* vault timeout fixes

* account list status enhancements

* logout fixes and token handling improvements

* merge latest (#1727)

* remove duplicate dependency

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

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

* Updated account switching menu UI (#1733)

* updated account switching menu UI

* additional changes

* add key suffix to constant

* GetFirstLetters method tweaks

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

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

* Account Switching Tap to dismiss (#1743)

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

* Fix account switching overlay background transparent on the proper place

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

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

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

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

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

* dismiss account list on certain events

* use new FireAndForget method for back button logic

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

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

* Fix account switching Accounts list binding update

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

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

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

* accountswitching fixes (#1784)

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

* fix for pin lock flow

* named tuple values and updated async

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

* Global theme and account removal (#1793)

* Global theme and account removal

* remove redundant call to hide account list overlay

* cleanup and additional tweaks

* add try/catch to remove account dialog flow

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

* Linting

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

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

* switching to download artifacts from rc

* testing the upload of the 'Bitwarden iOS' directory

* Build zip asset of the Bitwarden iOS asset

* trying a couple of different zip paths

* Final package test

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

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

* Fixed build.yml dsym artifact

* Fix upload dsym build.yml

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

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

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

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

* Add secret to build workflow (#1771)

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

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

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

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

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

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

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

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

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

* Adding in the missing provisioning profile

* Removed .DS_Store from the iOS.ShareExtension csproj Resources

* switching out the share extension profile

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

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

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

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

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

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

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

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

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

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

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

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

* Add exception handling to Autofill Service

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

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

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

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

* revert to catch all ApiExceptions

* add back throw in auditService

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

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

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

* remove commented and unneccesary code

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

* Disabled using Microsoft.AppCenter.Crashes for FDroid

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

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

* Update navbar if using biometric auth only

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

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

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

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

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

* Adding in the missing provisioning profile

* Removed .DS_Store from the iOS.ShareExtension csproj Resources

* switching out the share extension profile

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

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

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

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

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

* Using cleanup for FDroid  #1640

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

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

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

* Bypass lock page if already unlocked

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

* Disable password reprompt when using key connector

* hide password reprompt checkbox when editing or adding cipher

* add PostUserKey and PostSetKeyConnector calls

* add ConvertMasterPasswordPage

* add functionality to RemoveMasterPasswordPage
- rename Convert to Remove

* Hide Change Master Password button if using key connector

* Add OTP verification for export component

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

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

* remove toolbar item "close"

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

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

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

* implement GetAndSetKey in KeyConnectorService
- ignore EnvironmentService call

* remove unnecesary orgIdentifier

* move RemoveMasterPasswordPage call to LockPage

* add spacing to export vault page

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

* Delete excessive whitespace

* Delete excessive whitespace

* Change capitalisation of OTP

* add default value to models for backwards compatibility

* remove this keyword

* actually handle exceptions

* move RemoveMasterPasswordPage to TabPage using messaging service

* add minor improvements

* remove 'this.'

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

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

* Finish basic linked fields for Login

* Use Field.LinkedId to store linked field info

* Reset Linked Custom Fields if cipherType changes

* Refactor to use ItemView class

* Use enum for LinkedId

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

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

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

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

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

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

* New translations AppResources.resx (Norwegian Nynorsk)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Vietnamese)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Tamil)

* New translations AppResources.resx (Bengali)

* New translations AppResources.resx (Thai)

* New translations AppResources.resx (Croatian)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Latvian)

* New translations AppResources.resx (Azerbaijani)

* New translations AppResources.resx (Hindi)

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

* New translations AppResources.resx (Filipino)

* New translations AppResources.resx (Malayalam)

* New translations AppResources.resx (Bosnian)

* New translations AppResources.resx (Sinhala)

* New translations AppResources.resx (Kannada)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Afrikaans)

* New translations AppResources.resx (Belarusian)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Greek)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Slovenian)

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

* New translations AppResources.resx (English, India)

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

* New translations copy.resx (Chinese Simplified)

* New translations copy.resx (English, India)

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

* New translations copy.resx (Chinese Simplified)

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

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

* Updated with blocking sync

* add the stuff I forgot to tell vsalucci about

* removed the lies I fed vsalucci

* remove unnecessary import

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

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

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

* additional tweaks

* refinements

* refinements

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

* Remove old permissions

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

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

* fixed order of operations for reset temp password flow

* Refactored bool with auth result

* Finished removal of temp password flow from set password

* iOS extension support plus extension bugfixes

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

* Remove leftover code

* Remove duplicate code

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

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

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

* combine original plus friendly message

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

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

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

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

* Autosync Crowdin translations

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

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

* Add captcha web auth to login

* Extract captcha to abstract base class

* Add Captcha to register

* Null out captcha token after each successful challenge

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

This reverts commit bd4a275558.

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

* Fix bug in 2FA method selection modal

* Move Log In button in SSO flow

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

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

* Resolve pr comments

* Move use another two step method button

* Resolve code suggestions

* Resolve for iPhone

* Apply suggestions from code review

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

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

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

* New translations copy.resx (Bosnian)

* New translations copy.resx (Kannada)

* New translations copy.resx (Tamil)

* New translations copy.resx (Tamil)

* New translations copy.resx (Bosnian)

* New translations copy.resx (Kannada)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Vietnamese)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Swedish)

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

* New translations AppResources.resx (Slovenian)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Bengali)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Afrikaans)

* New translations AppResources.resx (Belarusian)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Greek)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Tamil)

* New translations AppResources.resx (Thai)

* New translations AppResources.resx (Croatian)

* New translations AppResources.resx (Sinhala)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Latvian)

* New translations AppResources.resx (Hindi)

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

* New translations AppResources.resx (Malayalam)

* New translations AppResources.resx (Bosnian)

* New translations AppResources.resx (Kannada)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (English, India)

* New translations copy.resx (Bosnian)

* New translations copy.resx (German)

* New translations copy.resx (Danish)

* New translations copy.resx (Czech)

* New translations copy.resx (Catalan)

* New translations copy.resx (Bulgarian)

* New translations copy.resx (Belarusian)

* New translations copy.resx (Afrikaans)

* New translations copy.resx (Spanish)

* New translations copy.resx (French)

* New translations copy.resx (Romanian)

* New translations copy.resx (English, India)

* New translations copy.resx (Norwegian Bokmal)

* New translations copy.resx (Kannada)

* New translations copy.resx (Sinhala)

* New translations copy.resx (Malayalam)

* New translations copy.resx (Finnish)

* New translations copy.resx (Persian)

* New translations copy.resx (Ukrainian)

* New translations copy.resx (Chinese Simplified)

* New translations copy.resx (Chinese Traditional)

* New translations copy.resx (Vietnamese)

* New translations copy.resx (Portuguese, Brazilian)

* New translations copy.resx (Indonesian)

* New translations copy.resx (Tamil)

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

* New translations copy.resx (Bengali)

* New translations copy.resx (Thai)

* New translations copy.resx (Croatian)

* New translations copy.resx (Estonian)

* New translations copy.resx (Latvian)

* New translations copy.resx (Hindi)

* New translations copy.resx (Greek)

* New translations copy.resx (Hebrew)

* New translations copy.resx (Swedish)

* New translations copy.resx (Latvian)

* New translations copy.resx (Persian)

* New translations copy.resx (Tamil)

* New translations copy.resx (Bengali)

* New translations copy.resx (Thai)

* New translations copy.resx (Croatian)

* New translations copy.resx (Estonian)

* New translations copy.resx (Hindi)

* New translations copy.resx (Portuguese, Brazilian)

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

* New translations copy.resx (Malayalam)

* New translations copy.resx (Bosnian)

* New translations copy.resx (Sinhala)

* New translations copy.resx (Kannada)

* New translations copy.resx (Norwegian Bokmal)

* New translations copy.resx (Indonesian)

* New translations copy.resx (Vietnamese)

* New translations copy.resx (Hungarian)

* New translations copy.resx (Russian)

* New translations copy.resx (Italian)

* New translations copy.resx (Japanese)

* New translations copy.resx (Korean)

* New translations copy.resx (Dutch)

* New translations copy.resx (Polish)

* New translations copy.resx (Portuguese)

* New translations copy.resx (Slovak)

* New translations copy.resx (Chinese Traditional)

* New translations copy.resx (Slovenian)

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

* New translations copy.resx (Swedish)

* New translations copy.resx (Turkish)

* New translations copy.resx (Ukrainian)

* New translations copy.resx (Chinese Simplified)

* New translations copy.resx (Turkish)

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

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Italian)

* New translations copy.resx (Slovenian)

* New translations copy.resx (Italian)

* New translations copy.resx (Danish)

* New translations copy.resx (German)

* New translations copy.resx (Greek)

* New translations copy.resx (Finnish)

* New translations copy.resx (Hebrew)

* New translations copy.resx (Hungarian)

* New translations copy.resx (Japanese)

* New translations copy.resx (Catalan)

* New translations copy.resx (Korean)

* New translations copy.resx (Dutch)

* New translations copy.resx (Polish)

* New translations copy.resx (Portuguese)

* New translations copy.resx (Russian)

* New translations copy.resx (Slovak)

* New translations copy.resx (Czech)

* New translations copy.resx (Bulgarian)

* New translations copy.resx (Belarusian)

* New translations copy.resx (Romanian)

* New translations copy.resx (French)

* New translations copy.resx (Spanish)

* New translations copy.resx (Afrikaans)

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

* Use 2 iterations for local password hashing

* Force logout if user has old keyHash stored

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

This reverts commit 497d4928fa.

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

* fixed data for copy file

* fixed data for copy file for Google

* fixed more file formatting items for resx

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

* Add support for password reprompt

* Rename PasswordPrompt to Reprompt

* Protect autofill

* Use Enums.CipherRepromptType

* Fix iOS not building

* Protect iOS autofill

* Update to match jslib

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

* updates

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

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

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

This reverts commit b72314bc93.

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

* New translations copy.resx (Tamil)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Vietnamese)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Tamil)

* New translations copy.resx (Tamil)

* New translations AppResources.resx (Bengali)

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Thai)

* New translations AppResources.resx (Croatian)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Latvian)

* New translations AppResources.resx (Hindi)

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

* New translations AppResources.resx (Malayalam)

* New translations AppResources.resx (Sinhala)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (Turkish)

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

* New translations AppResources.resx (French)

* New translations AppResources.resx (Greek)

* New translations AppResources.resx (Spanish)

* New translations copy.resx (Spanish)

* New translations AppResources.resx (Afrikaans)

* New translations AppResources.resx (Belarusian)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (Slovenian)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Slovak)

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

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

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

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

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

* Remove Include of appveyor.yml from sln-file

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

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

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

* Add new Api paths for direct upload of Cipher Attachments

* Add Attachment upload to fileUploadService

* Save with direct upload and fallback to legacy uplaod

CipherID is required for direct upload to request an upload URL

* Inform on when to remove legacy code

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

* Fix UI strings

* Add HideEmail to SendService

* Add HideEmail option to UI

* Tidy up declarations

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

* Create azure upload service

* Update max file size

* Update send file upload test

* Move internationalization string to correct document

* Allow for one shot blob uploads

* Remove unused helper

* Use FileUploadService

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

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Latvian)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Turkish)

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

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (Danish)

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

* New translations AppResources.resx (German)

* New translations AppResources.resx (Slovenian)

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

* New translations copy.resx (Bengali)

* New translations copy.resx (Turkish)

* New translations copy.resx (Turkish)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Chinese Simplified)

* New translations copy.resx (Chinese Simplified)

* New translations copy.resx (Chinese Simplified)

* New translations AppResources.resx (Chinese Traditional)

* New translations copy.resx (Chinese Traditional)

* New translations copy.resx (Chinese Traditional)

* New translations AppResources.resx (Vietnamese)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Bengali)

* New translations copy.resx (Bengali)

* New translations AppResources.resx (Hindi)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (Sinhala)

* New translations AppResources.resx (Malayalam)

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

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

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

* New translations copy.resx (Latvian)

* New translations AppResources.resx (Thai)

* New translations copy.resx (Latvian)

* New translations AppResources.resx (Latvian)

* New translations AppResources.resx (Estonian)

* New translations copy.resx (Croatian)

* New translations copy.resx (Croatian)

* New translations AppResources.resx (Croatian)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (French)

* New translations copy.resx (Czech)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (Greek)

* New translations copy.resx (German)

* New translations copy.resx (German)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Danish)

* New translations copy.resx (Czech)

* New translations copy.resx (Finnish)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Belarusian)

* New translations AppResources.resx (Afrikaans)

* New translations AppResources.resx (Spanish)

* New translations copy.resx (Finnish)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Portuguese)

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

* New translations AppResources.resx (Slovenian)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Italian)

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

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

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

* add Alook browser to AutofillHelpers.cs

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

* cleanup

* show/hide options support for send search results

* additional failsafes and copy function consolidation

* added missing disabled send icon to android renderer

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

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

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

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

* replace send type picker with segmented control

* formatting

* added note about rider issue

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

* added fallback for KdfIterations

* additional property exclusions for tests

* support encryptedFileData as byte array comparison in SendServiceTests

* formatting

* requested changes

* additional changes

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

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

* Add tests for hkdf crypto functions

Took the testing infrastructure from bitwarden/server

* Move Hkdf to cryptoFunctionService

* Port changes from bitwarden/jslib#192

* Port changes from bitwarden/jslib#205

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

* Bug fixes found by testing

* Test helpers

* Test conversion between model types

* Test SendService

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

* Add run tests step to GitHub Actions

* Test send decryption

* Test Request generation from Send

* Constructor dependencies on separate lines

* Remove unused testing infrastructure

* Rename to match class name

* Move fat arrows to previous lines

* Handle exceptions in App layer

* PR review cleanups

* Throw when attempting to save an unkown Send Type

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

* Set custom indentation on WordSeparator control

* Set correct RowsInSection for passphrase controls

* Fix RowsInSection for password controls

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

* New translations AppResources.resx (Vietnamese)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Slovenian)

* New translations copy.resx (Slovenian)

* New translations copy.resx (Slovenian)

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

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Thai)

* New translations AppResources.resx (Croatian)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Latvian)

* New translations AppResources.resx (Hindi)

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

* New translations AppResources.resx (Malayalam)

* New translations AppResources.resx (Sinhala)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Polish)

* New translations copy.resx (Romanian)

* New translations AppResources.resx (Greek)

* New translations copy.resx (Romanian)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Afrikaans)

* New translations AppResources.resx (Belarusian)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (Dutch)

* New translations copy.resx (Finnish)

* New translations copy.resx (Finnish)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (Hungarian)

* New translations copy.resx (Hungarian)

* New translations copy.resx (Hungarian)

* New translations AppResources.resx (Italian)

* New translations copy.resx (Italian)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Korean)

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

* changed permissions to permissions model

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

* New translations AppResources.resx (Vietnamese)

* New translations copy.resx (Russian)

* New translations AppResources.resx (Slovak)

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

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

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

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Ukrainian)

* New translations copy.resx (Ukrainian)

* New translations copy.resx (Ukrainian)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Russian)

* New translations copy.resx (Portuguese, Brazilian)

* New translations copy.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Thai)

* New translations AppResources.resx (Croatian)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Latvian)

* New translations AppResources.resx (Hindi)

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

* New translations AppResources.resx (Malayalam)

* New translations AppResources.resx (Sinhala)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations copy.resx (Russian)

* New translations AppResources.resx (Portuguese)

* New translations copy.resx (Romanian)

* New translations copy.resx (Danish)

* New translations copy.resx (Romanian)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Afrikaans)

* New translations AppResources.resx (Belarusian)

* New translations copy.resx (Belarusian)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Danish)

* New translations copy.resx (Danish)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Greek)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Dutch)

* New translations copy.resx (Dutch)

* New translations copy.resx (Dutch)

* New translations AppResources.resx (English, India)

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

See PR for more info.

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

Reason: deprecated.

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

Reason: deprecated.

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

* Revert "Fix auto biometric prompt on vault timeout"

This reverts commit 67663d7be9.

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

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

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

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

* free memory

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

* Match jslib export of non-org ciphers

* Clean up export

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

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

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

* Updated logic for returning from allowing cipher creation from notification

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

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

* make sure bio integrity values are written to pref storage

* integrity state migration to pref storage

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

* New translations AppResources.resx (Portuguese, Brazilian)

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

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

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Vietnamese)

* New translations AppResources.resx (Indonesian)

* New translations copy.resx (Slovak)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Thai)

* New translations AppResources.resx (Croatian)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Latvian)

* New translations AppResources.resx (Hindi)

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

* New translations AppResources.resx (Malayalam)

* New translations AppResources.resx (Sinhala)

* New translations AppResources.resx (Norwegian Bokmal)

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

* New translations copy.resx (Slovak)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Finnish)

* New translations copy.resx (French)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Afrikaans)

* New translations AppResources.resx (Belarusian)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Greek)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (English, India)

* New translations copy.resx (French)

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

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

* New translations copy.resx (Ukrainian)

* New translations copy.resx (Portuguese, Brazilian)

* New translations copy.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations copy.resx (Vietnamese)

* New translations copy.resx (Vietnamese)

* New translations copy.resx (Chinese Traditional)

* New translations copy.resx (Chinese Traditional)

* New translations copy.resx (Chinese Simplified)

* New translations copy.resx (Chinese Simplified)

* New translations AppResources.resx (Chinese Simplified)

* New translations copy.resx (Ukrainian)

* New translations copy.resx (Indonesian)

* New translations AppResources.resx (Ukrainian)

* New translations copy.resx (Turkish)

* New translations copy.resx (Turkish)

* New translations copy.resx (Swedish)

* New translations copy.resx (Swedish)

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

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

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

* New translations copy.resx (Slovak)

* New translations copy.resx (Slovak)

* New translations AppResources.resx (Indonesian)

* New translations copy.resx (Indonesian)

* New translations copy.resx (Russian)

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

* New translations copy.resx (English, India)

* New translations copy.resx (Norwegian Bokmal)

* New translations copy.resx (Norwegian Bokmal)

* New translations copy.resx (Sinhala)

* New translations copy.resx (Sinhala)

* New translations copy.resx (Malayalam)

* New translations copy.resx (Malayalam)

* New translations AppResources.resx (Malayalam)

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

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

* New translations copy.resx (Persian)

* New translations copy.resx (Hindi)

* New translations copy.resx (Hindi)

* New translations copy.resx (Latvian)

* New translations copy.resx (Latvian)

* New translations copy.resx (Estonian)

* New translations copy.resx (Estonian)

* New translations copy.resx (Croatian)

* New translations copy.resx (Croatian)

* New translations copy.resx (Thai)

* New translations copy.resx (Thai)

* New translations copy.resx (Persian)

* New translations AppResources.resx (Slovak)

* New translations copy.resx (Russian)

* New translations copy.resx (Romanian)

* New translations copy.resx (Bulgarian)

* New translations copy.resx (German)

* New translations AppResources.resx (German)

* New translations copy.resx (Danish)

* New translations copy.resx (Danish)

* New translations AppResources.resx (Danish)

* New translations copy.resx (Czech)

* New translations copy.resx (Czech)

* New translations copy.resx (Catalan)

* New translations copy.resx (Catalan)

* New translations AppResources.resx (Catalan)

* New translations copy.resx (Bulgarian)

* New translations AppResources.resx (Greek)

* New translations copy.resx (Belarusian)

* New translations copy.resx (Belarusian)

* New translations copy.resx (Afrikaans)

* New translations copy.resx (Afrikaans)

* New translations copy.resx (Spanish)

* New translations copy.resx (Spanish)

* New translations AppResources.resx (Spanish)

* New translations copy.resx (French)

* New translations copy.resx (French)

* New translations AppResources.resx (French)

* New translations copy.resx (Romanian)

* New translations copy.resx (German)

* New translations copy.resx (Greek)

* New translations AppResources.resx (Russian)

* New translations copy.resx (Korean)

* New translations copy.resx (Portuguese)

* New translations copy.resx (Portuguese)

* New translations AppResources.resx (Portuguese)

* New translations copy.resx (Polish)

* New translations copy.resx (Polish)

* New translations AppResources.resx (Polish)

* New translations copy.resx (Dutch)

* New translations copy.resx (Dutch)

* New translations AppResources.resx (Dutch)

* New translations copy.resx (Korean)

* New translations copy.resx (Japanese)

* New translations copy.resx (Greek)

* New translations copy.resx (Japanese)

* New translations copy.resx (Italian)

* New translations copy.resx (Italian)

* New translations copy.resx (Hungarian)

* New translations copy.resx (Hungarian)

* New translations AppResources.resx (Hungarian)

* New translations copy.resx (Hebrew)

* New translations copy.resx (Hebrew)

* New translations copy.resx (Finnish)

* New translations copy.resx (Finnish)

* New translations AppResources.resx (Finnish)

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

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

* finish changes to improved login ui

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

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

* null check intent before getting bool extra

* Updated xamarin androidx autofill

* fixed broken overlay fallback

* fixed filename

* auto-compat-check cleanup

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

* New translations AppResources.resx (Persian)

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

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

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

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Vietnamese)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Thai)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Croatian)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Latvian)

* New translations AppResources.resx (Hindi)

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

* New translations AppResources.resx (Malayalam)

* New translations AppResources.resx (Sinhala)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (English, India)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Portuguese)

* New translations copy.resx (Romanian)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Afrikaans)

* New translations AppResources.resx (Belarusian)

* New translations copy.resx (Belarusian)

* New translations copy.resx (Belarusian)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Greek)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Dutch)

* New translations copy.resx (English, India)

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

* Added specialized margin by platform

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

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

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

* Add browsers to AccessibilityHelpers

* Add browsers to AutofillHelpers

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

* tweaks for ios pre-13

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

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

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

* changed to be service-centric

* support for multiple cache keys

* async suffix

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

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

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

* applied Sane Person Technology (tm) to index check

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

* Map localized pt to pt-BR

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

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

* added new iOS Screenshots

* fixed resolution for some screenshots

* fixed resolution for iPad pro #5

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

* Update autofillservice.xml

* Update AccessibilityHelpers.cs

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

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

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

* New translations AppResources.resx (French)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations copy.resx (Chinese Simplified)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Dutch)

* New translations copy.resx (Korean)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Spanish)

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

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

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Vietnamese)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Belarusian)

* New translations AppResources.resx (Afrikaans)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Greek)

* New translations copy.resx (Latvian)

* New translations copy.resx (Latvian)

* New translations AppResources.resx (Hindi)

* New translations copy.resx (Hindi)

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

* New translations AppResources.resx (Sinhala)

* New translations AppResources.resx (Malayalam)

* New translations copy.resx (Malayalam)

* New translations copy.resx (Malayalam)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (Latvian)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Thai)

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

* 2FA progress

* 2FA support

* Added SSO flows and functionality

* Handle webauthenticator cancellation gracefully

* updates & bugfixes

* Added state validation to web auth response handling

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

* Added SSO prevalidation to auth process

* prevalidation now hitting identity service base url

* additional error handling

* Requested changes

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

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

* Ensure biometric validity is re-checked on focus

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

* Fix styling according to comments

* Fallback for Android 5.

* Improve comment

* Add boilerplate for iOS

* Change BiometricService to public

* Untested iOS implementation.

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

* Base64 NSData.

* Review comments for Android BiometricService.

* Rename methods in BiometricService to append Async

* Ensure we wait for async SetupBiometricAsync.

* Update BiometricService.cs

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

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

* Less spacing

* Even less spacing

* Additional reduction of spacing

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

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

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

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

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

* Removed unused field

* Fixed refreshing on disappearing & unnecessary codes removed

* Requested changes

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

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

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

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Polish)

* New translations copy.resx (Polish)

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

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Vietnamese)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Thai)

* New translations AppResources.resx (Hindi)

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

* New translations AppResources.resx (Sinhala)

* New translations copy.resx (Sinhala)

* New translations copy.resx (Sinhala)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Portuguese)

* New translations copy.resx (Romanian)

* New translations copy.resx (Romanian)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Afrikaans)

* New translations AppResources.resx (Belarusian)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (Korean)

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

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

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

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

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

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

* Hide TOTP, hide hidden fields.

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

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

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

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

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Greek)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Estonian)

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

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

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

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

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Italian)

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

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Vietnamese)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Thai)

* New translations AppResources.resx (Croatian)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Hindi)

* New translations copy.resx (Hindi)

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

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (French)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Afrikaans)

* New translations AppResources.resx (Belarusian)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Greek)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Dutch)

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

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

* Initial commit of service logic update

* Added default value for action

* Updated ToggleTokensAsync conditional

* Removed unused variables, updated action conditional

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

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

* Initial commit of app layer part 2

* Updated biometrics position

* Reverted resource name refactor

* LockOptions refactor revert

* Updated method casing :: Removed VaultTimeout prefix for timeouts

* Fixed dupe string resource (#854)

* Updated dependency to use VaultTimeoutService (#896)

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

* fix typo in PINRequireMasterPasswordRestart (#900)

* initial commit for xf usage in autofill

* Fixed databinding for hint button

* Updated Two Factor page launch - removed unused imports

* First pass at broadcast/messenger implentation for autofill

* setting theme in extension using theme manager

* extension app resources

* App resources from main app

* fix ref to twoFactorPage

* apply resources to page

* load empty app for sytling in extension

* move ios renderers to ios core

* static ref to resources and GetResourceColor helper

* fix method ref

* move application.current.resources refs to helper

* switch login page alerts to device action dialogs

* run on main thread

* showDialog with device action service

* abstract action sheet to device action service

* add support for yubikey

* add yubikey iimages to extension

* support close button action

* add support to action extension

* remove empty lines

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

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

* Initial commit - make lock action default

* Removed extra whitespace

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

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (Korean)

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

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

* Early support for future versions of some Firefox forks

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

* New translations AppResources.resx (Portuguese)

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

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Belarusian)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Catalan)

* New translations copy.resx (Belarusian)

* New translations copy.resx (Belarusian)

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

* New translations AppResources.resx (Vietnamese)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Thai)

* New translations AppResources.resx (Croatian)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Hindi)

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

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Afrikaans)

* New translations AppResources.resx (Belarusian)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Greek)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Korean)

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

* Add Privacy Browser (Free/Standard) to CompatBrowsers

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

* [Soft Delete] Added trash folder to mobile

* [Soft Delete] - Revert send to trash label

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

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

* [Soft Delete] Added trash folder to mobile

* [Soft Delete] - Revert send to trash label

* [Soft Delete] - iOS autofill index behavior fix

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

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

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

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Hebrew)

* New translations copy.resx (Hebrew)

* New translations AppResources.resx (Hungarian)

* New translations copy.resx (Hungarian)

* New translations copy.resx (Hungarian)

* New translations AppResources.resx (Italian)

* New translations copy.resx (Italian)

* New translations copy.resx (Italian)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Finnish)

* New translations copy.resx (Korean)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Polish)

* New translations copy.resx (Polish)

* New translations copy.resx (Polish)

* New translations AppResources.resx (Portuguese)

* New translations copy.resx (Portuguese)

* New translations copy.resx (Romanian)

* New translations AppResources.resx (Russian)

* New translations copy.resx (Finnish)

* New translations copy.resx (Portuguese)

* New translations AppResources.resx (Greek)

* New translations AppResources.resx (Bulgarian)

* New translations copy.resx (German)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Spanish)

* New translations copy.resx (Spanish)

* New translations copy.resx (Spanish)

* New translations AppResources.resx (Afrikaans)

* New translations copy.resx (Afrikaans)

* New translations copy.resx (Afrikaans)

* New translations AppResources.resx (Belarusian)

* New translations copy.resx (Romanian)

* New translations copy.resx (Bulgarian)

* New translations AppResources.resx (Catalan)

* New translations copy.resx (Catalan)

* New translations copy.resx (Catalan)

* New translations AppResources.resx (Czech)

* New translations copy.resx (Czech)

* New translations AppResources.resx (Danish)

* New translations copy.resx (Danish)

* New translations AppResources.resx (German)

* New translations copy.resx (Bulgarian)

* New translations copy.resx (Persian)

* New translations AppResources.resx (Thai)

* New translations copy.resx (Portuguese, Brazilian)

* New translations copy.resx (Persian)

* New translations AppResources.resx (Persian)

* New translations copy.resx (Indonesian)

* New translations AppResources.resx (Indonesian)

* New translations copy.resx (Thai)

* New translations copy.resx (Estonian)

* New translations copy.resx (Thai)

* New translations AppResources.resx (Croatian)

* New translations copy.resx (Croatian)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Hindi)

* New translations copy.resx (Hindi)

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

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

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations copy.resx (Portuguese, Brazilian)

* New translations copy.resx (Ukrainian)

* New translations copy.resx (Vietnamese)

* New translations copy.resx (Turkish)

* New translations AppResources.resx (Slovak)

* New translations copy.resx (Slovak)

* New translations copy.resx (Slovak)

* New translations AppResources.resx (Swedish)

* New translations copy.resx (Swedish)

* New translations copy.resx (Swedish)

* New translations AppResources.resx (Turkish)

* New translations copy.resx (Turkish)

* New translations AppResources.resx (Ukrainian)

* New translations copy.resx (Vietnamese)

* New translations copy.resx (Ukrainian)

* New translations AppResources.resx (Chinese Simplified)

* New translations copy.resx (Chinese Simplified)

* New translations copy.resx (Chinese Simplified)

* New translations AppResources.resx (Chinese Traditional)

* New translations copy.resx (Chinese Traditional)

* New translations copy.resx (Chinese Traditional)

* New translations AppResources.resx (Vietnamese)

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

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

* Add AVG Browser to CompatBrowsers

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

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

* AutofillHelpers.cs: global clarification

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

* Add Tor Browser (Alpha) to CompatBrowsers

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

* Add GNU IceCat to CompatBrowsers

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

* Add Avast Secure Browser to CompatBrowsers

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

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

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

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

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

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

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

* AutofillHelpers.TrustedBrowsers: sort the entries alphabetically

* AutofillHelpers.CompatBrowsers: sort the entries alphabetically

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

* Add Vivaldi Sopranos to CompatBrowsers

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

* Add Brave Beta to CompatBrowsers

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

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

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

* Log upload exception

* Restore original apk creation alongside the bundle

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

* Add Naver Whale to CompatBrowsers

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

* Alphabetized imports

* Removed unnecessary else conditional

* Fix for talkback slider control (#828)

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

* Alphabetized imports

* Removed unnecessary else conditional

* Fixed variable init order

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

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

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

* Prevent tracking for FDroid builds

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

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

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

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

* New translations copy.resx (Korean)

* New translations copy.resx (Korean)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Greek)

* New translations copy.resx (Greek)

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

* merged

* merged

* WIP

* WIP

* WIP

* WIP

* Updated LiteDB

* Update ZXing libs to 2.4.1

* Missing semicolon

* rename fab style to btn-fab

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

* Formatting updates

* Else if format

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

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

* Update multi-line conditional formatting

* Updated formatting round 2

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

* New translations copy.resx (Hebrew)

* New translations copy.resx (Hindi)

* New translations copy.resx (Hungarian)

* New translations copy.resx (Indonesian)

* New translations copy.resx (Italian)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations copy.resx (Norwegian Bokmal)

* New translations AppResources.resx (Polish)

* New translations copy.resx (German)

* New translations copy.resx (Chinese Simplified)

* New translations copy.resx (Czech)

* New translations copy.resx (Croatian)

* New translations copy.resx (Danish)

* New translations AppResources.resx (Dutch)

* New translations copy.resx (Finnish)

* New translations copy.resx (Estonian)

* New translations AppResources.resx (Estonian)

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

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

* New translations AppResources.resx (Russian)

* New translations copy.resx (Russian)

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

* Update src/Core/Services/SyncService.cs

formatting

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

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

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

* New translations AppResources.resx (Greek)

* New translations AppResources.resx (German)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Japanese)

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

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Japanese)

* New translations copy.resx (Japanese)

* New translations copy.resx (Japanese)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Polish)

* New translations copy.resx (Polish)

* New translations copy.resx (Polish)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Romanian)

* New translations AppResources.resx (Russian)

* New translations copy.resx (Russian)

* New translations copy.resx (Russian)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Thai)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Hindi)

* New translations AppResources.resx (Belarusian)

* New translations copy.resx (Dutch)

* New translations copy.resx (Belarusian)

* New translations copy.resx (Belarusian)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Croatian)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Dutch)

* New translations copy.resx (Dutch)

* New translations AppResources.resx (Hebrew)

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

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (French)

* New translations copy.resx (French)

* New translations copy.resx (French)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Greek)

* New translations copy.resx (Greek)

* New translations copy.resx (Greek)

* New translations AppResources.resx (Vietnamese)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (German)

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

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

* Update ISSUE_TEMPLATE.md

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

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

* Formatting

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

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

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

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

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

* Formatting

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

* Fixed formatter

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

* Removed formatting on AppResources file

* Fixed casing on UpdateCipherId method

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

* Password validation via cryptoService

* Export service framework

* support for constructing json export data

* Support for constructing csv export data

* Cleanup and simplification

* Completion of vault export feature

* Formatting and simplification

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

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

* Improvements to accessibility overlay anchor view tracking

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

* Cleanup

* Hide overlay when expanding status (notification) bar

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

* Adjust accessibility overlay position in response to scroll events

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

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

* Updated with requested changes

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

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

* Change ColoredPassword from FormattedString to HTML string for improved performance

* PasswordFormatter fixes

* Correct || to && condition

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

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Romanian)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Polish)

* New translations copy.resx (Persian)

* New translations copy.resx (Persian)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (German)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (Estonian)

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

* New translations copy.resx (Dutch)

* New translations copy.resx (Dutch)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Croatian)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Chinese Simplified)

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

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Romanian)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Thai)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Hindi)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Croatian)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Hebrew)

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

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (French)

* New translations AppResources.resx (German)

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

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Croatian)

* New translations copy.resx (German)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Dutch)

* New translations copy.resx (Dutch)

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

* New translations copy.resx (Bulgarian)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (French)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Romanian)

* New translations AppResources.resx (Russian)

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

* New translations AppResources.resx (German)

* New translations AppResources.resx (Hungarian)

* New translations copy.resx (Hungarian)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Persian)

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

* New translations AppResources.resx (French)

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

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (German)

* New translations AppResources.resx (French)

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

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Czech)

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

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (German)

* New translations AppResources.resx (French)

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

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Romanian)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Thai)

* New translations AppResources.resx (Vietnamese)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Croatian)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Hindi)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (German)

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

* New translations AppResources.resx (French)

* New translations AppResources.resx (Finnish)

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

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Hebrew)

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

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (French)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Czech)

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

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Romanian)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Croatian)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Hindi)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (Estonian)

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

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Vietnamese)

* New translations AppResources.resx (Turkish)

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

* Update AutofillHelpers.cs

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

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Portuguese, Brazilian)
2019-06-12 23:00:39 -04:00
Kyle Spearrin
b13d2f7f91 dot for fallback text. resolves #531 2019-06-12 22:21:47 -04:00
Kyle Spearrin
0b56dd2795 null checks 2019-06-12 21:49:52 -04:00
Kyle Spearrin
028ebff102 activity key and unsub when activity destroyed 2019-06-12 21:49:43 -04:00
Kyle Spearrin
cd60c3da2a fixed size icons 2019-06-12 09:13:13 -04:00
Kyle Spearrin
3d239a3c2b selectable label effect 2019-06-12 08:31:33 -04:00
Kyle Spearrin
26d0077bb8 delay search to 500 ms 2019-06-12 08:12:55 -04:00
Kyle Spearrin
5dbe9e5ca2 add lots of misc thigns to appdelegate 2019-06-11 23:04:41 -04:00
Kyle Spearrin
5aac96edb5 remove XF reference 2019-06-11 22:27:39 -04:00
Kyle Spearrin
c45b62fa6e icons and splash screen 2019-06-11 22:20:59 -04:00
Kyle Spearrin
e05708979d close buttons for ios 2019-06-11 21:31:51 -04:00
Kyle Spearrin
b6e7db6ecf custom content page renderer for left nav items 2019-06-11 20:57:12 -04:00
Kyle Spearrin
17060a2a1b dont link on debug 2019-06-11 20:47:01 -04:00
Kyle Spearrin
389fbc31e9 bootstrap ios 2019-06-11 16:01:56 -04:00
Kyle Spearrin
da3c3c30e7 MtouchLink sdkonly 2019-06-11 15:41:32 -04:00
Kyle Spearrin
42a7086088 info and entitlements plists 2019-06-11 15:31:32 -04:00
Kyle Spearrin
5d4cc007bb bootstrap ios 2019-06-11 15:20:28 -04:00
Kyle Spearrin
a8dfb8e2b9 add back ios project 2019-06-11 14:46:11 -04:00
Kyle Spearrin
873999336f added ios core project 2019-06-11 11:07:56 -04:00
Kyle Spearrin
8476f53337 try create uri 2019-06-11 11:00:34 -04:00
Kyle Spearrin
31a77a6e19 autofocus prompt input 2019-06-10 23:18:34 -04:00
Kyle Spearrin
2376489f51 minor layout adjustments 2019-06-10 22:37:25 -04:00
Kyle Spearrin
0bfd9f386e fdroid button first 2019-06-10 22:07:06 -04:00
Kyle Spearrin
00e214871d .ToLocalTime() on view dates 2019-06-10 21:59:23 -04:00
Kyle Spearrin
fd41047923 layout adjustments 2019-06-10 21:53:12 -04:00
Kyle Spearrin
393882f57b size adjustments for cipher cell 2019-06-10 21:40:36 -04:00
Kyle Spearrin
313e3a3447 remove old layouts 2019-06-10 21:16:33 -04:00
Kyle Spearrin
23b3972503 catch bad regex parse 2019-06-10 20:47:30 -04:00
Kyle Spearrin
01a64676b4 re-enable appveyor regular builds 2019-06-10 17:01:27 -04:00
Kyle Spearrin
a8ee067215 copy/paste fdroid 2019-06-10 16:58:09 -04:00
Kyle Spearrin
504731885a add repo url info to fdroid page 2019-06-10 16:47:00 -04:00
Kyle Spearrin
76078348d6 style updates 2019-06-10 16:26:36 -04:00
Kyle Spearrin
464fb2144b limitations 2019-06-10 16:13:08 -04:00
Kyle Spearrin
c4e64ae80a bitwarden fdroid webpage 2019-06-10 16:09:34 -04:00
Kyle Spearrin
a614d6634a disable vs build 2019-06-10 15:42:40 -04:00
Kyle Spearrin
856d7905db dist is up one dir 2019-06-10 15:42:16 -04:00
Kyle Spearrin
5b4be62fb4 copy fdroid index html file to dist 2019-06-10 15:34:48 -04:00
Kyle Spearrin
44a58e3e9b test fdroid deploy 2019-06-10 15:32:50 -04:00
Kyle Spearrin
28b6d2ee2e bitwarden on fdroid index html file 2019-06-10 15:31:33 -04:00
Kyle Spearrin
d749095d08 New Crowdin translations (#526)
* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Dutch)

* New translations copy.resx (Hebrew)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Estonian)
2019-06-10 15:18:59 -04:00
Kyle Spearrin
2cdf2cbe19 remove "of apps" 2019-06-10 15:15:33 -04:00
Kyle Spearrin
06669bc77b rename npm package to bitwarden-mobile 2019-06-10 15:11:49 -04:00
Kyle Spearrin
6cd6b00ea6 clean l10n script 2019-06-10 15:11:01 -04:00
Kyle Spearrin
61bf43cd96 only deploy fdroid on release tag 2019-06-10 15:05:49 -04:00
Kyle Spearrin
3be53235a5 build whole solution 2019-06-10 14:50:26 -04:00
Kyle Spearrin
0f0d9f9a10 try cd 2019-06-10 14:40:38 -04:00
Kyle Spearrin
e6cfa84b73 cname dist 2019-06-10 14:38:33 -04:00
Kyle Spearrin
e5888e4b90 move cmd to ps 2019-06-10 14:28:05 -04:00
Kyle Spearrin
8e9e818c43 fixes for appveyor 2019-06-10 14:10:14 -04:00
Kyle Spearrin
5f41487fd2 fdroid-dist 2019-06-10 13:58:34 -04:00
Kyle Spearrin
3b7d3e2652 update appveyor for fdroid builds 2019-06-10 13:57:12 -04:00
Kyle Spearrin
5963cd35d5 fdroid assets 2019-06-10 13:36:03 -04:00
Kyle Spearrin
c4ebd8b6b7 fixes to locking 2019-06-10 13:19:05 -04:00
Kyle Spearrin
678640966e NormalizePassword 2019-06-10 13:09:42 -04:00
Kyle Spearrin
89f9394977 formatting 2019-06-10 12:58:54 -04:00
Kyle Spearrin
e7df752581 fix yubikey listening 2019-06-10 10:53:11 -04:00
Kyle Spearrin
dca567b00d _inited check on 2fa page load 2019-06-10 10:45:22 -04:00
Kyle Spearrin
5248df85ec transparent bg more button 2019-06-10 10:42:15 -04:00
Kyle Spearrin
31d39e0626 padding on cipher list item 2019-06-10 10:37:47 -04:00
Kyle Spearrin
5485bb574e font sizes for cipher cell on android 2019-06-10 10:02:09 -04:00
Kyle Spearrin
337965a7f7 set colors for cipher view cell 2019-06-08 22:29:22 -04:00
Kyle Spearrin
81cd2e26f4 more button click command 2019-06-08 13:04:06 -04:00
Kyle Spearrin
95c07334d7 website icons enabled property 2019-06-08 12:18:49 -04:00
Kyle Spearrin
2f66ee264b image and icon 2019-06-08 11:48:45 -04:00
Kyle Spearrin
5f16066641 autosize 2019-06-08 01:04:31 -04:00
Kyle Spearrin
6cdf84dcb7 wiring up cipher view cell elements 2019-06-07 15:52:47 -04:00
Kyle Spearrin
d7bfc64840 stub native cipher view cell for android 2019-06-07 14:35:44 -04:00
Kyle Spearrin
d199c83a61 null check 2019-06-07 10:31:41 -04:00
Kyle Spearrin
060e1a822f only prompt fingerprint if set 2019-06-07 10:12:11 -04:00
Kyle Spearrin
54141f77d6 no fade animations 2019-06-06 20:38:53 -04:00
Kyle Spearrin
d5c610b819 set generator page from tile if locked 2019-06-06 20:34:59 -04:00
Kyle Spearrin
a2bedaab8a try 1s delay on search to stop crashing 2019-06-06 16:18:44 -04:00
Kyle Spearrin
fa5c8c2c75 always focus search bar on appear, resolves #521 2019-06-06 09:39:48 -04:00
Kyle Spearrin
a2d00c4057 ResetWithRange once on search 2019-06-06 09:32:25 -04:00
Kyle Spearrin
cf9595a0bc only show autofill settings button when disabled
resolves #522
2019-06-06 09:14:32 -04:00
Kyle Spearrin
68d8b1fa3e catch disable display for nfc 2019-06-06 08:59:54 -04:00
Kyle Spearrin
6f905319c3 prompt fignerprint on resume of lock page 2019-06-06 08:04:54 -04:00
Kyle Spearrin
d6fd3edb3c nav bar background theming 2019-06-05 20:18:11 -04:00
Kyle Spearrin
5441c49d8d navigationBarColor black 2019-06-05 17:39:32 -04:00
Kyle Spearrin
c7938a8630 adjust toolbar after loading completes 2019-06-05 17:25:12 -04:00
Kyle Spearrin
bc0bb7c7bb fic editor renderer and add incognito to prompt 2019-06-05 16:48:54 -04:00
Kyle Spearrin
1c58d99006 add back app name and theme 2019-06-05 16:40:05 -04:00
Kyle Spearrin
e0c52dea3a generator tile and icon size adjustments 2019-06-05 16:37:54 -04:00
Kyle Spearrin
a1a5d3b363 dont need splash activity 2019-06-05 15:09:13 -04:00
Kyle Spearrin
9ae08932c2 support "no folder" short list on vault page 2019-06-05 14:27:34 -04:00
Kyle Spearrin
7d8dfb997e ShowNoData for main page 2019-06-05 13:59:08 -04:00
Kyle Spearrin
c8d8d94c7f placeholder colors 2019-06-05 12:32:40 -04:00
Kyle Spearrin
58f01493e0 darkbasedTheme 2019-06-05 12:19:53 -04:00
Kyle Spearrin
4a01116e93 catch any errors on OpenAccessibilitySettings 2019-06-05 12:09:05 -04:00
Kyle Spearrin
1cdc97f037 nord placeholder color 2019-06-05 12:00:15 -04:00
Kyle Spearrin
927c1a6799 set DisabledIconColor 2019-06-05 11:54:31 -04:00
Kyle Spearrin
8eec0c22d7 nord theme 2019-06-05 11:36:58 -04:00
Kyle Spearrin
9d86fac103 IsBusy on syncing 2019-06-05 09:39:30 -04:00
Kyle Spearrin
65f2ea1df2 stop blocking OnBackButtonPressed 2019-06-05 09:12:29 -04:00
Kyle Spearrin
4d54c8f1d1 resolve some todos 2019-06-05 08:58:11 -04:00
Kyle Spearrin
046f25c223 catch No public key when generating fingerprint 2019-06-05 08:37:07 -04:00
Kyle Spearrin
661cd79654 null check on parts 2019-06-05 08:29:27 -04:00
Kyle Spearrin
3b7078e565 try/catch on autofill service detection 2019-06-05 08:24:47 -04:00
Kyle Spearrin
e59ac5d65d generator buttons on different lines 2019-06-05 08:19:36 -04:00
Kyle Spearrin
67da9387ff take whole otpauth URI 2019-06-05 00:41:12 -04:00
Kyle Spearrin
c3f91761f6 HasCiphers and HasFolders props 2019-06-05 00:29:49 -04:00
Kyle Spearrin
a239ee80bc null checks 2019-06-05 00:21:45 -04:00
Kyle Spearrin
96275d8eec attempted workaround for arg outof range exception 2019-06-05 00:15:54 -04:00
Kyle Spearrin
1ef086a02c triedV1ReSync check 2019-06-04 23:39:58 -04:00
Kyle Spearrin
db10fee207 check internet connection on sync 2019-06-04 23:26:56 -04:00
Kyle Spearrin
279b53704b do full sync if no data is present 2019-06-04 23:25:09 -04:00
Kyle Spearrin
dbc750b44e request focus on email field for hint page 2019-06-04 23:16:57 -04:00
Kyle Spearrin
b29ccf67b1 load login page after registration 2019-06-04 23:07:35 -04:00
Kyle Spearrin
b67adf8789 properly parse error model 2019-06-04 22:48:03 -04:00
Kyle Spearrin
113eaef0d1 cleanup themes 2019-06-04 22:11:31 -04:00
Kyle Spearrin
6c88d25941 add locking to BroadcasterService 2019-06-04 21:28:50 -04:00
Kyle Spearrin
f6f6253eab catch exception on accessibility service running 2019-06-04 17:06:27 -04:00
Kyle Spearrin
8e1753ea37 sync date on settings list is local 2019-06-04 16:36:34 -04:00
Kyle Spearrin
83f8989d1f update screenshots 2019-06-04 16:36:25 -04:00
Kyle Spearrin
e1f5c97550 New Crowdin translations (#516)
* New translations AppResources.resx (Danish)

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

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Spanish)
2019-06-04 12:40:15 -04:00
Kyle Spearrin
f8fa867154 Cipher.Login null check 2019-06-04 12:37:57 -04:00
Kyle Spearrin
f0893ca214 UriMatchType cast from int 2019-06-04 12:34:29 -04:00
Kyle Spearrin
82a58d9487 do you typo 2019-06-04 12:18:23 -04:00
Kyle Spearrin
d0ea6aedd0 appveyor updates 2019-06-04 12:01:51 -04:00
Kyle Spearrin
775d929711 migration settings are for prefs storage 2019-06-04 10:57:02 -04:00
Kyle Spearrin
5bae62cdcb New Crowdin translations (#513)
* New translations AppResources.resx (Afrikaans)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Romanian)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Thai)

* New translations AppResources.resx (Vietnamese)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Croatian)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Hindi)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (German)

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

* New translations AppResources.resx (French)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (Estonian)
2019-06-04 10:56:55 -04:00
Kyle Spearrin
0a664c47b7 autofill not enabled prompt if migrated 2019-06-04 10:51:10 -04:00
Kyle Spearrin
f856e559a2 update readme 2019-06-04 10:08:56 -04:00
Kyle Spearrin
0283120934 New Crowdin translations (#512)
* New translations AppResources.resx (Afrikaans)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Romanian)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Thai)

* New translations AppResources.resx (Vietnamese)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Croatian)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Hindi)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (German)

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

* New translations AppResources.resx (French)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (Estonian)
2019-06-04 10:08:37 -04:00
Kyle Spearrin
5237cbeab0 remove some old resource strings 2019-06-04 09:58:12 -04:00
Kyle Spearrin
15961c419e New Crowdin translations (#510)
* New translations AppResources.resx (Afrikaans)

* New translations copy.resx (Italian)

* New translations copy.resx (Norwegian Bokmal)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations copy.resx (Korean)

* New translations copy.resx (Korean)

* New translations AppResources.resx (Korean)

* New translations copy.resx (Japanese)

* New translations copy.resx (Japanese)

* New translations AppResources.resx (Japanese)

* New translations copy.resx (Italian)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Italian)

* New translations copy.resx (Indonesian)

* New translations copy.resx (Afrikaans)

* New translations AppResources.resx (Indonesian)

* New translations copy.resx (Hungarian)

* New translations copy.resx (Hungarian)

* New translations AppResources.resx (Hungarian)

* New translations copy.resx (Hindi)

* New translations copy.resx (Norwegian Bokmal)

* New translations copy.resx (Persian)

* New translations AppResources.resx (Hindi)

* New translations copy.resx (Romanian)

* New translations AppResources.resx (Spanish)

* New translations copy.resx (Slovak)

* New translations copy.resx (Slovak)

* New translations AppResources.resx (Slovak)

* New translations copy.resx (Russian)

* New translations copy.resx (Russian)

* New translations AppResources.resx (Russian)

* New translations copy.resx (Romanian)

* New translations AppResources.resx (Romanian)

* New translations copy.resx (Persian)

* 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 AppResources.resx (Portuguese)

* New translations copy.resx (Polish)

* New translations copy.resx (Polish)

* New translations AppResources.resx (Polish)

* New translations copy.resx (Hindi)

* New translations copy.resx (Indonesian)

* New translations copy.resx (Hebrew)

* New translations copy.resx (Chinese Simplified)

* New translations copy.resx (Czech)

* New translations AppResources.resx (Czech)

* New translations copy.resx (Croatian)

* New translations copy.resx (Croatian)

* New translations AppResources.resx (Croatian)

* New translations copy.resx (Hebrew)

* New translations copy.resx (Chinese Traditional)

* New translations AppResources.resx (Chinese Traditional)

* New translations copy.resx (Chinese Simplified)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Chinese Simplified)

* New translations copy.resx (Catalan)

* New translations copy.resx (Catalan)

* New translations AppResources.resx (Catalan)

* New translations copy.resx (Bulgarian)

* New translations copy.resx (Bulgarian)

* New translations AppResources.resx (Bulgarian)

* New translations copy.resx (Afrikaans)

* New translations copy.resx (Czech)

* New translations copy.resx (Chinese Traditional)

* New translations copy.resx (Danish)

* New translations copy.resx (Finnish)

* New translations AppResources.resx (Hebrew)

* New translations copy.resx (Danish)

* 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 (German)

* New translations AppResources.resx (Finnish)

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

* New translations copy.resx (Estonian)

* New translations AppResources.resx (Dutch)

* New translations copy.resx (Dutch)

* New translations copy.resx (Dutch)

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

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

* New translations AppResources.resx (Estonian)

* New translations copy.resx (Estonian)

* New translations copy.resx (Turkish)

* New translations copy.resx (Vietnamese)

* New translations AppResources.resx (Vietnamese)

* New translations copy.resx (Ukrainian)

* New translations copy.resx (Ukrainian)

* New translations AppResources.resx (Ukrainian)

* New translations copy.resx (Turkish)

* New translations copy.resx (Swedish)

* New translations AppResources.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 copy.resx (Spanish)

* New translations copy.resx (Vietnamese)
2019-06-04 09:49:42 -04:00
Kyle Spearrin
8b591a7f0c replace password copied 2019-06-04 09:48:08 -04:00
Kyle Spearrin
f7977c3435 cloc XAML 2019-06-04 09:42:11 -04:00
Kyle Spearrin
0c699e6c12 remove old boxedview 2019-06-04 09:38:31 -04:00
Kyle Spearrin
11e5b2ea5d rename main theme to light theme 2019-06-04 09:36:45 -04:00
Kyle Spearrin
fdfd2d20e6 fdroid builds 2019-06-03 23:54:40 -04:00
Kyle Spearrin
32adb7b91a store assets 2019-06-03 23:51:59 -04:00
Kyle Spearrin
237d31be28 add resx for other languages 2019-06-03 23:46:09 -04:00
Kyle Spearrin
ee07182157 ListItemBorderColor for dark theme 2019-06-03 23:33:48 -04:00
Kyle Spearrin
506ab12b95 sync on migrate if online 2019-06-03 23:26:57 -04:00
Kyle Spearrin
42d6a7c9b8 ShowAndroidAutofillSettings
ShowAndroidAccessibilitySettings
2019-06-03 23:20:59 -04:00
Kyle Spearrin
44530b63ca check internet connection 2019-06-03 23:12:54 -04:00
Kyle Spearrin
eadba95d5f settings screen 2019-06-03 23:01:31 -04:00
Kyle Spearrin
2574e0cba5 Add Site Prompt 2019-06-03 23:00:48 -04:00
Kyle Spearrin
e03cf94441 check internet connection before calling server 2019-06-03 22:43:52 -04:00
Kyle Spearrin
b38b801963 android tweaks 2019-06-03 22:19:51 -04:00
Kyle Spearrin
4f990ffe96 more imeFlags 2019-06-03 17:23:50 -04:00
Kyle Spearrin
8c54062c44 remove lock logging 2019-06-03 17:04:45 -04:00
Kyle Spearrin
9766ebc8e3 always set FingerprintLocked explicitly 2019-06-03 16:56:37 -04:00
Kyle Spearrin
07bc425046 more logging 2019-06-03 16:43:57 -04:00
Kyle Spearrin
d0b8c2c4bf more lock logging 2019-06-03 16:35:04 -04:00
Kyle Spearrin
83bc7c6d51 remove lock service logging 2019-06-03 16:25:43 -04:00
Kyle Spearrin
d64625aba2 more lock service logging 2019-06-03 16:07:45 -04:00
Kyle Spearrin
d1eec27fae lock service logging 2019-06-03 16:04:04 -04:00
Kyle Spearrin
43517fc4f6 set last active to 1 year ago 2019-06-03 15:50:26 -04:00
Kyle Spearrin
0e3eeab828 post migration 2019-06-03 15:44:05 -04:00
Kyle Spearrin
6b68e85077 check lock after migration 2019-06-03 15:32:40 -04:00
Kyle Spearrin
c9faa40475 don't migrate push:lastRegistrationDate 2019-06-03 15:15:00 -04:00
Kyle Spearrin
f8969675e7 only set default lock if unset 2019-06-03 15:07:19 -04:00
Kyle Spearrin
d620b70dac migration cleanup 2019-06-03 15:06:05 -04:00
Kyle Spearrin
4055f92831 migration cleanup 2019-06-03 14:52:16 -04:00
Kyle Spearrin
3e50461ea7 set passphrase defaults 2019-06-03 14:38:54 -04:00
Kyle Spearrin
5eee358059 sync when finished migrating 2019-06-03 14:32:43 -04:00
Kyle Spearrin
17b90c744c adjust defaults for pwGenerator migration 2019-06-03 14:25:29 -04:00
Kyle Spearrin
a78997771f only set pin when needed. sync after migration 2019-06-03 14:21:56 -04:00
Kyle Spearrin
3a691977aa remove reg date from migration 2019-06-03 14:08:27 -04:00
Kyle Spearrin
4bea105693 autofill save prompt is for preferences 2019-06-03 14:06:17 -04:00
Kyle Spearrin
0918e1d963 migrate push reg date 2019-06-03 14:03:24 -04:00
Kyle Spearrin
11ec9b320e proper type for push reg date on migration 2019-06-03 13:53:36 -04:00
Kyle Spearrin
97e98e1d9d more logging 2019-06-03 13:27:32 -04:00
Kyle Spearrin
e6dcdc51a4 more logging 2019-06-03 13:20:46 -04:00
Kyle Spearrin
702d27fea0 migration logging 2019-06-03 13:13:50 -04:00
Kyle Spearrin
59b086168a debug write line migration 2019-06-03 13:05:04 -04:00
Kyle Spearrin
57c89f5b2a log if needs migration 2019-06-03 12:54:31 -04:00
Kyle Spearrin
b69304992f log service 2019-06-03 12:52:46 -04:00
Kyle Spearrin
a5256a6491 remove device lock 2019-06-03 12:33:20 -04:00
Kyle Spearrin
8211f85725 lock on app restart 2019-06-03 12:30:26 -04:00
Kyle Spearrin
c27e44a7d2 autofill service page 2019-06-03 12:19:42 -04:00
Kyle Spearrin
22f16ea514 accessibility settings page 2019-06-03 12:05:18 -04:00
Kyle Spearrin
7ed45c3535 missing scroll view 2019-06-03 11:32:48 -04:00
Kyle Spearrin
a3716bc841 settings enabled/disabled text 2019-06-03 11:26:16 -04:00
Kyle Spearrin
e8c776fe49 implement blacklisted uris options for autofill 2019-06-03 11:08:33 -04:00
Kyle Spearrin
999c9667c8 dont process OnSaveRequest if prompt disabled 2019-06-03 11:01:08 -04:00
Kyle Spearrin
59620e6435 cleanup options page a bit more 2019-06-03 10:57:08 -04:00
Kyle Spearrin
cf4a6bb1a2 autosize notes 2019-06-03 10:46:05 -04:00
Kyle Spearrin
8658ebd6bb new autofill options 2019-06-03 10:45:27 -04:00
Kyle Spearrin
59f1dcca12 logged in as on 2019-06-03 09:58:35 -04:00
Kyle Spearrin
4382490823 black theme styling 2019-06-02 00:14:09 -04:00
Kyle Spearrin
479ad31325 black theme option 2019-06-02 00:08:20 -04:00
Kyle Spearrin
dd976b5b86 more black theme stub 2019-06-01 23:59:17 -04:00
Kyle Spearrin
18c2c1433b stub black theme 2019-06-01 23:42:42 -04:00
Kyle Spearrin
0fc013eb8a migrated messaging 2019-06-01 23:33:36 -04:00
Kyle Spearrin
1d95c73173 set type selected index later 2019-06-01 23:09:38 -04:00
Kyle Spearrin
312b6c2d44 pass _appOptions to load method 2019-06-01 22:44:15 -04:00
Kyle Spearrin
cab2b261b5 do not request focus on yubikey 2019-06-01 22:27:08 -04:00
Kyle Spearrin
2ddb384c80 blacklist com.android.settings 2019-06-01 21:27:30 -04:00
Kyle Spearrin
ca27b34122 focus yubikey token entry 2019-06-01 01:08:18 -04:00
Kyle Spearrin
5ce2eaf77e dont auto show fingerprint if lock is initiated 2019-06-01 01:07:02 -04:00
Kyle Spearrin
4ae02c27a4 old userid is string 2019-06-01 00:51:50 -04:00
Kyle Spearrin
50f71e7280 migration flag fix 2019-06-01 00:42:26 -04:00
Kyle Spearrin
638de90cc4 validating 2019-06-01 00:13:36 -04:00
Kyle Spearrin
d1646e5aca support old key on password unlock 2019-05-31 23:46:22 -04:00
Kyle Spearrin
ddd521cd4b migrate if necessary 2019-05-31 23:32:01 -04:00
Kyle Spearrin
f5b05ecd92 remove needs migration flag 2019-05-31 23:26:09 -04:00
Kyle Spearrin
4f2b76c442 finish migrate data helper 2019-05-31 23:23:58 -04:00
Kyle Spearrin
6aef106482 start some migration work for auth data 2019-05-31 17:49:51 -04:00
Kyle Spearrin
b191542ab7 ime NoPersonalizedLearning on entry and editor 2019-05-31 16:47:54 -04:00
Kyle Spearrin
e0e69920e9 masterPassOnRestart option for pin locking 2019-05-31 15:30:22 -04:00
Kyle Spearrin
f3edae9bb1 NoOrgsToList 2019-05-31 14:57:11 -04:00
Kyle Spearrin
0d5f5ec9ba init settings on tabs page changed 2019-05-31 14:18:32 -04:00
Kyle Spearrin
582799464f back button to groupings page on android 2019-05-31 14:15:37 -04:00
Kyle Spearrin
fc0d91d3e7 return type field focus on cipher add/edit 2019-05-31 14:10:49 -04:00
Kyle Spearrin
81b8c1716f color adjustments 2019-05-31 13:41:18 -04:00
Kyle Spearrin
b5d2a9a2fb return command for folders add/edit 2019-05-31 12:14:25 -04:00
Kyle Spearrin
a98283f3ff return commands for accounts pages 2019-05-31 12:13:14 -04:00
Kyle Spearrin
61be796c76 return commands on login page 2019-05-31 12:02:40 -04:00
Kyle Spearrin
dd090b0ed9 do once 2019-05-31 11:55:11 -04:00
Kyle Spearrin
6588b5bebb list section separator on settings page 2019-05-31 11:52:56 -04:00
Kyle Spearrin
aa3fd29508 list row separator 2019-05-31 11:40:53 -04:00
Kyle Spearrin
dcf412d94d border for sections 2019-05-31 11:36:44 -04:00
Kyle Spearrin
defac4e2d5 center numbers 2019-05-31 11:19:14 -04:00
Kyle Spearrin
6163a6dd77 fix slider history saves 2019-05-31 11:13:46 -04:00
Kyle Spearrin
32e757a873 update slider stroke 2019-05-31 11:03:32 -04:00
Kyle Spearrin
8df940447d save length and history when value done changing 2019-05-31 09:09:32 -04:00
Kyle Spearrin
ac6f3a6bb6 fix ip address matching on getdomain 2019-05-31 08:30:18 -04:00
Kyle Spearrin
46e631388d no need to catch apiexception 2019-05-31 08:18:18 -04:00
Kyle Spearrin
ff7c9f210c hide password and clear field on unlock 2019-05-30 23:48:39 -04:00
Kyle Spearrin
eecf81f0a5 verify fingerprint when enabling 2019-05-30 22:50:58 -04:00
Kyle Spearrin
b356627afd autofill rows on settings page 2019-05-30 22:45:48 -04:00
Kyle Spearrin
e3dcf4aed1 dont return null 2019-05-30 22:11:19 -04:00
Kyle Spearrin
4dd05cf10e remove boxedview 2019-05-30 22:09:28 -04:00
Kyle Spearrin
68a85a2561 myvault tile service 2019-05-30 22:05:50 -04:00
Kyle Spearrin
49cde1c67d icons updates 2019-05-30 21:59:02 -04:00
Kyle Spearrin
249dffe778 build number on about page 2019-05-30 21:25:54 -04:00
Kyle Spearrin
6d9b860c8b update tabbar 2019-05-30 21:24:03 -04:00
Kyle Spearrin
b1eabdfe86 main thread 2019-05-30 20:40:50 -04:00
Kyle Spearrin
ab9bbf7b0f save activity 2019-05-30 20:24:30 -04:00
Kyle Spearrin
cf2308a12d CipherListOptions on search page 2019-05-30 18:33:18 -04:00
Kyle Spearrin
0aa1359ad4 use current.mainpage 2019-05-30 18:27:57 -04:00
Kyle Spearrin
48c51173a1 CipherListOptions on autofill page 2019-05-30 17:24:41 -04:00
Kyle Spearrin
6838b32304 copy to remove no folder from list 2019-05-30 15:20:04 -04:00
Kyle Spearrin
60f81c5cba no need to check sync success 2019-05-30 15:15:58 -04:00
Kyle Spearrin
419cfceef1 needs migration flag 2019-05-30 15:11:22 -04:00
Kyle Spearrin
c7b62c8551 move some items needed for migration 2019-05-30 14:43:35 -04:00
Kyle Spearrin
a66489cd8c make AutofillServiceEnabled public 2019-05-30 14:21:15 -04:00
Kyle Spearrin
6d51864873 update tasks and sync on app start 2019-05-30 14:13:02 -04:00
Kyle Spearrin
dc7b37c8f2 accessibility service autofill 2019-05-30 12:37:35 -04:00
Kyle Spearrin
21bbb2af42 search icon 2019-05-30 12:04:31 -04:00
Kyle Spearrin
c3b9f4e5a8 run subscribed messages on main thread 2019-05-30 11:40:33 -04:00
Kyle Spearrin
70fa41ca3e clear clipboard alarm 2019-05-30 11:22:35 -04:00
Kyle Spearrin
49705b1074 use ValueHasBeenCopied string 2019-05-30 09:15:59 -04:00
Kyle Spearrin
32395dcb20 fixes 2019-05-30 08:45:39 -04:00
Kyle Spearrin
e34ca49b9b pop pages if cipher doesnt exist 2019-05-30 08:40:10 -04:00
Kyle Spearrin
46a8ffa5ae pop page on delete success 2019-05-30 08:35:50 -04:00
Kyle Spearrin
3f8f29dfe7 secondary menu on groupings page 2019-05-30 00:29:00 -04:00
Kyle Spearrin
67970afc1e log out on stamp mismatch when syncing 2019-05-29 23:41:43 -04:00
Kyle Spearrin
1c08901698 remove some todos 2019-05-29 23:37:25 -04:00
Kyle Spearrin
86d8d64bf6 CipherListOptions 2019-05-29 23:35:34 -04:00
Kyle Spearrin
cc8b8f9ceb restart app after theme change 2019-05-29 23:02:30 -04:00
Kyle Spearrin
6e91d66b2c white logo and popupTheme 2019-05-29 17:14:15 -04:00
Kyle Spearrin
886f356525 blue track color on dark theme 2019-05-29 16:55:13 -04:00
Kyle Spearrin
3fe7324cdf more theming 2019-05-29 16:44:18 -04:00
Kyle Spearrin
a1741fdd67 themeing 2019-05-29 15:50:20 -04:00
Kyle Spearrin
40484a7bf0 set theme on options change 2019-05-29 14:23:55 -04:00
Kyle Spearrin
48376d0a93 more options 2019-05-29 14:11:15 -04:00
Kyle Spearrin
6be54fa7ee disable favicons and totp copy fix for org 2019-05-29 09:55:48 -04:00
Kyle Spearrin
6c6da368dd options page 2019-05-29 09:36:57 -04:00
Kyle Spearrin
d70de04816 stub out options page 2019-05-29 09:08:47 -04:00
Kyle Spearrin
bf022f8a41 move settings page into folder 2019-05-29 09:05:24 -04:00
Kyle Spearrin
7046a010f9 remove XF 2019-05-29 08:40:16 -04:00
Kyle Spearrin
5cdccc7527 fix warnings 2019-05-29 08:27:58 -04:00
Kyle Spearrin
02552d0b24 add xf back to android project 2019-05-29 00:34:15 -04:00
Kyle Spearrin
026dd4761e hockeyapp 2019-05-28 23:14:02 -04:00
Kyle Spearrin
635dd5d4d5 non-debug is secure 2019-05-28 23:04:01 -04:00
Kyle Spearrin
81d972a462 thread policy 2019-05-28 23:03:03 -04:00
Kyle Spearrin
bfeddd6d99 forms only needs to be on main app project 2019-05-28 23:01:10 -04:00
Kyle Spearrin
437a60a967 crash fixes 2019-05-28 22:57:59 -04:00
Kyle Spearrin
6218c65ec6 prime expensive tasks 2019-05-28 17:18:27 -04:00
Kyle Spearrin
25d02cec25 load EEFLongWordList from file 2019-05-28 17:06:57 -04:00
Kyle Spearrin
0bbb549533 prime the word list 2019-05-28 16:39:10 -04:00
Kyle Spearrin
4ca5593d2e load on sync completed 2019-05-28 16:28:21 -04:00
Kyle Spearrin
630fc3f73c fix route for device token PUT 2019-05-28 16:20:24 -04:00
Kyle Spearrin
d66646d168 disable fdroid for now to speed of builds 2019-05-28 15:50:53 -04:00
Kyle Spearrin
ffe7771801 async await 2019-05-28 15:40:56 -04:00
Kyle Spearrin
5942bcc16d remove old autofill service 2019-05-28 15:34:49 -04:00
Kyle Spearrin
eb3d0d726f turn off rdp builds 2019-05-28 15:21:14 -04:00
Kyle Spearrin
a4846c7b11 remove ios projects for now 2019-05-28 15:05:28 -04:00
Kyle Spearrin
8e7ed05f25 firebase receivers 2019-05-28 14:53:23 -04:00
Kyle Spearrin
84d21efb5d enable rdp 2019-05-28 14:28:06 -04:00
Kyle Spearrin
68ee013114 multidex? 2019-05-28 13:54:13 -04:00
Kyle Spearrin
cd8a09ddef fdroid config profile 2019-05-28 13:50:01 -04:00
Kyle Spearrin
e1f6302280 remove json.net from ios core project 2019-05-28 13:41:39 -04:00
Kyle Spearrin
144197daaf play store publisher 2019-05-28 13:29:09 -04:00
Kyle Spearrin
57af4e0a03 merge fixes 2019-05-28 12:15:38 -04:00
Kyle Spearrin
309caa2f83 fix ios handler 2019-05-28 12:03:41 -04:00
Kyle Spearrin
3f11fdaa82 push notification services 2019-05-28 12:01:55 -04:00
Kyle Spearrin
faccb61a6b clear master password on login 2019-05-28 10:16:57 -04:00
Kyle Spearrin
786f3b4644 2fa for email 2019-05-28 10:12:51 -04:00
Kyle Spearrin
58d101659a listen to yubikey 2019-05-28 09:54:08 -04:00
Kyle Spearrin
822fc7f308 add/remove continue button 2019-05-28 09:12:05 -04:00
Kyle Spearrin
29ab7f7a30 touch ups on two-factor page 2019-05-28 09:04:20 -04:00
Kyle Spearrin
bf4f0bdba0 two-factor page UI 2019-05-27 11:57:10 -04:00
Kyle Spearrin
e8705d49f2 stub our 2fa page backend 2019-05-27 10:28:38 -04:00
Kyle Spearrin
6d49253ee5 stub out two factor page 2019-05-23 21:19:45 -04:00
Kyle Spearrin
23f27282d6 hybrid webview 2019-05-23 21:05:52 -04:00
Kyle Spearrin
bfa336b72d scan totp key 2019-05-22 21:10:04 -04:00
Kyle Spearrin
b5522c1b5e no async 2019-05-22 20:54:44 -04:00
Kyle Spearrin
543e3418a5 scan page 2019-05-22 20:54:17 -04:00
Kyle Spearrin
ea3dcd6250 add zxing lib 2019-05-22 20:28:31 -04:00
Kyle Spearrin
b8cbd5e0aa search for autofilling 2019-05-20 22:18:34 -04:00
Kyle Spearrin
29951207ec lock page work with autofill 2019-05-17 16:36:29 -04:00
Kyle Spearrin
3c58775ae2 fixes for autofill service 2019-05-17 15:43:14 -04:00
Kyle Spearrin
9ab41c5de6 populate add page from autofill 2019-05-17 15:24:15 -04:00
Kyle Spearrin
65f3a146fa autofill page fixes 2019-05-17 14:58:42 -04:00
Kyle Spearrin
22366ec0a2 autofill cipher 2019-05-17 14:46:31 -04:00
Kyle Spearrin
d038fb900e fuzzy autofill prop 2019-05-17 14:34:29 -04:00
Kyle Spearrin
13c5ebe065 disable favicons constant 2019-05-17 14:34:14 -04:00
Kyle Spearrin
4112e0a4c9 autofill actions 2019-05-17 14:34:00 -04:00
Kyle Spearrin
f73a5d6307 display alert action 2019-05-17 14:04:16 -04:00
Kyle Spearrin
a3e165fa06 some device functions 2019-05-17 13:46:32 -04:00
Kyle Spearrin
3e633dc38e stub out autofill ciphers listing page 2019-05-17 13:14:26 -04:00
Kyle Spearrin
d53bfae529 fix settings 2019-05-17 13:10:07 -04:00
Kyle Spearrin
9d491a3636 app options for add/edit page 2019-05-17 12:03:35 -04:00
Kyle Spearrin
c77d4b795a is locked inside if 2019-05-17 11:02:50 -04:00
Kyle Spearrin
c96daf2d68 logged in as and verify messages 2019-05-17 10:01:45 -04:00
Kyle Spearrin
961e23f0b8 face id strings 2019-05-17 09:46:36 -04:00
Kyle Spearrin
defb67c523 faceid detection 2019-05-17 09:45:07 -04:00
Kyle Spearrin
4aa1209bc7 fingerprint unlock 2019-05-17 09:42:20 -04:00
Kyle Spearrin
a7ad89471a update libs 2019-05-17 09:22:16 -04:00
Kyle Spearrin
1f74e102fa dont focus fields if using fingerprint locking 2019-05-16 17:31:08 -04:00
Kyle Spearrin
5761b47073 fingerprint locking 2019-05-16 17:30:07 -04:00
Kyle Spearrin
22a0b262e1 fingerprint setup 2019-05-16 16:31:58 -04:00
Kyle Spearrin
6e42f5ce7b use proper set lock option method 2019-05-16 16:00:16 -04:00
Kyle Spearrin
c5bd59e52c set pin from settings 2019-05-16 15:54:21 -04:00
Kyle Spearrin
c65b065dd7 lock option picker 2019-05-16 14:55:18 -04:00
Kyle Spearrin
3f8ab1bfe7 no need to schedule locking if already locked 2019-05-16 12:33:48 -04:00
Kyle Spearrin
cf41c5e090 lock now 2019-05-16 12:31:00 -04:00
Kyle Spearrin
290e90ba8e lock alarm 2019-05-16 12:30:20 -04:00
Kyle Spearrin
84c9516659 log user activity 2019-05-16 12:30:13 -04:00
Kyle Spearrin
3eb1ab0452 lock service fixes 2019-05-16 12:29:55 -04:00
Kyle Spearrin
f317f45d14 type change fix 2019-05-16 12:03:36 -04:00
Kyle Spearrin
5f6a3f4cb5 lock page fixes 2019-05-16 08:41:57 -04:00
Kyle Spearrin
27b6631cc1 lock page 2019-05-15 17:37:59 -04:00
Kyle Spearrin
f7bb091366 lock now button 2019-05-15 15:47:50 -04:00
Kyle Spearrin
5cf2092576 register lock service 2019-05-15 14:26:23 -04:00
Kyle Spearrin
954de743f5 lock service 2019-05-15 14:22:28 -04:00
Kyle Spearrin
8ab632e207 lock now string 2019-05-15 13:35:17 -04:00
Kyle Spearrin
547cd4e828 various settings 2019-05-15 13:26:55 -04:00
Kyle Spearrin
264028b623 rate app 2019-05-15 13:09:49 -04:00
Kyle Spearrin
2c302985f8 colon 2019-05-15 12:55:52 -04:00
Kyle Spearrin
d6f46cf5c5 fingerprint phrase and help settings 2019-05-15 12:54:48 -04:00
Kyle Spearrin
d4ed276684 hash phrase fixes 2019-05-15 12:53:01 -04:00
Kyle Spearrin
67e458833f settings about dialog 2019-05-15 09:14:49 -04:00
Kyle Spearrin
291c201b00 folder add/edit page 2019-05-14 17:25:58 -04:00
Kyle Spearrin
f9473ea61d folders page 2019-05-14 17:02:24 -04:00
Kyle Spearrin
b68031bd11 sync page details 2019-05-14 16:36:54 -04:00
Kyle Spearrin
879b5ef3aa stub sync page 2019-05-14 12:05:30 -04:00
Kyle Spearrin
ff1f895476 stub out settings page with a listview 2019-05-14 11:53:41 -04:00
Kyle Spearrin
3229835f50 load something for other tab pages 2019-05-14 09:51:13 -04:00
Kyle Spearrin
f0a96759a4 page name for groupings 2019-05-14 09:48:40 -04:00
Kyle Spearrin
4f4c6064db new tab page from code 2019-05-14 09:43:46 -04:00
Kyle Spearrin
df802152d7 tab page IsSwipePagingEnabled false 2019-05-14 09:20:03 -04:00
Kyle Spearrin
4f3a3a5b19 stub out settings page 2019-05-14 09:09:35 -04:00
Kyle Spearrin
cc7ccf921b generated password history page 2019-05-14 09:01:07 -04:00
Kyle Spearrin
4dfd8b6985 width on length label 2019-05-14 08:37:27 -04:00
Kyle Spearrin
919eedc0fa colored password property 2019-05-14 08:32:07 -04:00
Kyle Spearrin
9400c22e4f pass gen fixes 2019-05-13 16:06:56 -04:00
Kyle Spearrin
99f00b8e63 fix renderer namespaces 2019-05-13 15:25:20 -04:00
Kyle Spearrin
29d876eaed extended slider 2019-05-13 15:24:38 -04:00
Kyle Spearrin
018a7c9f96 generator UI elements 2019-05-13 14:43:23 -04:00
Kyle Spearrin
28473dd85f stub out password generator page functionality 2019-05-13 12:13:23 -04:00
Kyle Spearrin
29b37219c2 attachments page 2019-05-10 23:43:35 -04:00
Kyle Spearrin
34fd9b5842 stub attachments page 2019-05-10 14:33:33 -04:00
Kyle Spearrin
2b2787b187 collections page 2019-05-10 14:28:17 -04:00
Kyle Spearrin
253217cf20 changes based on add/edit mode 2019-05-10 14:09:13 -04:00
Kyle Spearrin
74c0e52458 secondary toolbar buttons 2019-05-10 13:47:59 -04:00
Kyle Spearrin
75cb67890d light overflow menu 2019-05-10 13:26:37 -04:00
Kyle Spearrin
9668bd85c1 share page 2019-05-10 13:22:35 -04:00
Kyle Spearrin
9aef584494 fix dialog resolve message 2019-05-10 13:22:25 -04:00
Kyle Spearrin
a535e8a82b null checks 2019-05-09 17:27:43 -04:00
Kyle Spearrin
3bd01067e3 collection management when adding new cipher 2019-05-09 16:55:11 -04:00
Kyle Spearrin
056b9fd2de fab on view page 2019-05-09 14:12:30 -04:00
Kyle Spearrin
da2ec4a38e favorite 2019-05-09 12:29:57 -04:00
Kyle Spearrin
fb5c36071d misc section with folders 2019-05-09 12:18:23 -04:00
Kyle Spearrin
b07afa7f11 fixes for custom field name prompt 2019-05-09 11:56:39 -04:00
Kyle Spearrin
a0e65fa75e custom field name prompt 2019-05-09 11:44:27 -04:00
Kyle Spearrin
866a20ed5a custom fields add/edit 2019-05-08 23:13:10 -04:00
Kyle Spearrin
49c355e52f manage URIS on add/edit 2019-05-08 16:49:32 -04:00
Kyle Spearrin
8d0dc2d230 update repeaterview to handle observables 2019-05-08 16:37:58 -04:00
Kyle Spearrin
cbda58f770 identity fields and notes 2019-05-08 15:00:45 -04:00
Kyle Spearrin
bb0ee239b4 pickers 2019-05-08 14:37:12 -04:00
Kyle Spearrin
0495c17fc8 fab padding and clicked action 2019-05-08 10:42:55 -04:00
Kyle Spearrin
2a5739dfdc fab 2019-05-08 08:33:17 -04:00
Kyle Spearrin
0b73317dd0 add some fields for various types 2019-05-07 23:22:55 -04:00
Kyle Spearrin
5dc4357078 padding/margins for entry/picker 2019-05-07 23:22:25 -04:00
Kyle Spearrin
cf2ae9d7e8 check tasks for completion 2019-05-07 23:21:56 -04:00
Kyle Spearrin
68c6537bcb fixes to cipher service 2019-05-07 13:58:50 -04:00
Kyle Spearrin
a236d7fbb1 stub out more add/edit page stuff 2019-05-07 12:29:02 -04:00
Kyle Spearrin
13267ff83d stub new add/edit page 2019-05-07 11:25:21 -04:00
Kyle Spearrin
8c31c7290c more do once and other cleanup 2019-05-06 23:30:54 -04:00
Kyle Spearrin
7d3ef39f67 more do once 2019-05-06 23:22:48 -04:00
Kyle Spearrin
51ee93eca0 better sizing on btn title 2019-05-06 23:18:13 -04:00
Kyle Spearrin
2816e72aa9 more do once checks 2019-05-06 23:07:47 -04:00
Kyle Spearrin
5ef4c96ee7 DoOnce helper 2019-05-06 22:49:57 -04:00
Kyle Spearrin
4ed12a859b cipher searching 2019-05-06 22:35:42 -04:00
Kyle Spearrin
128935eb9f searchbar on ciphers page 2019-05-04 00:14:49 -04:00
Kyle Spearrin
2553938380 material icons. stub out ciphers search page 2019-05-02 21:25:26 -04:00
Kyle Spearrin
59e412ea09 cipher password history page 2019-05-02 14:53:45 -04:00
Kyle Spearrin
9195bdcf95 style stweaks 2019-05-02 12:46:08 -04:00
Kyle Spearrin
2ca066327a re-org pages into folders 2019-05-02 12:27:23 -04:00
Kyle Spearrin
daa9bdfb8c improve home page spacing 2019-05-02 12:26:09 -04:00
Kyle Spearrin
faf690d899 environment page 2019-05-02 12:20:56 -04:00
Kyle Spearrin
9965121011 register page 2019-05-02 10:10:05 -04:00
Kyle Spearrin
15cda95c64 hint page 2019-05-01 15:53:56 -04:00
Kyle Spearrin
9678eab43f init login page 2019-05-01 15:29:57 -04:00
Kyle Spearrin
3b97fa0379 login page layout 2019-05-01 15:11:54 -04:00
Kyle Spearrin
c8368a2190 grouping counts 2019-05-01 12:28:49 -04:00
Kyle Spearrin
ba9605383d grouping types filter 2019-05-01 11:31:00 -04:00
Kyle Spearrin
caaec3ea57 fix password leaked check 2019-05-01 10:33:48 -04:00
Kyle Spearrin
a018369ae8 BaseContentPage on groupings page 2019-05-01 10:20:05 -04:00
Kyle Spearrin
b4f4f24c24 show activity indicator while still loading 2019-05-01 10:11:49 -04:00
Kyle Spearrin
9eeafcd027 accessibility service 2019-04-30 14:33:00 -04:00
Kyle Spearrin
464f4ba300 autofill service 2019-04-30 12:35:58 -04:00
Kyle Spearrin
cad56d438f more resources 2019-04-30 11:54:44 -04:00
Kyle Spearrin
5812dc7e7e more button on cipher listing 2019-04-30 11:27:53 -04:00
Kyle Spearrin
4a1bccd516 android resources 2019-04-30 10:40:51 -04:00
Kyle Spearrin
e46277c2ac preserve none folder filter 2019-04-30 09:55:28 -04:00
Kyle Spearrin
33684bd140 view page update info 2019-04-30 09:50:35 -04:00
Kyle Spearrin
865deaf401 null converters 2019-04-30 09:50:24 -04:00
Kyle Spearrin
1f4bdb04ee attachments on view page abd device actions 2019-04-29 16:09:27 -04:00
Kyle Spearrin
a5bf16a415 attachment listing 2019-04-29 14:35:44 -04:00
Kyle Spearrin
2a6fe3f351 move field view model 2019-04-29 13:56:36 -04:00
Kyle Spearrin
9468bb322d add I to ambiguous characters 2019-04-29 13:53:33 -04:00
Kyle Spearrin
9650e44078 field logic 2019-04-29 13:51:05 -04:00
Kyle Spearrin
134a4ec5d2 view page card and identity info 2019-04-29 10:20:29 -04:00
Kyle Spearrin
b7d87486a8 dont need to check target type of bool? 2019-04-29 10:00:59 -04:00
Kyle Spearrin
a75295662c null check 2019-04-29 09:59:33 -04:00
Kyle Spearrin
69eeb8bd23 fix logic on identity view address 2019-04-29 09:31:44 -04:00
Kyle Spearrin
65fe0e8f62 string has value converter 2019-04-29 09:31:34 -04:00
Kyle Spearrin
8fa2ef863f exposed password check 2019-04-27 00:19:44 -04:00
Kyle Spearrin
5e114e8074 colored password 2019-04-26 23:58:15 -04:00
Kyle Spearrin
223e8a5293 toggle password 2019-04-26 23:37:21 -04:00
Kyle Spearrin
aee9ce802a line break for box value 2019-04-26 22:59:53 -04:00
Kyle Spearrin
04bd6b49ad correct launch icon 2019-04-26 22:44:15 -04:00
Kyle Spearrin
e9d54d9cf5 remove css styling 2019-04-26 22:42:05 -04:00
Kyle Spearrin
9b2ce98b46 view page updates 2019-04-26 21:53:39 -04:00
Kyle Spearrin
d7312e2977 uris, fields, etc to view page 2019-04-26 16:58:20 -04:00
Kyle Spearrin
c2a168c6b7 styling boxes 2019-04-26 12:57:52 -04:00
Kyle Spearrin
a01f9c7351 totp text color changes with DynamicResource 2019-04-26 12:03:29 -04:00
Kyle Spearrin
dc0f9847c6 task.run ffimage init 2019-04-26 10:58:41 -04:00
Kyle Spearrin
7613f4191b init storage 2019-04-26 10:55:29 -04:00
Kyle Spearrin
1b613db534 task.run init 2019-04-26 10:54:02 -04:00
Kyle Spearrin
fb50123af0 init task 2019-04-26 10:40:28 -04:00
Kyle Spearrin
08c3aff60b litedb init 2019-04-26 10:30:41 -04:00
Kyle Spearrin
9cb141ef62 splash 2019-04-26 10:07:42 -04:00
Kyle Spearrin
baf77eb3a3 view page login info with copy buttons 2019-04-26 00:26:09 -04:00
Kyle Spearrin
0625f313dc repeater view 2019-04-25 11:43:45 -04:00
Kyle Spearrin
b644ed5a25 icon fixes 2019-04-24 23:53:36 -04:00
Kyle Spearrin
18ff6c7976 refreshing 2019-04-24 23:37:47 -04:00
Kyle Spearrin
be5fd8381f no data messages 2019-04-24 23:28:41 -04:00
Kyle Spearrin
003092a55b re-use groupings page for ciphers listing 2019-04-24 16:50:34 -04:00
Kyle Spearrin
3d50133fa8 search service 2019-04-24 14:52:26 -04:00
Kyle Spearrin
594a491251 move groupings page under vault 2019-04-24 11:25:18 -04:00
Kyle Spearrin
1cde9b8356 go to view page from groupings 2019-04-24 11:23:03 -04:00
Kyle Spearrin
b107df60e2 dark theme test 2019-04-22 17:23:11 -04:00
Kyle Spearrin
997ed42178 folder none translation 2019-04-22 17:10:28 -04:00
Kyle Spearrin
913cd23c45 cipher view cell and groupings styles 2019-04-22 17:08:37 -04:00
Kyle Spearrin
6cd1171fd5 theme variables 2019-04-22 14:17:33 -04:00
Kyle Spearrin
c3fe3292ad i18n extension 2019-04-22 13:47:45 -04:00
Kyle Spearrin
b48c231500 theming with resource dictionary 2019-04-22 11:32:17 -04:00
Kyle Spearrin
a6cd16cdb5 selected list cell transparent 2019-04-22 09:16:47 -04:00
Kyle Spearrin
2959577163 children default is empty list 2019-04-22 09:08:24 -04:00
Kyle Spearrin
efddb385d8 folder service bug 2019-04-22 08:54:43 -04:00
Kyle Spearrin
ea5a411f30 bug fixes 2019-04-19 16:57:34 -04:00
Kyle Spearrin
7548122e2d grouping listing 2019-04-19 16:45:16 -04:00
Kyle Spearrin
a4cbf3bee3 set main page 2019-04-19 16:40:20 -04:00
Kyle Spearrin
7f2c265965 sequentialize some methods 2019-04-19 16:38:20 -04:00
Kyle Spearrin
c6ce3e9480 convert to local functions to avoid continuewith 2019-04-19 16:15:29 -04:00
Kyle Spearrin
6d8af4d97a null check 2019-04-19 15:33:55 -04:00
Kyle Spearrin
60efcbaf02 empty ctors 2019-04-19 15:25:07 -04:00
Kyle Spearrin
3b63fbb61b no userid on cipher domain 2019-04-19 15:18:43 -04:00
Kyle Spearrin
2637587cf7 null checks 2019-04-19 15:18:26 -04:00
Kyle Spearrin
480f954433 changes for new messaging 2019-04-19 12:33:57 -04:00
Kyle Spearrin
7c1549bb95 re-worked message sending 2019-04-19 12:29:37 -04:00
Kyle Spearrin
4b7366e9b3 full sync on login 2019-04-19 09:57:19 -04:00
Kyle Spearrin
6288a06b49 login page 2019-04-19 09:42:55 -04:00
Kyle Spearrin
b3c67bab92 json property mapping 2019-04-19 09:25:15 -04:00
Kyle Spearrin
8c8fa8ae4c api error detection updates 2019-04-19 09:11:17 -04:00
Kyle Spearrin
0c93fc2662 home page buttons 2019-04-19 07:42:36 -04:00
Kyle Spearrin
aec2855db9 update message send type 2019-04-18 14:30:38 -04:00
Kyle Spearrin
2becf769c1 use new messaging and broadcaster services 2019-04-18 13:15:46 -04:00
Kyle Spearrin
da73a2f5d2 mobile broadcaster service 2019-04-18 12:53:05 -04:00
Kyle Spearrin
1dd5f9fc27 fix multiple i18n inits 2019-04-18 12:34:53 -04:00
Kyle Spearrin
e141991166 bootstrap 2019-04-18 12:31:35 -04:00
Kyle Spearrin
fff32e8086 register environment service 2019-04-18 12:21:35 -04:00
Kyle Spearrin
859788ca46 environment service 2019-04-18 12:19:17 -04:00
Kyle Spearrin
b94485be75 register services on android 2019-04-18 10:40:57 -04:00
Kyle Spearrin
43948c65f1 auth service 2019-04-18 09:45:31 -04:00
Kyle Spearrin
b61355a8fa update xamarin forms 2019-04-17 17:14:04 -04:00
Kyle Spearrin
8834492ec2 update xamarin forms 2019-04-17 17:13:53 -04:00
Kyle Spearrin
676e896d8c audit service 2019-04-17 17:10:21 -04:00
Kyle Spearrin
6d159740d9 remove preproject 2019-04-17 16:02:19 -04:00
Kyle Spearrin
f48aa24129 totp service 2019-04-17 16:01:07 -04:00
Kyle Spearrin
f46151bb71 password generation service 2019-04-17 15:23:26 -04:00
Kyle Spearrin
818414eb37 sync service 2019-04-17 12:12:43 -04:00
Kyle Spearrin
808fcea655 setup sync service 2019-04-17 09:38:20 -04:00
Kyle Spearrin
d050e01d08 interfaces 2019-04-17 09:09:54 -04:00
Kyle Spearrin
6cab060509 collection service 2019-04-17 09:07:51 -04:00
Kyle Spearrin
18f04af051 tree node traversal for folder 2019-04-17 08:46:51 -04:00
Kyle Spearrin
4b3bae5797 optional params 2019-04-16 23:31:05 -04:00
Kyle Spearrin
98291caf76 cipher service interface 2019-04-16 23:30:52 -04:00
Kyle Spearrin
a1a8c95ece cipher service methods 2019-04-16 20:43:54 -04:00
Kyle Spearrin
40b6460ac9 more cipher service functions 2019-04-16 17:34:59 -04:00
Kyle Spearrin
25c82ffd58 new apis 2019-04-16 17:21:04 -04:00
Kyle Spearrin
f76051d362 data model updates 2019-04-16 11:09:05 -04:00
Kyle Spearrin
351c99fb42 locale string comparer for i18n service 2019-04-16 11:08:28 -04:00
Kyle Spearrin
803527f585 locale string comparer for i18n service 2019-04-16 11:08:05 -04:00
Kyle Spearrin
d1c696bad5 new api endpoints 2019-04-16 11:07:44 -04:00
Kyle Spearrin
5d2f4e6ca4 api models 2019-04-16 11:07:32 -04:00
Kyle Spearrin
567ebcd06e more cipher service functions 2019-04-16 07:59:53 -04:00
Kyle Spearrin
1103354de3 new constants for mobile app prefixes 2019-04-16 07:44:18 -04:00
Kyle Spearrin
2fa3d214e5 make regex helpers public 2019-04-16 07:44:05 -04:00
Kyle Spearrin
7d6ec46ebe view updates 2019-04-16 07:43:56 -04:00
Kyle Spearrin
40598721f1 Url helpers 2019-04-15 18:17:19 -04:00
Kyle Spearrin
576f44a924 DomainName helper class for getting base domain 2019-04-15 16:16:53 -04:00
Kyle Spearrin
694e4960ad cipher service encrypt 2019-04-15 11:46:20 -04:00
Kyle Spearrin
4b67ba027e collection and folder models 2019-04-15 08:42:50 -04:00
Kyle Spearrin
eeb28f6ddf card view 2019-04-15 08:30:59 -04:00
Kyle Spearrin
4aa5ba2754 use crypto service 2019-04-15 07:56:46 -04:00
Kyle Spearrin
f228758fb7 domains and cipherview 2019-04-13 22:53:20 -04:00
Kyle Spearrin
d136eee224 field and password history domains/views 2019-04-12 17:21:21 -04:00
Kyle Spearrin
52a978a59a cipher data 2019-04-12 16:55:14 -04:00
Kyle Spearrin
8ade49c958 domains and view stubs 2019-04-12 16:39:20 -04:00
Kyle Spearrin
7c6c36b744 attachment models 2019-04-12 15:50:30 -04:00
Dustin C. Hatch
6c59bf8717 Android: Support autofill in Fennec F-Droid (#483)
The F-Droid build of Firefox (Fennec) has a different package name.
This name needs to be explicitly listed in order for autofill support to
work correctly.
2019-04-12 15:32:58 -04:00
Kyle Spearrin
87798612a6 more models 2019-04-12 11:42:45 -04:00
Kyle Spearrin
c89805d123 setup more models 2019-04-12 10:06:47 -04:00
Kyle Spearrin
a1ba2bf60b setup domain and view 2019-04-11 23:57:41 -04:00
Kyle Spearrin
87543f5beb api service interface 2019-04-11 23:57:05 -04:00
Kyle Spearrin
2e31a7b280 settings service 2019-04-11 16:27:45 -04:00
Kyle Spearrin
9fb2ce9297 mobile messaging service 2019-04-11 15:50:51 -04:00
Kyle Spearrin
567d527a71 fixes to i18n service 2019-04-11 15:43:13 -04:00
Kyle Spearrin
6ee109dc80 i18n service 2019-04-11 15:33:10 -04:00
Kyle Spearrin
6a65b6d735 platform utils init 2019-04-11 14:28:38 -04:00
Kyle Spearrin
b9838ecc4e service container 2019-04-11 14:14:34 -04:00
Kyle Spearrin
e1080f9be4 add app resources resx 2019-04-10 17:01:25 -04:00
Kyle Spearrin
115fa349d2 account apis 2019-04-10 15:35:23 -04:00
Kyle Spearrin
567161d8f3 auth apis and api helpers 2019-04-10 15:03:09 -04:00
Kyle Spearrin
579a7e0398 stub out beginnings of apiservice 2019-04-10 10:49:24 -04:00
Kyle Spearrin
0d417b3eee more device actions 2019-04-09 23:33:12 -04:00
Kyle Spearrin
9e51c46522 mobile platform utils 2019-04-09 23:24:03 -04:00
Kyle Spearrin
36780c5ef8 lots of enums 2019-04-09 17:14:16 -04:00
Kyle Spearrin
9e3ee50020 move some xamarin specific services to app proj 2019-04-09 17:10:56 -04:00
Kyle Spearrin
963b27fd71 state service 2019-04-09 17:01:55 -04:00
Kyle Spearrin
13a2206735 user service 2019-04-09 16:13:32 -04:00
Kyle Spearrin
929727ba41 token service 2019-04-09 10:35:21 -04:00
Kyle Spearrin
a0f6af8097 requires nuget refs 2019-04-09 10:00:32 -04:00
Kyle Spearrin
f79f93ba43 editor config with guideline at 120 2019-04-09 09:47:22 -04:00
Kyle Spearrin
0898e3cc09 no nuget packages directly 2019-04-09 09:33:08 -04:00
Kyle Spearrin
c68927c17a crypto service interface 2019-04-09 09:08:15 -04:00
Kyle Spearrin
9f740cf371 remove app reference 2019-04-08 21:42:19 -04:00
Kyle Spearrin
474ce458bf ios core lib 2019-04-08 21:38:17 -04:00
Kyle Spearrin
8c6823c463 key chain storage service 2019-04-08 21:23:16 -04:00
Kyle Spearrin
8055de4f25 shared name 2019-04-08 20:59:19 -04:00
Kyle Spearrin
d1c1aff7d9 mobile storage service 2019-04-08 20:54:59 -04:00
Kyle Spearrin
41321e3c9e json settings 2019-04-08 20:49:48 -04:00
Kyle Spearrin
992cf033f2 support more object types by using JSON strings 2019-04-08 20:48:18 -04:00
Kyle Spearrin
24b4073616 support bool type 2019-04-08 20:33:52 -04:00
Kyle Spearrin
4ef8ccaa8e support nullable preference types 2019-04-08 20:32:12 -04:00
Kyle Spearrin
f0eca137ef crypto service implementation 2019-04-08 16:04:41 -04:00
Kyle Spearrin
3f5115728b layout tweaks 2019-04-05 22:30:11 -04:00
Kyle Spearrin
3539d7389e cell buttons 2019-04-05 16:13:17 -04:00
Kyle Spearrin
8c79c42b28 entry cell renderer 2019-04-05 13:35:19 -04:00
Kyle Spearrin
1085808867 rename cell resources 2019-04-04 23:29:29 -04:00
Kyle Spearrin
0a5f9f1b23 remove description from base cell 2019-04-04 23:15:24 -04:00
Kyle Spearrin
8006bcf10c cleanup 2019-04-04 23:00:02 -04:00
Kyle Spearrin
61e95e03c8 BoxedView with LabelCell 2019-04-04 22:28:03 -04:00
Kyle Spearrin
2b2342bcad start writing crypto service 2019-04-03 14:21:54 -04:00
Kyle Spearrin
56b8bc1730 run sass on build 2019-04-03 10:05:37 -04:00
Kyle Spearrin
53aaf7caa8 back to sass 2019-04-02 23:41:17 -04:00
Kyle Spearrin
18f659de7b fix less 2019-04-02 23:22:37 -04:00
Kyle Spearrin
b2c0b02be4 move gulp tasks to sln root 2019-04-02 22:43:22 -04:00
Kyle Spearrin
61c1c6ebf8 build css from less 2019-04-02 22:15:11 -04:00
Kyle Spearrin
b837c600a8 remove css files from source 2019-04-02 21:47:36 -04:00
Kyle Spearrin
54a109345b support new moz browser in accessibility service 2019-04-01 12:57:51 -04:00
Kyle Spearrin
3a90b3beb6 theme manager 2019-03-29 21:23:34 -04:00
Kyle Spearrin
fe52324eea stylesheets 2019-03-29 17:54:03 -04:00
Kyle Spearrin
a1c853d7fc cipher view cell control 2019-03-29 16:52:57 -04:00
Kyle Spearrin
53974c4464 reorg groupings page 2019-03-29 13:24:44 -04:00
Kyle Spearrin
69ac98b2f6 vault groupings page list view stubbed 2019-03-29 12:52:57 -04:00
Kyle Spearrin
d84eece715 compile bindings 2019-03-29 09:16:22 -04:00
Kyle Spearrin
af7a456e96 more moz browsers for autofill 2019-03-29 08:48:48 -04:00
Kyle Spearrin
6088cfe266 resolves #477 2019-03-29 08:43:03 -04:00
Kyle Spearrin
02e03c7654 stub out various pages 2019-03-28 23:52:33 -04:00
Kyle Spearrin
30dd2e993f home page 2019-03-28 17:10:10 -04:00
Kyle Spearrin
574c826036 app id service 2019-03-28 16:45:00 -04:00
Kyle Spearrin
6d22888bf6 crypto function service interface 2019-03-28 16:06:55 -04:00
Kyle Spearrin
556741683d compare crypto alg 2019-03-28 16:04:38 -04:00
Kyle Spearrin
cb9dddc7a7 crypto function service 2019-03-28 15:43:50 -04:00
Kyle Spearrin
fca1dbd6ec secure storage service 2019-03-28 14:09:39 -04:00
Kyle Spearrin
364f25e22a fixes to PreferencesStorageService 2019-03-28 14:09:33 -04:00
Kyle Spearrin
9042702c09 use formatted key 2019-03-28 14:01:36 -04:00
Kyle Spearrin
86f1874379 playground app and json settings for litedb 2019-03-28 13:57:45 -04:00
Kyle Spearrin
781f838ce7 remove installLocation 2019-03-28 13:39:50 -04:00
Kyle Spearrin
addb7a0ecb fix connection string for litedb 2019-03-27 23:47:24 -04:00
Kyle Spearrin
21777602f6 storage services 2019-03-27 23:44:54 -04:00
Kyle Spearrin
a88f799372 rename lib to core 2019-03-27 21:36:28 -04:00
Kyle Spearrin
daee1a8e9d lib project 2019-03-27 21:34:39 -04:00
Kyle Spearrin
afd5d55b5f fontawesome icons 2019-03-27 21:26:57 -04:00
Kyle Spearrin
0f2d2ac7a9 themeing 2019-03-27 21:09:59 -04:00
Kyle Spearrin
a77bf9ddff stub out xamarin project 2019-03-27 20:12:44 -04:00
Kyle Spearrin
297beac169 reset for v2 2019-03-27 16:23:00 -04:00
Kyle Spearrin
5a7f106e3e restore secure flag 2019-03-15 23:00:22 -04:00
Kyle Spearrin
25636ac6ce remove secure flag 2019-03-15 23:00:06 -04:00
Kyle Spearrin
6d11921f45 exclude TextFlagMultiLine from autofill detection 2019-02-26 11:50:02 -05:00
Kyle Spearrin
05f6d6d156 opera touch support 2019-02-19 22:25:15 -05:00
Kyle Spearrin
b0cabbbfc2 parsed ShouldAutofill with app URL blacklist 2019-02-10 22:16:16 -05:00
Kyle Spearrin
4b9fa5041c bump version for ios 2019-02-04 08:56:19 -05:00
Kyle Spearrin
ed2ea75938 invoke Dispatch handler 2019-02-04 08:53:54 -05:00
Kyle Spearrin
a1fdc4a970 detect hidden field even when toggled 2019-01-25 09:08:13 -05:00
kspearrin
d20b3cadbf fix opening file on ipad 2019-01-25 08:55:26 -05:00
kspearrin
1374ee31ba remove additional ga refs 2019-01-25 08:55:26 -05:00
Kyle Spearrin
062f6b6665 remove whitespace 2019-01-24 14:46:27 -05:00
ShirokaiLon
8053e6cb81 Set Android InputType directly for the pin lock screen to force numeric-only keyboard layout. (#451)
* Set Android InputType directly for the pin lock screen to force numeric-only keyboard layout.

* Renamed variable
2019-01-24 14:45:42 -05:00
ShirokaiLon
60c5bbc73d Handle exception when adding attachment that does not exist on file system. (#449) 2019-01-22 15:53:48 -05:00
Kyle Spearrin
f0fb401d07 analytics not part of fdroid build any longer 2019-01-16 17:29:05 -05:00
Kyle Spearrin
6f3c302f28 missing null check 2019-01-16 16:38:12 -05:00
Kyle Spearrin
ba5495877c disable test nodes 2019-01-16 16:15:13 -05:00
Kyle Spearrin
2b8fe5fa98 New Crowdin translations (#445)
* New translations AppResources.resx (Bulgarian)

* 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 AppResources.resx (Portuguese)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (Korean)

* New translations copy.resx (Vietnamese)

* New translations AppResources.resx (Vietnamese)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Thai)

* New translations AppResources.resx (Swedish)

* New translations copy.resx (Spanish)

* New translations copy.resx (Spanish)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Czech)

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

* New translations AppResources.resx (Dutch)

* New translations copy.resx (Danish)

* New translations copy.resx (Danish)

* New translations AppResources.resx (Danish)

* New translations copy.resx (Czech)

* New translations copy.resx (Czech)

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

* New translations AppResources.resx (Croatian)

* New translations copy.resx (Chinese Traditional)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Chinese Simplified)

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

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Hindi)

* 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)

* New translations AppResources.resx (Finnish)

* New translations copy.resx (Vietnamese)
2019-01-15 20:26:21 -05:00
Kyle Spearrin
c4253e63d2 Revert "New Crowdin translations (#440)"
This reverts commit 0694721e68.
2019-01-15 20:19:27 -05:00
Kyle Spearrin
8c1dc9c4ae Revert "New Crowdin translations (#443)"
This reverts commit bfddb2b4d6.
2019-01-15 20:19:17 -05:00
Kyle Spearrin
bfddb2b4d6 New Crowdin translations (#443)
* New translations copy.resx (Danish)

* New translations copy.resx (Czech)

* New translations copy.resx (Chinese Traditional)

* New translations copy.resx (Vietnamese)

* New translations copy.resx (Spanish)

* New translations copy.resx (Portuguese, Brazilian)

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

* New translations copy.resx (Finnish)

* New translations copy.resx (Spanish)

* New translations copy.resx (Portuguese, Brazilian)

* New translations copy.resx (French)

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

* New translations copy.resx (Danish)

* New translations copy.resx (German)

* New translations copy.resx (French)

* New translations copy.resx (Finnish)

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

* New translations copy.resx (Czech)

* New translations copy.resx (Vietnamese)
2019-01-15 19:08:29 -05:00
Kyle Spearrin
b53ba52d05 en-gb support 2019-01-15 17:54:52 -05:00
Kyle Spearrin
0694721e68 New Crowdin translations (#440)
* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Romanian)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Vietnamese)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Thai)

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Czech)

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

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Danish)

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

* New translations AppResources.resx (Croatian)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Chinese Simplified)

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

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Hindi)

* New translations AppResources.resx (German)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Finnish)
2019-01-15 17:35:48 -05:00
Kyle Spearrin
bc0084cc8b bump version 2019-01-15 11:33:57 -05:00
Kyle Spearrin
d3d4cca0e8 remove analytics settings 2019-01-15 11:30:13 -05:00
Kyle Spearrin
5b6becc63f remove analytics 2019-01-15 11:19:31 -05:00
Kyle Spearrin
7ed015aeb1 dont sub 1 when getting next random value 2019-01-13 22:11:01 -05:00
Kyle Spearrin
a8b84da17f New Crowdin translations (#429)
* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Croatian)

* New translations copy.resx (Chinese Traditional)

* New translations copy.resx (Chinese Traditional)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (French)
2018-12-27 09:22:21 -05:00
Kyle Spearrin
2d687c98df dont return if no identity 2018-12-24 11:29:12 -05:00
Kyle Spearrin
9c2a6da692 add qwant browser to autofill 2018-12-19 16:16:45 -05:00
Kyle Spearrin
ee9ecfbee9 revert colorized password on password generator 2018-12-15 16:56:06 -05:00
Kyle Spearrin
9d8a9387bc copy model password, not label text 2018-12-12 08:21:15 -05:00
Kyle Spearrin
8934cebc2a update fingerprint lib 2018-12-11 17:06:26 -05:00
Kyle Spearrin
c03a42e108 disable all install scripts 2018-12-11 10:16:17 -05:00
Kyle Spearrin
a39dfcf4d5 disable cloc 2018-12-11 10:15:56 -05:00
Kyle Spearrin
f25ab537f2 clear focus on cell 2018-12-11 10:13:17 -05:00
kspearrin
ff776e485a new instance of deviceservice 2018-12-10 11:56:07 -05:00
Kyle Spearrin
3b9f4433ad ClearExtensionCiphersCache 2018-12-10 11:48:35 -05:00
Kyle Spearrin
a8c18cf83a FormattedPassword formatting 2018-12-10 09:42:58 -05:00
Kyle Spearrin
dff91dc67d no folder fixes for groupings display 2018-12-10 09:41:21 -05:00
Kyle Spearrin
fdea212415 formatting fixes 2018-12-10 09:41:10 -05:00
Andreas Schneider
421f7e8799 Colorized passwords (#424)
* Added utility to format passwords using spans

* Use the password formatter to render the cipher password

* Colorize the password in the password generator
2018-12-10 09:30:11 -05:00
Kyle Spearrin
8fc5ad099b name short 2018-12-06 14:49:26 -05:00
Kyle Spearrin
0b1c0be0f0 support for showing groupings on ciphers list page 2018-12-06 14:17:28 -05:00
Kyle Spearrin
5cc1e2bb29 only show top level groupings on main vault page 2018-12-05 17:26:16 -05:00
Kyle Spearrin
c0eb84b7b1 bump version 2018-12-03 22:24:07 -05:00
Kyle Spearrin
66e8d955d9 allow cleartextTrafficPermitted for base config 2018-12-02 13:06:35 -05:00
Farzad E
e280f585cf Honor user CA store when targeting Android Nougat SDK and later (#420)
* Included network-security-config.xml file to honor user added CAs (see:
https://android-developers.googleblog.com/2016/07/changes-to-trusted-certificate.html)

* Added domain-config entry to only use system CAs connecting to bitwarden.com

* Deny all plaintext traffic from network_security_config


Ref: https://developer.android.com/training/articles/security-config#CleartextTrafficPermitted
2018-12-02 08:56:16 -05:00
Kyle Spearrin
366578600b accessible typo 2018-11-30 11:28:35 -05:00
Kyle Spearrin
8611501423 nested tree node traversal helpers 2018-11-29 19:42:24 -05:00
Kyle Spearrin
8175af4e84 add steam support for otp generation 2018-11-29 17:10:51 -05:00
Kyle Spearrin
7ff628ea51 deprecate mac checks on RSA decrypt 2018-11-26 16:05:30 -05:00
Kyle Spearrin
5792372a47 bump version 2018-11-26 09:14:07 -05:00
Kyle Spearrin
9a169251d7 New Crowdin translations (#417)
* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (Portuguese)

* New translations copy.resx (Russian)

* New translations copy.resx (Russian)
2018-11-26 08:41:46 -05:00
Kyle Spearrin
2f0935dbbe update libs 2018-11-23 09:20:39 -05:00
Kyle Spearrin
5af7c7d58a Revert "comment out keyboard dismissal"
This reverts commit ed087b81b4.
2018-11-22 21:16:11 -05:00
Kyle Spearrin
9e1abb13a3 Revert "dont focus on cell tapped"
This reverts commit bbea5fe53c.
2018-11-22 21:16:02 -05:00
Kyle Spearrin
bbea5fe53c dont focus on cell tapped 2018-11-21 21:46:26 -05:00
Kyle Spearrin
ed087b81b4 comment out keyboard dismissal 2018-11-21 07:58:21 -05:00
Kyle Spearrin
0b06c87cb7 New Crowdin translations (#411)
* New translations AppResources.resx (German)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Romanian)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Spanish)
2018-11-20 22:48:03 -05:00
Kyle Spearrin
a9d204d3fa support attachment key, 100k iterations on regist. 2018-11-19 22:24:10 -05:00
Kyle Spearrin
36e263b9ff zh-HK gets traditional chinse 2018-11-15 08:23:45 -05:00
Kyle Spearrin
49af74729f update packages 2018-10-25 21:55:46 -04:00
Kyle Spearrin
aec0415cad New Crowdin translations (#398)
* New translations AppResources.resx (German)

* New translations AppResources.resx (Spanish)
2018-10-24 13:03:55 -04:00
Kyle Spearrin
8c8cec08e5 New Crowdin translations (#395)
* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (Turkish)
2018-10-16 08:58:57 -04:00
Kyle Spearrin
8d0ee1caba bump version 2018-10-09 09:39:44 -04:00
Kyle Spearrin
a2a6d5a57f New Crowdin translations (#389)
* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Ukrainian)
2018-10-09 09:29:07 -04:00
Kyle Spearrin
9593f330db target android sdk 26 with fixes to HybridWebView 2018-10-08 23:21:29 -04:00
Kyle Spearrin
144d932591 null ref check 2018-10-08 15:04:18 -04:00
Kyle Spearrin
726db336a8 dont try to fill unless has username and password 2018-10-07 07:40:44 -04:00
Kyle Spearrin
8632f7cadc version bump 2018-10-06 19:26:54 -04:00
Kyle Spearrin
525b5fa19a null checks 2018-10-06 17:28:40 -04:00
Kyle Spearrin
b7c6b65a3d bump version 2018-10-03 00:35:06 -04:00
kspearrin
a4f93eea45 ios < 12 fixes 2018-10-03 00:29:42 -04:00
Kyle Spearrin
8d9a5bc08f formatting 2018-10-01 14:37:16 -04:00
Kyle Spearrin
28a93cdcb4 bump version 2018-10-01 14:19:28 -04:00
Kyle Spearrin
d32dd95e12 add minimum os version 2018-10-01 14:19:28 -04:00
kspearrin
f19a8a3cc5 os version checks on auth service apis 2018-09-29 12:14:44 -04:00
Kyle Spearrin
f8d5ee9d5d bump version 2018-09-26 12:38:26 -04:00
kspearrin
a98fb7d41e back button should be white 2018-09-26 12:36:31 -04:00
kspearrin
d2ccc5c022 remove min os 2018-09-25 14:35:41 -04:00
Kyle Spearrin
3339c8b676 fix navbar color on setup 2018-09-24 16:59:05 -04:00
kspearrin
2cc331b136 support loginSearchSegue when no service ids 2018-09-24 16:34:50 -04:00
Kyle Spearrin
df1a65e6a3 fix color on search nav bar 2018-09-24 16:20:17 -04:00
Kyle Spearrin
f416f95b77 reuse code 2018-09-24 16:11:54 -04:00
kspearrin
44fe5af4fb run on main thread fixes 2018-09-24 15:45:36 -04:00
Kyle Spearrin
f394eddc01 throttle fast type searches 2018-09-24 15:30:05 -04:00
kspearrin
07dd9df3ec no search display controller 2018-09-24 15:24:43 -04:00
Kyle Spearrin
340d4ce714 do searching 2018-09-24 15:08:16 -04:00
kspearrin
2870b8331e text changed 2018-09-24 14:57:28 -04:00
Kyle Spearrin
bc79f22e22 implement search delegate 2018-09-24 14:51:37 -04:00
Kyle Spearrin
b3e0b148a6 not translucent 2018-09-24 12:50:58 -04:00
Kyle Spearrin
6131dfeb2c add tint colors to search nav bar 2018-09-24 12:43:19 -04:00
kspearrin
42fc868b68 Search controller for autofill setup 2018-09-24 12:41:08 -04:00
Kyle Spearrin
e9ec02929d Revert "add login search view controller"
This reverts commit 389d7d77c2.
2018-09-24 11:25:43 -04:00
Kyle Spearrin
389d7d77c2 add login search view controller 2018-09-24 11:24:12 -04:00
Kyle Spearrin
03a55d38d3 move power manager check inside try/catch 2018-09-23 08:08:38 -04:00
Kyle Spearrin
5504298251 adjust check green color 2018-09-22 23:49:47 -04:00
Kyle Spearrin
0fff61de34 New Crowdin translations (#374)
* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Romanian)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (Vietnamese)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Thai)

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Croatian)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (Hindi)

* New translations AppResources.resx (German)

* New translations AppResources.resx (French)
2018-09-22 23:45:30 -04:00
Kyle Spearrin
4db7311611 remove period 2018-09-22 23:43:36 -04:00
Kyle Spearrin
650d970b5e fix GA service methods 2018-09-22 23:37:44 -04:00
Kyle Spearrin
7f796963f3 no need to install sdk 28 anymore 2018-09-22 23:31:42 -04:00
Kyle Spearrin
9231da2f1c Revert "remove credential provider from main app entitle"
This reverts commit 0d422c53d1.
2018-09-22 23:22:48 -04:00
Kyle Spearrin
0d422c53d1 remove credential provider from main app entitle 2018-09-22 23:05:21 -04:00
kspearrin
7bf9354e32 provide credentials if using fingerprint too 2018-09-22 22:06:12 -04:00
kspearrin
277fd67814 add bitwarden domain 2018-09-22 21:58:50 -04:00
Kyle Spearrin
68e9cd3779 only copy totp key is setting not disabled 2018-09-21 23:32:26 -04:00
Kyle Spearrin
73b2ae71a9 copy totp code. derp 2018-09-21 23:29:05 -04:00
kspearrin
f9028245d8 better handle service identifiers 2018-09-21 22:27:20 -04:00
Kyle Spearrin
3fff0617fe replace all on updates 2018-09-21 21:59:11 -04:00
Kyle Spearrin
d958dc6bce replace vs created on save 2018-09-21 21:53:04 -04:00
Kyle Spearrin
045ce42168 add alert for autofill extension 2018-09-21 21:52:46 -04:00
kspearrin
edef84a4f9 return instead of else 2018-09-21 20:40:34 -04:00
kspearrin
ec9b2d7f7d add item to cred store when added from extension 2018-09-21 20:22:13 -04:00
Kyle Spearrin
640beeed23 delete cipher messages passes object 2018-09-21 17:04:54 -04:00
Kyle Spearrin
a998ee84ec fix strings 2018-09-21 16:26:55 -04:00
kspearrin
bd74634201 spacing 2018-09-21 16:25:31 -04:00
Kyle Spearrin
364287028b autofill instructions 2018-09-21 16:20:17 -04:00
Kyle Spearrin
7be8513bb5 updated autofill tools page strings 2018-09-21 16:11:11 -04:00
Kyle Spearrin
89c2f62f11 autofill tools page for ios 12 2018-09-21 16:03:34 -04:00
Kyle Spearrin
fce2a7ba94 cleanup and updated resource strings for autofill 2018-09-21 15:32:12 -04:00
kspearrin
e613198252 updated 2018-09-21 15:15:02 -04:00
Kyle Spearrin
3e240c4d2f setup view controller during config 2018-09-21 15:06:23 -04:00
kspearrin
eee96bf8cf config flow 2018-09-21 14:29:42 -04:00
Kyle Spearrin
471871eb2e done use this. 2018-09-21 12:45:32 -04:00
Kyle Spearrin
225b8b8cd8 Merge branch 'master' of github.com:bitwarden/mobile 2018-09-21 12:45:16 -04:00
kspearrin
cb2d133eb0 remove base calls 2018-09-21 12:00:44 -04:00
kspearrin
d957111249 remove base method calls 2018-09-21 12:00:07 -04:00
Kyle Spearrin
f0a701e134 formatting 2018-09-21 11:25:44 -04:00
kspearrin
0c8c216fba only build id store if authed 2018-09-21 11:23:34 -04:00
kspearrin
f153c7509c build identity store for quick type bar 2018-09-21 11:22:06 -04:00
Kyle Spearrin
197683b722 messages for credential store 2018-09-21 09:57:24 -04:00
Kyle Spearrin
fbce0be457 listen to messages for credential store updates 2018-09-20 23:54:03 -04:00
Kyle Spearrin
24304c2f55 formatting 2018-09-20 23:50:02 -04:00
Kyle Spearrin
b0c6c09cea full sync and cipher modification messages 2018-09-20 23:47:19 -04:00
kspearrin
2732fc93f9 provide credential implementations 2018-09-20 23:24:59 -04:00
Kyle Spearrin
cc9a4a288a fix analytics for autofill events 2018-09-20 23:02:53 -04:00
kspearrin
f57db917d1 wire up shared view controllers 2018-09-20 22:53:23 -04:00
Kyle Spearrin
d32eb9c9bc copy classes to autofill 2018-09-20 22:24:13 -04:00
Kyle Spearrin
219af7f288 extract extension table source 2018-09-20 22:18:25 -04:00
kspearrin
e767b6c5be missing using 2018-09-20 22:06:53 -04:00
Kyle Spearrin
5f1a8017f1 moved view controllers to core library for reuse 2018-09-20 21:54:01 -04:00
kspearrin
df80122ce1 moved cipher model 2018-09-20 16:44:41 -04:00
kspearrin
6904ea118b basic autofill 2018-09-20 16:44:06 -04:00
kspearrin
0baa07daa2 load ioc and stuff 2018-09-20 13:18:30 -04:00
kspearrin
2abf407b36 move to default storyboard from xcode 2018-09-20 12:53:53 -04:00
kspearrin
55dc9cbfc7 log debug 2018-09-20 09:29:48 -04:00
Kyle Spearrin
fa15a10ae0 entitle main project for autofill 2018-09-19 23:18:53 -04:00
Kyle Spearrin
e821d8a135 reference autofill project 2018-09-19 23:10:26 -04:00
kspearrin
cefcc14d4d update autofill files 2018-09-19 23:08:39 -04:00
Kyle Spearrin
a52d1e1506 autofill project 2018-09-19 22:25:16 -04:00
Kyle Spearrin
42df1aecd5 New Crowdin translations (#371)
* New translations AppResources.resx (Danish)

* New translations copy.resx (Danish)

* New translations copy.resx (Danish)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Korean)
2018-09-17 15:33:18 -04:00
Kyle Spearrin
920f4fc525 trim email 2018-09-15 23:36:32 -04:00
Kyle Spearrin
d57d583076 bump version 2018-09-14 16:36:38 -04:00
Kyle Spearrin
1c8cd2dcbb remove unused const strings 2018-09-12 15:53:27 -04:00
Kyle Spearrin
bb66a6c805 add firefox nightly, resolves #368 2018-09-10 08:17:22 -04:00
Kyle Spearrin
10ecdfbe31 add more autofill compat support 2018-09-06 00:17:26 -04:00
Kyle Spearrin
43dad1df63 dont need to rdp anymore 2018-09-05 17:37:05 -04:00
Kyle Spearrin
fdcc6b0cb8 change back to pwd, out-null 2018-09-05 17:19:53 -04:00
Kyle Spearrin
ac82d6bc6b update android using sdkmanager 2018-09-05 17:01:28 -04:00
Kyle Spearrin
a8e98cfa78 rdp for debugging 2018-09-05 16:37:13 -04:00
Kyle Spearrin
fa51314639 update-android for appveyor 2018-09-04 08:00:02 -04:00
Kyle Spearrin
3e0097c22c update android sdks on appveyor 2018-09-04 07:58:09 -04:00
Kyle Spearrin
e62ff2fe36 fix appveoyr yml 2018-09-03 23:05:54 -04:00
Kyle Spearrin
88a13eb54f update vs 2018-09-03 23:02:37 -04:00
Kyle Spearrin
355dc151c4 add more compat 2018-09-03 22:32:55 -04:00
Kyle Spearrin
4f0ea44078 update to android 9, test compat autofill mode. 2018-09-03 10:09:17 -04:00
Kyle Spearrin
9cc12fd577 check enabled too 2018-08-29 13:45:58 -04:00
Kyle Spearrin
960c2567bd can access premium for orgs 2018-08-29 12:36:44 -04:00
Kyle Spearrin
430e4dd445 rename UserPushNotification 2018-08-28 08:47:47 -04:00
Kyle Spearrin
1ec31c6899 add support for log out notification 2018-08-28 08:41:23 -04:00
Kyle Spearrin
42c21ce892 PBKDF2 is SHA256 2018-08-28 08:41:23 -04:00
kspearrin
d278fde5f2 fix missing params on extension 2018-08-24 17:10:52 -04:00
Kyle Spearrin
2616a5f500 bump versions 2018-08-21 16:29:31 -04:00
BestPig
cc58f7730e Use BaseUrl when opening web vault if defined (#360) 2018-08-20 13:32:16 -04:00
Kyle Spearrin
d49e001b21 New Crowdin translations (#358)
* New translations AppResources.resx (Croatian)

* New translations AppResources.resx (Danish)

* New translations copy.resx (Danish)

* New translations copy.resx (Danish)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (French)

* New translations copy.resx (French)

* New translations copy.resx (French)

* New translations AppResources.resx (Portuguese, Brazilian)
2018-08-16 15:18:21 -04:00
Kyle Spearrin
f12ceb69ce update public suffix list 2018-08-15 08:44:21 -04:00
Kyle Spearrin
7862005055 support for prelogin kdf params 2018-08-14 16:46:31 -04:00
Kyle Spearrin
e70dbf8d8d add UmAlQuraCalendar 2018-08-13 07:55:26 -04:00
Kyle Spearrin
16ee34d7a7 set calendars removed by linker 2018-08-13 07:54:08 -04:00
Kyle Spearrin
2ad55e8a8c New Crowdin translations (#353)
* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (German)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Ukrainian)
2018-08-09 17:34:58 -04:00
Kyle Spearrin
a8a1750d5c version bump 2018-08-09 11:48:10 -04:00
Kyle Spearrin
5407e20150 update libs 2018-08-04 00:55:01 -04:00
Kyle Spearrin
58aa37bf8e catch EnableForegroundDispatch exception. disable
back button on yubikey 2fa.
2018-08-01 15:45:32 -04:00
Kyle Spearrin
7c781b60c5 add protocol if missing 2018-08-01 15:32:12 -04:00
Kyle Spearrin
acdfce7e88 support otpath:// totp secrets 2018-07-31 12:34:10 -04:00
Kyle Spearrin
4e4b56d7fe password updated fixes 2018-07-30 22:42:54 -04:00
Kyle Spearrin
a3174d7015 New Crowdin translations (#349)
* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Romanian)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (Vietnamese)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Thai)

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Croatian)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (Hindi)

* New translations AppResources.resx (German)

* New translations AppResources.resx (French)
2018-07-30 17:14:39 -04:00
Kyle Spearrin
b595c8aeac contrib updates 2018-07-30 17:07:44 -04:00
Kyle Spearrin
a9a33ad71e save password history changes 2018-07-30 16:15:36 -04:00
Kyle Spearrin
4d08ce90cc Merge branch 'master' of github.com:bitwarden/mobile 2018-07-30 13:16:04 -04:00
Kyle Spearrin
01d9ccc110 add password history and updated dates 2018-07-30 13:15:53 -04:00
Jacob
029f069ad5 fetch image from bitwarden/brand (#345) 2018-07-19 10:51:15 -04:00
Kyle Spearrin
13b9e01604 check lock only if locked on all pages 2018-07-16 23:14:45 -04:00
Kyle Spearrin
19c46a472a fix name bug on section group names 2018-07-16 10:24:53 -04:00
Kyle Spearrin
37edfffb97 move last launch check after _lastQueriedUri 2018-07-16 10:17:05 -04:00
Kyle Spearrin
67fa653d06 prevent multiple main activities from autofill 2018-07-16 10:07:22 -04:00
Kyle Spearrin
366b9ddc4a update libs. update android security provider 2018-07-16 08:55:37 -04:00
Kyle Spearrin
c9354f79b8 add escosia browser autofill 2018-07-16 08:40:38 -04:00
Kyle Spearrin
d5b3bd5905 remove no connection alert on appearing of pages 2018-07-12 13:12:42 -04:00
Kyle Spearrin
45dd240415 include some type info with extension exception 2018-06-30 08:55:54 -04:00
Kyle Spearrin
bf99cea004 possible null pointer fix 2018-06-30 08:19:18 -04:00
Kyle Spearrin
f680b1e856 update libs 2018-06-30 00:06:41 -04:00
Kyle Spearrin
b2f40c7af0 fix track bug 2018-06-29 15:26:46 -04:00
Kyle Spearrin
82b17677b9 default track is alpha 2018-06-29 15:24:19 -04:00
Kyle Spearrin
b7df2d5441 rollout track 2018-06-29 15:05:40 -04:00
Kyle Spearrin
dd511ba365 tracks are now strings 2018-06-29 15:04:34 -04:00
Kyle Spearrin
d705e3c1fb version bump 2018-06-29 14:19:35 -04:00
Kyle Spearrin
4bd1322904 update libs 2018-06-29 14:09:53 -04:00
Kyle Spearrin
ac027ee3a0 add support for kiwi browser 2018-06-29 13:48:47 -04:00
Kyle Spearrin
e5e3ebdbba update to Xamarin forms 3.1 2018-06-29 12:45:10 -04:00
Kyle Spearrin
993fc2e6f4 bump version 2018-06-29 10:42:28 -04:00
Kyle Spearrin
61c480618c try to generate key with and without date 2018-06-29 10:39:29 -04:00
Kyle Spearrin
db7f2622c8 org.chromium.chrome support 2018-06-28 23:33:34 -04:00
1981 changed files with 243395 additions and 95880 deletions

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

@@ -0,0 +1,18 @@
{
"version": 1,
"isRoot": true,
"tools": {
"dotnet-format": {
"version": "5.1.250801",
"commands": [
"dotnet-format"
]
},
"cake.tool": {
"version": "2.2.0",
"commands": [
"dotnet-cake"
]
}
}
}

113
.editorconfig Normal file
View File

@@ -0,0 +1,113 @@
# EditorConfig is awesome: http://EditorConfig.org
# top-most EditorConfig file
root = true
# Don't use tabs for indentation.
[*]
indent_style = space
end_of_line = lf
# (Please don't specify an indent_size here; that has too many unintended consequences.)
# Code files
[*.{cs,csx,vb,vbx}]
indent_size = 4
insert_final_newline = true
charset = utf-8-bom
# Xml project files
[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}]
indent_size = 2
# Xml config files
[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}]
indent_size = 2
# JSON files
[*.json]
indent_size = 2
# Dotnet code style settings:
[*.{cs,vb}]
# Sort using and Import directives with System.* appearing first
dotnet_sort_system_directives_first = true
# Avoid "this." and "Me." if not necessary
dotnet_style_qualification_for_field = false:suggestion
dotnet_style_qualification_for_property = false:suggestion
dotnet_style_qualification_for_method = false:suggestion
dotnet_style_qualification_for_event = false:suggestion
# Use language keywords instead of framework type names for type references
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
dotnet_style_predefined_type_for_member_access = true:suggestion
# Suggest more modern language features when available
dotnet_style_object_initializer = true:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_explicit_tuple_names = true:suggestion
# Prefix private members with underscore
dotnet_naming_rule.private_members_with_underscore.symbols = private_members
dotnet_naming_rule.private_members_with_underscore.style = underscore_prefix
dotnet_naming_rule.private_members_with_underscore.severity = suggestion
dotnet_naming_symbols.private_members.applicable_kinds = field
dotnet_naming_symbols.private_members.applicable_accessibilities = private
dotnet_naming_symbols.private_members.required_modifiers = readonly
dotnet_naming_style.underscore_prefix.capitalization = camel_case
dotnet_naming_style.underscore_prefix.required_prefix = _
dotnet_naming_style.underscore_prefix.required_suffix =
dotnet_naming_style.underscore_prefix.word_separator =
# Async methods should have "Async" suffix
dotnet_naming_rule.async_methods_end_in_async.symbols = any_async_methods
dotnet_naming_rule.async_methods_end_in_async.style = end_in_async
dotnet_naming_rule.async_methods_end_in_async.severity = suggestion
dotnet_naming_symbols.any_async_methods.applicable_kinds = method
dotnet_naming_symbols.any_async_methods.applicable_accessibilities = *
dotnet_naming_symbols.any_async_methods.required_modifiers = async
dotnet_naming_style.end_in_async.required_prefix =
dotnet_naming_style.end_in_async.required_suffix = Async
dotnet_naming_style.end_in_async.capitalization = pascal_case
dotnet_naming_style.end_in_async.word_separator =
# CSharp code style settings:
[*.cs]
# Prefer "var" everywhere
csharp_style_var_for_built_in_types = true:suggestion
csharp_style_var_when_type_is_apparent = true:suggestion
csharp_style_var_elsewhere = true:suggestion
# Prefer method-like constructs to have a expression-body
csharp_style_expression_bodied_methods = true:none
csharp_style_expression_bodied_constructors = true:none
csharp_style_expression_bodied_operators = true:none
# Prefer property-like constructs to have an expression-body
csharp_style_expression_bodied_properties = true:none
csharp_style_expression_bodied_indexers = true:none
csharp_style_expression_bodied_accessors = true:none
# Suggest more modern language features when available
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
csharp_style_inlined_variable_declaration = true:suggestion
csharp_style_throw_expression = true:suggestion
csharp_style_conditional_delegate_call = true:suggestion
# Newline settings
csharp_new_line_before_open_brace = all
csharp_new_line_before_else = true
csharp_new_line_before_catch = true
csharp_new_line_before_finally = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_members_in_anonymous_types = true
# All files
[*]
guidelines = 120

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

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

63
.gitattributes vendored Normal file
View File

@@ -0,0 +1,63 @@
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto eol=lf
###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp
###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary
###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary
###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain

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

@@ -0,0 +1,81 @@
name: Bug Report
description: File a bug report
labels: [bug]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report!
Please do not submit feature requests. The [Community Forums](https://community.bitwarden.com) has a section for submitting, voting for, and discussing product feature requests.
- type: textarea
id: reproduce
attributes:
label: Steps To Reproduce
description: How can we reproduce the behavior.
value: |
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. Click on '...'
validations:
required: true
- type: textarea
id: expected
attributes:
label: Expected Result
description: A clear and concise description of what you expected to happen.
validations:
required: true
- type: textarea
id: actual
attributes:
label: Actual Result
description: A clear and concise description of what is happening.
validations:
required: true
- type: textarea
id: screenshots
attributes:
label: Screenshots or Videos
description: If applicable, add screenshots and/or a short video to help explain your problem.
- type: textarea
id: additional-context
attributes:
label: Additional Context
description: Add any other context about the problem here.
- type: dropdown
id: os
attributes:
label: Operating System
description: What operating system are you seeing the problem on?
multiple: true
options:
- Android
- iOS
validations:
required: true
- type: input
id: os-version
attributes:
label: Operating System Version
description: What version of the operating system(s) are you seeing the problem on?
- type: input
id: device
attributes:
label: Device
description: Which device are you seeing the problem on?
placeholder: iPhone 12, Samsung Galaxy S10
- type: input
id: version
attributes:
label: Build Version
description: What version of our software are you running? (go to "Settings" → "About" in the app)
validations:
required: true
- type: checkboxes
id: beta
attributes:
label: Beta
options:
- label: Using a pre-release version of the application.

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

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

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

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

22
.github/renovate.json vendored Normal file
View File

@@ -0,0 +1,22 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:base",
"schedule:monthly",
":maintainLockFilesMonthly",
":preserveSemverRanges",
":rebaseStalePrs",
":disableDependencyDashboard"
],
"enabledManagers": [
"nuget"
],
"packageRules": [
{
"matchManagers": ["nuget"],
"groupName": "Nuget updates",
"groupSlug": "nuget",
"separateMajorMinor": false
}
]
}

View File

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

View File

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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

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

Binary file not shown.

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

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,64 @@
---
name: Automatic responses
on:
issues:
types:
- labeled
jobs:
close-issue:
name: 'Close issue with automatic response'
runs-on: ubuntu-20.04
permissions:
issues: write
steps:
# Feature request
- if: github.event.label.name == 'feature-request'
name: Feature request
uses: peter-evans/close-issue@849549ba7c3a595a064c4b2c56f206ee78f93515 # v2.0.0
with:
comment: |
We use GitHub issues as a place to track bugs and other development related issues. The [Bitwarden Community Forums](https://community.bitwarden.com/) has a [Feature Requests](https://community.bitwarden.com/c/feature-requests) section for submitting, voting for, and discussing requests like this one.
Please [sign up on our forums](https://community.bitwarden.com/signup) and search to see if this request already exists. If so, you can vote for it and contribute to any discussions about it. If not, you can re-create the request there so that it can be properly tracked.
This issue will now be closed. Thanks!
# Intended behavior
- if: github.event.label.name == 'intended-behavior'
name: Intended behaviour
uses: peter-evans/close-issue@849549ba7c3a595a064c4b2c56f206ee78f93515 # v2.0.0
with:
comment: |
Your issue appears to be describing the intended behavior of the software. If you want this to be changed, it would be a feature request.
We use GitHub issues as a place to track bugs and other development related issues. The [Bitwarden Community Forums](https://community.bitwarden.com/) has a [Feature Requests](https://community.bitwarden.com/c/feature-requests) section for submitting, voting for, and discussing requests like this one.
Please [sign up on our forums](https://community.bitwarden.com/signup) and search to see if this request already exists. If so, you can vote for it and contribute to any discussions about it. If not, you can re-create the request there so that it can be properly tracked.
This issue will now be closed. Thanks!
# Customer support request
- if: github.event.label.name == 'customer-support'
name: Customer Support request
uses: peter-evans/close-issue@849549ba7c3a595a064c4b2c56f206ee78f93515 # v2.0.0
with:
comment: |
We use GitHub issues as a place to track bugs and other development related issues. Your issue appears to be a support request, or would otherwise be better handled by our dedicated Customer Success team.
Please contact us using our [Contact page](https://bitwarden.com/contact). You can include a link to this issue in the message content.
Alternatively, you can also search for an answer in our [help documentation](https://bitwarden.com/help/) or get help from other Bitwarden users on our [community forums](https://community.bitwarden.com/c/support/). The issue here will be closed.
# Resolved
- if: github.event.label.name == 'resolved'
name: Resolved
uses: peter-evans/close-issue@849549ba7c3a595a064c4b2c56f206ee78f93515 # v2.0.0
with:
comment: |
Weve closed this issue, as it appears the original problem has been resolved. If this happens again or continues to be an problem, please respond to this issue with any additional detail to assist with reproduction and root cause analysis.
# Stale
- if: github.event.label.name == 'stale'
name: Stale
uses: peter-evans/close-issue@849549ba7c3a595a064c4b2c56f206ee78f93515 # v2.0.0
with:
comment: |
As we havent heard from you about this problem in some time, this issue will now be closed.
If this happens again or continues to be an problem, please respond to this issue with any additional detail to assist with reproduction and root cause analysis.

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

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

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

@@ -0,0 +1,51 @@
---
name: Crowdin Sync
on:
workflow_dispatch:
inputs: {}
schedule:
- cron: '0 0 * * 5'
jobs:
crowdin-sync:
name: Autosync
runs-on: ubuntu-20.04
env:
_CROWDIN_PROJECT_ID: "269690"
steps:
- name: Checkout repo
uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
- name: Login to Azure
uses: Azure/login@77f1b2e3fb80c0e8645114159d17008b8a2e475a
with:
creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }}
- name: Retrieve secrets
id: retrieve-secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@c3b3285993151c5af47cefcb3b9134c28ab479af
with:
keyvault: "bitwarden-prod-kv"
secrets: "crowdin-api-token, github-gpg-private-key, github-gpg-private-key-passphrase"
- name: Download translations
uses: crowdin/github-action@12143a68c213f3c6d9913c9e5023224f7231face
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }}
with:
config: crowdin.yml
crowdin_branch_name: master
upload_sources: false
upload_translations: false
download_translations: true
github_user_name: "bitwarden-devops-bot"
github_user_email: "106330231+bitwarden-devops-bot@users.noreply.github.com"
commit_message: "Autosync the updated translations"
localization_branch_name: crowdin-auto-sync
create_pull_request: true
pull_request_title: "Autosync Crowdin Translations"
pull_request_body: "Autosync the updated translations"
gpg_private_key: ${{ steps.retrieve-secrets.outputs.github-gpg-private-key }}
gpg_passphrase: ${{ steps.retrieve-secrets.outputs.github-gpg-private-key-passphrase }}

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

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

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

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

30
.github/workflows/stale-bot.yml vendored Normal file
View File

@@ -0,0 +1,30 @@
---
name: 'Close stale issues and PRs'
on:
workflow_dispatch:
schedule: # Run once a day at 5.23am (arbitrary but should avoid peak loads on the hour)
- cron: '23 5 * * *'
jobs:
stale:
name: 'Check for stale issues and PRs'
runs-on: ubuntu-20.04
steps:
- name: 'Run stale action'
uses: actions/stale@3cc123766321e9f15a6676375c154ccffb12a358 # v5.0.0
with:
stale-issue-label: 'needs-reply'
stale-pr-label: 'needs-changes'
days-before-stale: -1 # Do not apply the stale labels automatically, this is a manual process
days-before-issue-close: 14 # Close issue if no further activity after X days
days-before-pr-close: 21 # Close PR if no further activity after X days
close-issue-message: |
We need more information before we can help you with your problem. As we havent heard from you recently, this issue will be closed.
If this happens again or continues to be an problem, please respond to this issue with the information weve requested and anything else relevant.
close-pr-message: |
We cant merge your pull request until you make the changes weve requested. As we havent heard from you recently, this pull request will be closed.
If youre still working on this, please respond here after youve made the changes weve requested and our team will re-open it for further review.
Please make sure to resolve any conflicts with the master branch before requesting another review.

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

@@ -0,0 +1,63 @@
---
name: Version Auto Bump
on:
push:
tags:
- v**
jobs:
setup:
name: "Setup"
runs-on: ubuntu-22.04
outputs:
version_number: ${{ steps.version.outputs.new-version }}
steps:
- name: Checkout Branch
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Calculate bumped version
id: version
env:
RELEASE_TAG: ${{ github.ref }}
run: |
CURR_MAJOR=$(echo $RELEASE_TAG | sed -r 's/v([0-9]{4}\.[0-9]{1,2})\.([0-9]{1,2})/\1/')
CURR_PATCH=$(echo $RELEASE_TAG | sed -r 's/v([0-9]{4}\.[0-9]{1,2})\.([0-9]{1,2})/\2/')
echo "Current Major: $CURR_MAJOR"
echo "Current Patch: $CURR_PATCH"
NEW_PATCH=$((CURR_PATCH+1))
NEW_VER=$CURR_MAJOR.$NEW_PATCH
echo "New Version: $NEW_VER"
echo "::set-output name=new-version::$NEW_VER"
trigger_version_bump:
name: "Trigger version bump workflow"
runs-on: ubuntu-22.04
needs:
- setup
steps:
- name: Login to Azure
uses: Azure/login@ec3c14589bd3e9312b3cc8c41e6860e258df9010
with:
creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }}
- name: Retrieve secrets
id: retrieve-secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@c3b3285993151c5af47cefcb3b9134c28ab479af
with:
keyvault: "bitwarden-prod-kv"
secrets: "github-pat-bitwarden-devops-bot-repo-scope"
- name: Call GitHub API to trigger workflow bump
env:
TOKEN: ${{ steps.retrieve-secrets.outputs.github-pat-bitwarden-devops-bot-repo-scope }}
VERSION: ${{ needs.setup.outputs.version_number}}
run: |
JSON_STRING=$(printf '{"ref":"master", "inputs": { "version_number":"%s"}}' "$VERSION")
curl \
-X POST \
-i -u bitwarden-devops-bot:$TOKEN \
-H "Accept: application/vnd.github.v3+json" \
https://api.github.com/repos/bitwarden/mobile/actions/workflows/version-bump.yml/dispatches \
-d $JSON_STRING

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

@@ -0,0 +1,119 @@
---
name: Version Bump
on:
workflow_dispatch:
inputs:
version_number:
description: "New Version"
required: true
jobs:
bump_version:
name: "Create version_bump_${{ github.event.inputs.version_number }} branch"
runs-on: ubuntu-20.04
steps:
- name: Checkout Branch
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Login to Azure - Prod Subscription
uses: Azure/login@1f63701bf3e6892515f1b7ce2d2bf1708b46beaf
with:
creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }}
- name: Retrieve secrets
id: retrieve-secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@c3b3285993151c5af47cefcb3b9134c28ab479af
with:
keyvault: "bitwarden-prod-kv"
secrets: "github-gpg-private-key, github-gpg-private-key-passphrase"
- name: Import GPG key
uses: crazy-max/ghaction-import-gpg@c8bb57c57e8df1be8c73ff3d59deab1dbc00e0d1
with:
gpg_private_key: ${{ steps.retrieve-secrets.outputs.github-gpg-private-key }}
passphrase: ${{ steps.retrieve-secrets.outputs.github-gpg-private-key-passphrase }}
git_user_signingkey: true
git_commit_gpgsign: true
- name: Create Version Branch
run: |
git switch -c version_bump_${{ github.event.inputs.version_number }}
- name: Bump Version - Android XML
uses: bitwarden/gh-actions/version-bump@03ad9a873c39cdc95dd8d77dbbda67f84db43945
with:
version: ${{ github.event.inputs.version_number }}
file_path: "./src/Android/Properties/AndroidManifest.xml"
- name: Bump Version - iOS.Autofill
uses: bitwarden/gh-actions/version-bump@03ad9a873c39cdc95dd8d77dbbda67f84db43945
with:
version: ${{ github.event.inputs.version_number }}
file_path: "./src/iOS.Autofill/Info.plist"
- name: Bump Version - iOS.Extension
uses: bitwarden/gh-actions/version-bump@03ad9a873c39cdc95dd8d77dbbda67f84db43945
with:
version: ${{ github.event.inputs.version_number }}
file_path: "./src/iOS.Extension/Info.plist"
- name: Bump Version - iOS.ShareExtension
uses: bitwarden/gh-actions/version-bump@03ad9a873c39cdc95dd8d77dbbda67f84db43945
with:
version: ${{ github.event.inputs.version_number }}
file_path: "./src/iOS.ShareExtension/Info.plist"
- name: Bump Version - iOS
uses: bitwarden/gh-actions/version-bump@03ad9a873c39cdc95dd8d77dbbda67f84db43945
with:
version: ${{ github.event.inputs.version_number }}
file_path: "./src/iOS/Info.plist"
- name: Setup git
run: |
git config --local user.email "106330231+bitwarden-devops-bot@users.noreply.github.com"
git config --local user.name "bitwarden-devops-bot"
- name: Check if version changed
id: version-changed
run: |
if [ -n "$(git status --porcelain)" ]; then
echo "::set-output name=changes_to_commit::TRUE"
else
echo "::set-output name=changes_to_commit::FALSE"
echo "No changes to commit!";
fi
- name: Commit files
if: ${{ steps.version-changed.outputs.changes_to_commit == 'TRUE' }}
run: |
git commit -m "Bumped version to ${{ github.event.inputs.version_number }}" -a
- name: Push changes
if: ${{ steps.version-changed.outputs.changes_to_commit == 'TRUE' }}
run: git push -u origin version_bump_${{ github.event.inputs.version_number }}
- name: Create Version PR
if: ${{ steps.version-changed.outputs.changes_to_commit == 'TRUE' }}
env:
PR_BRANCH: "version_bump_${{ github.event.inputs.version_number }}"
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
BASE_BRANCH: master
TITLE: "Bump version to ${{ github.event.inputs.version_number }}"
run: |
gh pr create --title "$TITLE" \
--base "$BASE" \
--head "$PR_BRANCH" \
--label "version update" \
--label "automated pr" \
--body "
## Type of change
- [ ] Bug fix
- [ ] New feature development
- [ ] Tech debt (refactoring, code cleanup, dependency upgrades, etc)
- [ ] Build/deploy pipeline (DevOps)
- [X] Other
## Objective
Automated version bump to ${{ github.event.inputs.version_number }}"

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

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

24
.gitignore vendored
View File

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

1
CNAME Normal file
View File

@@ -0,0 +1 @@
mobileapp.bitwarden.com

View File

@@ -1,13 +1,3 @@
Code contributions are welcome! Please commit any pull requests against the `master` branch.
# How to Contribute
# Localization (l10n)
[![Crowdin](https://d322cqt584bo4o.cloudfront.net/bitwarden-mobile/localized.svg)](https://crowdin.com/project/bitwarden-mobile)
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 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).
You can read Crowdin's getting started guide for translators here: https://support.crowdin.com/crowdin-intro/
Our [Contributing Guidelines](https://contributing.bitwarden.com/contributing/) are located in our [Contributing Documentation](https://contributing.bitwarden.com/). The documentation also includes recommended tooling, code style tips, and lots of other great information to get you started.

View File

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

View File

@@ -1,34 +1,37 @@
[![appveyor build](https://ci.appveyor.com/api/projects/status/github/bitwarden/mobile?branch=master&svg=true)](https://ci.appveyor.com/project/bitwarden/mobile)
[![Github Workflow build on master](https://github.com/bitwarden/mobile/actions/workflows/build.yml/badge.svg?branch=master)](https://github.com/bitwarden/mobile/actions/workflows/build.yml?query=branch:master)
[![Crowdin](https://d322cqt584bo4o.cloudfront.net/bitwarden-mobile/localized.svg)](https://crowdin.com/project/bitwarden-mobile)
[![Join the chat at https://gitter.im/bitwarden/Lobby](https://badges.gitter.im/bitwarden/Lobby.svg)](https://gitter.im/bitwarden/Lobby)
# 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>
<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://mobileapp.bitwarden.com/fdroid/" target="_blank"><img alt="Get it on Google Play" src="https://i.imgur.com/HDicnzz.png" width="154" 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, UWP, and Xamarin Forms.
The Bitwarden mobile application is written in C# with Xamarin Android, Xamarin iOS, and Xamarin Forms.
<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" />
<img src="https://raw.githubusercontent.com/bitwarden/brand/master/screenshots/mobile-android-myvault.png" alt="" width="325" height="650" /> <img src="https://raw.githubusercontent.com/bitwarden/brand/master/screenshots/mobile-ios-myvault.png" alt="" width="300" height="650" />
# Build/Run
**Requirements**
Please refer to the [Mobile section](https://contributing.bitwarden.com/mobile/) of the [Contributing Documentation](https://contributing.bitwarden.com/) for build instructions, recommended tooling, code style tips, and lots of other great information to get you started.
- [Visual Studio](https://store.xamarin.com/)
# We're Hiring!
**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.
Interested in contributing in a big way? Consider joining our team! We're hiring for many positions. Please take a look at our [Careers page](https://bitwarden.com/careers/) to see what opportunities are currently open as well as what it's like to work at Bitwarden.
# Contribute
Code contributions are welcome! Visual Studio or Xamarin Studio is required to work on this project. Please commit any pull requests against the `master` branch.
Learn more about how to contribute by reading the [`CONTRIBUTING.md`](CONTRIBUTING.md) file.
Code contributions are welcome! Please commit any pull requests against the `master` branch. Learn more about how to contribute by reading the [Contributing Guidelines](https://contributing.bitwarden.com/contributing/). Check out the [Contributing Documentation](https://contributing.bitwarden.com/) for how to get started with your first contribution.
Security audits and feedback are welcome. Please open an issue or email us privately if the report is sensitive in nature. You can read our security policy in the [`SECURITY.md`](SECURITY.md) file.
### Dotnet-format
We recently migrated to using dotnet-format as code formatter. All previous branches will need to updated to avoid large merge conflicts using the following steps:
1. Check out your local Branch
2. Run `git merge e0efcfbe45b2a27c73e9593bfd7a71fad2aa7a35`
3. Resolve any merge conflicts, commit.
4. Run `dotnet tool run dotnet-format`
5. Commit
6. Run `git merge -Xours 04539af2a66668b6e85476d5cf318c9150ec4357`
7. Push

View File

@@ -1,39 +1,11 @@
Bitwarden believes that working with security researchers across the globe is crucial to keeping our
users safe. If you believe you've found a security issue in our product or service, we encourage you to
notify us. We welcome working with you to resolve the issue promptly. Thanks in advance!
Bitwarden believes that working with security researchers across the globe is crucial to keeping our users safe. If you believe you've found a security issue in our product or service, we encourage you to please submit a report through our [HackerOne Program](https://hackerone.com/bitwarden/). We welcome working with you to resolve the issue promptly. Thanks in advance!
# Disclosure Policy
- Let us know as soon as possible upon discovery of a potential security issue, and we'll make every
effort to quickly resolve the issue.
- Provide us a reasonable amount of time to resolve the issue before any disclosure to the public or a
third-party. We may publicly disclose the issue before resolving it, if appropriate.
- Make a good faith effort to avoid privacy violations, destruction of data, and interruption or
degradation of our service. Only interact with accounts you own or with explicit permission of the
account holder.
- If you would like to encrypt your report, please use the PGP key with long ID
`0xDE6887086F892325FEC04CC0D847525B6931381F` (available in the public keyserver pool).
# In-scope
- Security issues in any current release of Bitwarden. This includes the web vault, browser extension,
and mobile apps (iOS and Android). Product downloads are available at https://bitwarden.com. Source
code is available at https://github.com/bitwarden.
# Exclusions
The following bug classes are out-of scope:
- Bugs that are already reported on any of Bitwarden's issue trackers (https://github.com/bitwarden),
or that we already know of. Note that some of our issue tracking is private.
- Issues in an upstream software dependency (ex: Xamarin, ASP.NET) which are already reported to the
upstream maintainer.
- Attacks requiring physical access to a user's device.
- Self-XSS
- Issues related to software or protocols not under Bitwarden's control
- Vulnerabilities in outdated versions of Bitwarden
- Missing security best practices that do not directly lead to a vulnerability
- Issues that do not have any impact on the general public
- Let us know as soon as possible upon discovery of a potential security issue, and we'll make every effort to quickly resolve the issue.
- Provide us a reasonable amount of time to resolve the issue before any disclosure to the public or a third-party. We may publicly disclose the issue before resolving it, if appropriate.
- Make a good faith effort to avoid privacy violations, destruction of data, and interruption or degradation of our service. Only interact with accounts you own or with explicit permission of the account holder.
- If you would like to encrypt your report, please use the PGP key with long ID `0xDE6887086F892325FEC04CC0D847525B6931381F` (available in the public keyserver pool).
While researching, we'd like to ask you to refrain from:
@@ -42,4 +14,8 @@ While researching, we'd like to ask you to refrain from:
- Social engineering (including phishing) of Bitwarden staff or contractors
- Any physical attempts against Bitwarden property or data centers
# We want to help you!
If you have something that you feel is close to exploitation, or if you'd like some information regarding the internal API, or generally have any questions regarding the app that would help in your efforts, please email us at https://bitwarden.com/contact and ask for that information. As stated above, Bitwarden wants to help you find issues, and is more than willing to help.
Thank you for helping keep Bitwarden and our users safe!

View File

@@ -1,24 +0,0 @@
install:
- choco install cloc --no-progress
- "cloc --vcs git --exclude-dir Resources,store,test,UWP,Properties --include-lang C#,JavaScript,TypeScript,PowerShell"
# - appveyor DownloadFile https://dist.nuget.org/win-x86-commandline/latest/nuget.exe
# - appveyor DownloadFile https://aka.ms/vs/15/release/vs_community.exe
# - vs_community.exe update --wait --quiet --norestart --installPath "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community"
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\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\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,476 +1,471 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.2010
# Visual Studio Version 16
VisualStudioVersion = 16.0.29009.5
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Android", "src\Android\Android.csproj", "{04B18ED2-B76D-4947-8474-191F8FD2B5E0}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Android", "src\Android\Android.csproj", "{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS", "src\iOS\iOS.csproj", "{1F78403F-9A28-405B-9289-B9DBEB55F074}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "App", "src\App\App.csproj", "{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{0D790714-ECF8-4A83-BE4A-E9C84DD1BB5D}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Core", "src\Core\Core.csproj", "{4B8A8C41-9820-4341-974C-41E65B7F4366}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{EC730FD9-F623-4B6C-B503-95CDCFBCF277}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Playground", "test\Playground\Playground.csproj", "{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "App.Test", "test\App.Test\App.Test.csproj", "{A300DCE1-8D10-4267-B96A-CB01AEB7C220}"
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{D10CA4A9-F866-40E1-B658-F69051236C71}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.Extension", "src\iOS.Extension\iOS.Extension.csproj", "{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.Core", "src\iOS.Core\iOS.Core.csproj", "{B2538ADA-B605-4D6F-ACD2-62A409680F84}"
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{8904C536-C67D-420F-9971-51B26574C3AA}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "store", "store", "{92470CBD-9047-4C3C-8EA3-D972D6622D84}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "google", "google", "{2E399654-26A2-46F6-B9CA-1B496A3F370A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "App", "src\App\App.csproj", "{8A279EE4-4537-4656-9C93-44945E594556}"
EndProject
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}"
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{76690DFB-B7F4-4781-83E4-113FDC450AFE}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
.gitignore = .gitignore
appveyor.yml = appveyor.yml
.github\workflows\build.yml = .github\workflows\build.yml
CONTRIBUTING.md = CONTRIBUTING.md
crowdin.yml = crowdin.yml
README.md = README.md
SECURITY.md = SECURITY.md
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Publisher", "store\google\Publisher\Publisher.csproj", "{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.Core", "src\iOS.Core\iOS.Core.csproj", "{E71F3053-056C-4381-9638-048ED73BDFF6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS", "src\iOS\iOS.csproj", "{599E0201-420A-4C3E-A7BA-5349F72E0B15}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.Extension", "src\iOS.Extension\iOS.Extension.csproj", "{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common", "test\Common\Common.csproj", "{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core.Test", "test\Core.Test\Core.Test.csproj", "{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.ShareExtension", "src\iOS.ShareExtension\iOS.ShareExtension.csproj", "{F8C3F648-EA5A-4719-8005-85D1690B1655}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.Autofill", "src\iOS.Autofill\iOS.Autofill.csproj", "{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Ad-Hoc|Any CPU = Ad-Hoc|Any CPU
Ad-Hoc|ARM = Ad-Hoc|ARM
Ad-Hoc|iPhone = Ad-Hoc|iPhone
Ad-Hoc|iPhoneSimulator = Ad-Hoc|iPhoneSimulator
Ad-Hoc|x64 = Ad-Hoc|x64
Ad-Hoc|x86 = Ad-Hoc|x86
AppStore|Any CPU = AppStore|Any CPU
AppStore|ARM = AppStore|ARM
AppStore|iPhone = AppStore|iPhone
AppStore|iPhoneSimulator = AppStore|iPhoneSimulator
AppStore|x64 = AppStore|x64
AppStore|x86 = AppStore|x86
Debug|Any CPU = Debug|Any CPU
Debug|ARM = Debug|ARM
Debug|iPhone = Debug|iPhone
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
Release|iPhoneSimulator = Release|iPhoneSimulator
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Ad-Hoc|Any CPU.Deploy.0 = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Ad-Hoc|ARM.Build.0 = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Ad-Hoc|ARM.Deploy.0 = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Ad-Hoc|x64.Build.0 = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Ad-Hoc|x64.Deploy.0 = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Ad-Hoc|x86.Build.0 = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Ad-Hoc|x86.Deploy.0 = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.AppStore|Any CPU.Build.0 = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.AppStore|Any CPU.Deploy.0 = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.AppStore|ARM.ActiveCfg = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.AppStore|ARM.Build.0 = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.AppStore|ARM.Deploy.0 = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.AppStore|iPhone.ActiveCfg = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.AppStore|x64.ActiveCfg = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.AppStore|x64.Build.0 = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.AppStore|x64.Deploy.0 = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.AppStore|x86.ActiveCfg = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.AppStore|x86.Build.0 = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.AppStore|x86.Deploy.0 = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Debug|ARM.ActiveCfg = Debug|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Debug|ARM.Build.0 = Debug|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Debug|ARM.Deploy.0 = Debug|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Debug|x64.ActiveCfg = Debug|Any CPU
{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
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Release|ARM.ActiveCfg = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Release|ARM.Build.0 = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Release|ARM.Deploy.0 = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Release|iPhone.ActiveCfg = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Release|x64.ActiveCfg = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Release|x64.Build.0 = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Release|x64.Deploy.0 = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Release|x86.ActiveCfg = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Release|x86.Build.0 = Release|Any CPU
{04B18ED2-B76D-4947-8474-191F8FD2B5E0}.Release|x86.Deploy.0 = Release|Any CPU
{1F78403F-9A28-405B-9289-B9DBEB55F074}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhone
{1F78403F-9A28-405B-9289-B9DBEB55F074}.Ad-Hoc|ARM.ActiveCfg = Ad-Hoc|iPhone
{1F78403F-9A28-405B-9289-B9DBEB55F074}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone
{1F78403F-9A28-405B-9289-B9DBEB55F074}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone
{1F78403F-9A28-405B-9289-B9DBEB55F074}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator
{1F78403F-9A28-405B-9289-B9DBEB55F074}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator
{1F78403F-9A28-405B-9289-B9DBEB55F074}.Ad-Hoc|x64.ActiveCfg = Ad-Hoc|iPhone
{1F78403F-9A28-405B-9289-B9DBEB55F074}.Ad-Hoc|x86.ActiveCfg = Ad-Hoc|iPhone
{1F78403F-9A28-405B-9289-B9DBEB55F074}.AppStore|Any CPU.ActiveCfg = AppStore|iPhone
{1F78403F-9A28-405B-9289-B9DBEB55F074}.AppStore|ARM.ActiveCfg = AppStore|iPhone
{1F78403F-9A28-405B-9289-B9DBEB55F074}.AppStore|iPhone.ActiveCfg = AppStore|iPhone
{1F78403F-9A28-405B-9289-B9DBEB55F074}.AppStore|iPhone.Build.0 = AppStore|iPhone
{1F78403F-9A28-405B-9289-B9DBEB55F074}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator
{1F78403F-9A28-405B-9289-B9DBEB55F074}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator
{1F78403F-9A28-405B-9289-B9DBEB55F074}.AppStore|x64.ActiveCfg = AppStore|iPhone
{1F78403F-9A28-405B-9289-B9DBEB55F074}.AppStore|x86.ActiveCfg = AppStore|iPhone
{1F78403F-9A28-405B-9289-B9DBEB55F074}.Debug|Any CPU.ActiveCfg = Debug|iPhone
{1F78403F-9A28-405B-9289-B9DBEB55F074}.Debug|ARM.ActiveCfg = Debug|iPhone
{1F78403F-9A28-405B-9289-B9DBEB55F074}.Debug|iPhone.ActiveCfg = Debug|iPhone
{1F78403F-9A28-405B-9289-B9DBEB55F074}.Debug|iPhone.Build.0 = Debug|iPhone
{1F78403F-9A28-405B-9289-B9DBEB55F074}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
{1F78403F-9A28-405B-9289-B9DBEB55F074}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
{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
{1F78403F-9A28-405B-9289-B9DBEB55F074}.Release|iPhone.Build.0 = Release|iPhone
{1F78403F-9A28-405B-9289-B9DBEB55F074}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
{1F78403F-9A28-405B-9289-B9DBEB55F074}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
{1F78403F-9A28-405B-9289-B9DBEB55F074}.Release|x64.ActiveCfg = Release|iPhone
{1F78403F-9A28-405B-9289-B9DBEB55F074}.Release|x86.ActiveCfg = Release|iPhone
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.Ad-Hoc|ARM.Build.0 = Release|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.Ad-Hoc|x64.Build.0 = Release|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.Ad-Hoc|x86.Build.0 = Release|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.AppStore|Any CPU.Build.0 = Release|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.AppStore|ARM.ActiveCfg = Release|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.AppStore|ARM.Build.0 = Release|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.AppStore|iPhone.ActiveCfg = Release|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.AppStore|x64.ActiveCfg = Release|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.AppStore|x64.Build.0 = Release|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.AppStore|x86.ActiveCfg = Release|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.AppStore|x86.Build.0 = Release|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.Debug|ARM.ActiveCfg = Debug|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.Debug|ARM.Build.0 = Debug|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{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
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.Release|ARM.Build.0 = Release|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.Release|iPhone.ActiveCfg = Release|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.Release|x64.ActiveCfg = Release|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.Release|x64.Build.0 = Release|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.Release|x86.ActiveCfg = Release|Any CPU
{A300DCE1-8D10-4267-B96A-CB01AEB7C220}.Release|x86.Build.0 = Release|Any CPU
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhone
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.Ad-Hoc|ARM.ActiveCfg = Ad-Hoc|iPhone
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.Ad-Hoc|x64.ActiveCfg = Ad-Hoc|iPhone
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.Ad-Hoc|x86.ActiveCfg = Ad-Hoc|iPhone
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.AppStore|Any CPU.ActiveCfg = AppStore|iPhone
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.AppStore|ARM.ActiveCfg = AppStore|iPhone
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.AppStore|iPhone.ActiveCfg = AppStore|iPhone
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.AppStore|iPhone.Build.0 = AppStore|iPhone
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.AppStore|x64.ActiveCfg = AppStore|iPhone
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.AppStore|x86.ActiveCfg = AppStore|iPhone
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.Debug|Any CPU.ActiveCfg = Debug|iPhone
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.Debug|ARM.ActiveCfg = Debug|iPhone
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.Debug|iPhone.ActiveCfg = Debug|iPhone
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.Debug|iPhone.Build.0 = Debug|iPhone
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
{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
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.Release|iPhone.Build.0 = Release|iPhone
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.Release|x64.ActiveCfg = Release|iPhone
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422}.Release|x86.ActiveCfg = Release|iPhone
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Ad-Hoc|ARM.Build.0 = Release|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Ad-Hoc|x64.Build.0 = Release|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Ad-Hoc|x86.Build.0 = Release|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.AppStore|Any CPU.Build.0 = Release|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.AppStore|ARM.ActiveCfg = Release|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.AppStore|ARM.Build.0 = Release|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.AppStore|iPhone.ActiveCfg = Release|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.AppStore|iPhone.Build.0 = Release|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.AppStore|x64.ActiveCfg = Release|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.AppStore|x64.Build.0 = Release|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.AppStore|x86.ActiveCfg = Release|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.AppStore|x86.Build.0 = Release|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Debug|ARM.ActiveCfg = Debug|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Debug|iPhone.Build.0 = Debug|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{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
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Release|iPhone.Build.0 = Release|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Release|x64.ActiveCfg = Release|Any CPU
{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
{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
{8A279EE4-4537-4656-9C93-44945E594556}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.AppStore|ARM.ActiveCfg = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.AppStore|ARM.Build.0 = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.AppStore|iPhone.Build.0 = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.AppStore|x64.ActiveCfg = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.AppStore|x64.Build.0 = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.AppStore|x86.ActiveCfg = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.AppStore|x86.Build.0 = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Debug|ARM.ActiveCfg = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Debug|ARM.Build.0 = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Debug|iPhone.Build.0 = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Debug|x64.ActiveCfg = Debug|Any CPU
{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
{8A279EE4-4537-4656-9C93-44945E594556}.Release|ARM.Build.0 = Release|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Release|iPhone.ActiveCfg = Release|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Release|iPhone.Build.0 = Release|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Release|x64.ActiveCfg = Release|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Release|x64.Build.0 = Release|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Release|x86.ActiveCfg = Release|Any CPU
{8A279EE4-4537-4656-9C93-44945E594556}.Release|x86.Build.0 = Release|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.AppStore|ARM.ActiveCfg = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.AppStore|ARM.Build.0 = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.AppStore|iPhone.Build.0 = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.AppStore|x64.ActiveCfg = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.AppStore|x64.Build.0 = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.AppStore|x86.ActiveCfg = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.AppStore|x86.Build.0 = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Debug|ARM.ActiveCfg = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Debug|ARM.Build.0 = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Debug|iPhone.Build.0 = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Debug|x64.ActiveCfg = Debug|Any CPU
{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
{D5D91152-CB01-4F24-A503-304D3A94408B}.Release|ARM.Build.0 = Release|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Release|iPhone.ActiveCfg = Release|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Release|iPhone.Build.0 = Release|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Release|x64.ActiveCfg = Release|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Release|x64.Build.0 = Release|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Release|x86.ActiveCfg = Release|Any CPU
{D5D91152-CB01-4F24-A503-304D3A94408B}.Release|x86.Build.0 = Release|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Ad-Hoc|Any CPU.Deploy.0 = Release|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Ad-Hoc|iPhone.Deploy.0 = Release|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Ad-Hoc|iPhoneSimulator.Deploy.0 = Release|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.AppStore|Any CPU.Build.0 = Release|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.AppStore|Any CPU.Deploy.0 = Release|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.AppStore|iPhone.ActiveCfg = Release|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.AppStore|iPhone.Build.0 = Release|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.AppStore|iPhone.Deploy.0 = Release|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.AppStore|iPhoneSimulator.Deploy.0 = Release|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Debug|iPhone.Build.0 = Debug|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Debug|iPhone.Deploy.0 = Debug|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Debug|iPhoneSimulator.Deploy.0 = Debug|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.FDroid|Any CPU.ActiveCfg = FDroid|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.FDroid|Any CPU.Build.0 = FDroid|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.FDroid|Any CPU.Deploy.0 = FDroid|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.FDroid|iPhone.ActiveCfg = FDroid|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.FDroid|iPhone.Build.0 = FDroid|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.FDroid|iPhone.Deploy.0 = FDroid|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.FDroid|iPhoneSimulator.ActiveCfg = FDroid|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.FDroid|iPhoneSimulator.Build.0 = FDroid|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.FDroid|iPhoneSimulator.Deploy.0 = FDroid|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Release|Any CPU.Build.0 = Release|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Release|Any CPU.Deploy.0 = Release|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Release|iPhone.ActiveCfg = Release|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Release|iPhone.Build.0 = Release|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Release|iPhone.Deploy.0 = Release|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F}.Release|iPhoneSimulator.Deploy.0 = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|Any CPU.Deploy.0 = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|iPhone.Deploy.0 = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Ad-Hoc|iPhoneSimulator.Deploy.0 = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|Any CPU.Build.0 = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|Any CPU.Deploy.0 = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|iPhone.ActiveCfg = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|iPhone.Build.0 = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|iPhone.Deploy.0 = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.AppStore|iPhoneSimulator.Deploy.0 = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Debug|iPhone.Build.0 = Debug|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Debug|iPhone.Deploy.0 = Debug|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Debug|iPhoneSimulator.Deploy.0 = Debug|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.FDroid|Any CPU.ActiveCfg = FDroid|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.FDroid|Any CPU.Build.0 = FDroid|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.FDroid|iPhone.ActiveCfg = FDroid|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.FDroid|iPhone.Build.0 = FDroid|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.FDroid|iPhoneSimulator.ActiveCfg = FDroid|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.FDroid|iPhoneSimulator.Build.0 = FDroid|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Release|Any CPU.Build.0 = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Release|Any CPU.Deploy.0 = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Release|iPhone.ActiveCfg = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Release|iPhone.Build.0 = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Release|iPhone.Deploy.0 = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}.Release|iPhoneSimulator.Deploy.0 = Release|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.AppStore|Any CPU.Build.0 = Release|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.AppStore|iPhone.ActiveCfg = Release|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.AppStore|iPhone.Build.0 = Release|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Debug|iPhone.Build.0 = Debug|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.FDroid|Any CPU.ActiveCfg = FDroid|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.FDroid|Any CPU.Build.0 = FDroid|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.FDroid|iPhone.ActiveCfg = FDroid|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.FDroid|iPhone.Build.0 = FDroid|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.FDroid|iPhoneSimulator.ActiveCfg = FDroid|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.FDroid|iPhoneSimulator.Build.0 = FDroid|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Release|Any CPU.Build.0 = Release|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Release|iPhone.ActiveCfg = Release|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Release|iPhone.Build.0 = Release|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{4B8A8C41-9820-4341-974C-41E65B7F4366}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.AppStore|iPhone.Build.0 = Debug|Any CPU
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Debug|iPhone.Build.0 = Debug|Any CPU
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.FDroid|Any CPU.ActiveCfg = FDroid|Any CPU
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.FDroid|Any CPU.Build.0 = FDroid|Any CPU
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.FDroid|iPhone.ActiveCfg = FDroid|Any CPU
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.FDroid|iPhone.Build.0 = FDroid|Any CPU
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.FDroid|iPhoneSimulator.ActiveCfg = FDroid|Any CPU
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.FDroid|iPhoneSimulator.Build.0 = FDroid|Any CPU
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Release|Any CPU.Build.0 = Release|Any CPU
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Release|iPhone.ActiveCfg = Release|Any CPU
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Release|iPhone.Build.0 = Release|Any CPU
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.AppStore|iPhone.Build.0 = Debug|Any CPU
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Debug|iPhone.Build.0 = Debug|Any CPU
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.FDroid|Any CPU.ActiveCfg = FDroid|Any CPU
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.FDroid|Any CPU.Build.0 = FDroid|Any CPU
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.FDroid|iPhone.ActiveCfg = FDroid|Any CPU
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.FDroid|iPhone.Build.0 = FDroid|Any CPU
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.FDroid|iPhoneSimulator.ActiveCfg = FDroid|Any CPU
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.FDroid|iPhoneSimulator.Build.0 = FDroid|Any CPU
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Release|Any CPU.Build.0 = Release|Any CPU
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Release|iPhone.ActiveCfg = Release|Any CPU
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Release|iPhone.Build.0 = Release|Any CPU
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|Any CPU.Build.0 = Ad-Hoc|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|Any CPU.ActiveCfg = AppStore|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|Any CPU.Build.0 = AppStore|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|iPhone.ActiveCfg = AppStore|iPhone
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|iPhone.Build.0 = AppStore|iPhone
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|iPhone.ActiveCfg = Debug|iPhone
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|iPhone.Build.0 = Debug|iPhone
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
{E71F3053-056C-4381-9638-048ED73BDFF6}.FDroid|Any CPU.ActiveCfg = FDroid|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.FDroid|Any CPU.Build.0 = FDroid|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.FDroid|iPhone.ActiveCfg = FDroid|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.FDroid|iPhone.Build.0 = FDroid|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.FDroid|iPhoneSimulator.ActiveCfg = FDroid|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.FDroid|iPhoneSimulator.Build.0 = FDroid|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.Release|Any CPU.Build.0 = Release|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.Release|iPhone.ActiveCfg = Release|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.Release|iPhone.Build.0 = Release|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhone
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.AppStore|Any CPU.ActiveCfg = AppStore|iPhone
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.AppStore|iPhone.ActiveCfg = AppStore|iPhone
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.AppStore|iPhone.Build.0 = AppStore|iPhone
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Debug|Any CPU.ActiveCfg = Debug|iPhone
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Debug|iPhone.ActiveCfg = Debug|iPhone
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Debug|iPhone.Build.0 = Debug|iPhone
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Debug|iPhone.Deploy.0 = Debug|iPhone
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.FDroid|Any CPU.ActiveCfg = FDroid|iPhone
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.FDroid|iPhone.ActiveCfg = FDroid|iPhone
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.FDroid|iPhone.Build.0 = FDroid|iPhone
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.FDroid|iPhoneSimulator.ActiveCfg = FDroid|iPhoneSimulator
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.FDroid|iPhoneSimulator.Build.0 = FDroid|iPhoneSimulator
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Release|Any CPU.ActiveCfg = Release|iPhone
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Release|iPhone.ActiveCfg = Release|iPhone
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Release|iPhone.Build.0 = Release|iPhone
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
{599E0201-420A-4C3E-A7BA-5349F72E0B15}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhone
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Ad-Hoc|Any CPU.Build.0 = Ad-Hoc|iPhone
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.AppStore|Any CPU.ActiveCfg = AppStore|iPhone
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.AppStore|Any CPU.Build.0 = AppStore|iPhone
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.AppStore|iPhone.ActiveCfg = AppStore|iPhone
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.AppStore|iPhone.Build.0 = AppStore|iPhone
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Debug|Any CPU.ActiveCfg = Debug|iPhone
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Debug|iPhone.ActiveCfg = Debug|iPhone
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Debug|iPhone.Build.0 = Debug|iPhone
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Debug|iPhone.Deploy.0 = Debug|iPhone
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.FDroid|Any CPU.ActiveCfg = Release|iPhone
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.FDroid|Any CPU.Build.0 = Release|iPhone
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.FDroid|iPhone.ActiveCfg = Release|iPhone
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.FDroid|iPhone.Build.0 = Release|iPhone
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.FDroid|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.FDroid|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Release|Any CPU.ActiveCfg = Release|iPhone
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Release|iPhone.ActiveCfg = Release|iPhone
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Release|iPhone.Build.0 = Release|iPhone
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.AppStore|Any CPU.Build.0 = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.AppStore|iPhone.ActiveCfg = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.AppStore|iPhone.Build.0 = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Debug|iPhone.Build.0 = Debug|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.FDroid|Any CPU.ActiveCfg = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.FDroid|Any CPU.Build.0 = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.FDroid|iPhone.ActiveCfg = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.FDroid|iPhone.Build.0 = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.FDroid|iPhoneSimulator.ActiveCfg = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.FDroid|iPhoneSimulator.Build.0 = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Release|Any CPU.Build.0 = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Release|iPhone.ActiveCfg = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Release|iPhone.Build.0 = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.AppStore|Any CPU.Build.0 = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.AppStore|iPhone.ActiveCfg = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.AppStore|iPhone.Build.0 = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Debug|iPhone.Build.0 = Debug|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.FDroid|Any CPU.ActiveCfg = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.FDroid|Any CPU.Build.0 = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.FDroid|iPhone.ActiveCfg = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.FDroid|iPhone.Build.0 = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.FDroid|iPhoneSimulator.ActiveCfg = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.FDroid|iPhoneSimulator.Build.0 = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Release|Any CPU.Build.0 = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Release|iPhone.ActiveCfg = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Release|iPhone.Build.0 = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Ad-Hoc|Any CPU.ActiveCfg = Debug|iPhoneSimulator
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Ad-Hoc|Any CPU.Build.0 = Debug|iPhoneSimulator
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Ad-Hoc|iPhone.ActiveCfg = Release|iPhone
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Ad-Hoc|iPhone.Build.0 = Release|iPhone
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
{F8C3F648-EA5A-4719-8005-85D1690B1655}.AppStore|Any CPU.ActiveCfg = Debug|iPhoneSimulator
{F8C3F648-EA5A-4719-8005-85D1690B1655}.AppStore|Any CPU.Build.0 = Debug|iPhoneSimulator
{F8C3F648-EA5A-4719-8005-85D1690B1655}.AppStore|iPhone.ActiveCfg = Release|iPhone
{F8C3F648-EA5A-4719-8005-85D1690B1655}.AppStore|iPhone.Build.0 = Release|iPhone
{F8C3F648-EA5A-4719-8005-85D1690B1655}.AppStore|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
{F8C3F648-EA5A-4719-8005-85D1690B1655}.AppStore|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Debug|Any CPU.Build.0 = Debug|iPhoneSimulator
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Debug|iPhone.ActiveCfg = Debug|iPhone
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Debug|iPhone.Build.0 = Debug|iPhone
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
{F8C3F648-EA5A-4719-8005-85D1690B1655}.FDroid|Any CPU.ActiveCfg = Debug|iPhoneSimulator
{F8C3F648-EA5A-4719-8005-85D1690B1655}.FDroid|Any CPU.Build.0 = Debug|iPhoneSimulator
{F8C3F648-EA5A-4719-8005-85D1690B1655}.FDroid|iPhone.ActiveCfg = Release|iPhone
{F8C3F648-EA5A-4719-8005-85D1690B1655}.FDroid|iPhone.Build.0 = Release|iPhone
{F8C3F648-EA5A-4719-8005-85D1690B1655}.FDroid|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
{F8C3F648-EA5A-4719-8005-85D1690B1655}.FDroid|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Release|Any CPU.ActiveCfg = Release|iPhone
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Release|Any CPU.Build.0 = Release|iPhone
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Release|iPhone.ActiveCfg = Release|iPhone
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Release|iPhone.Build.0 = Release|iPhone
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
{F8C3F648-EA5A-4719-8005-85D1690B1655}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Ad-Hoc|Any CPU.Build.0 = Ad-Hoc|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.AppStore|Any CPU.ActiveCfg = AppStore|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.AppStore|Any CPU.Build.0 = AppStore|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.AppStore|iPhone.ActiveCfg = AppStore|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.AppStore|iPhone.Build.0 = AppStore|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Debug|Any CPU.ActiveCfg = Debug|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Debug|iPhone.ActiveCfg = Debug|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Debug|iPhone.Build.0 = Debug|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Debug|iPhone.Deploy.0 = Debug|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.FDroid|Any CPU.ActiveCfg = Release|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.FDroid|Any CPU.Build.0 = Release|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.FDroid|iPhone.ActiveCfg = Release|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.FDroid|iPhone.Build.0 = Release|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.FDroid|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.FDroid|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Release|Any CPU.ActiveCfg = Release|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Release|iPhone.ActiveCfg = Release|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Release|iPhone.Build.0 = Release|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{04B18ED2-B76D-4947-8474-191F8FD2B5E0} = {EC730FD9-F623-4B6C-B503-95CDCFBCF277}
{1F78403F-9A28-405B-9289-B9DBEB55F074} = {EC730FD9-F623-4B6C-B503-95CDCFBCF277}
{A300DCE1-8D10-4267-B96A-CB01AEB7C220} = {0D790714-ECF8-4A83-BE4A-E9C84DD1BB5D}
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422} = {EC730FD9-F623-4B6C-B503-95CDCFBCF277}
{B2538ADA-B605-4D6F-ACD2-62A409680F84} = {EC730FD9-F623-4B6C-B503-95CDCFBCF277}
{304400AF-F0ED-40FA-B102-EA3C3EC43E4F} = {D10CA4A9-F866-40E1-B658-F69051236C71}
{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C} = {D10CA4A9-F866-40E1-B658-F69051236C71}
{4B8A8C41-9820-4341-974C-41E65B7F4366} = {D10CA4A9-F866-40E1-B658-F69051236C71}
{9C8DA5A8-904D-466F-B9B0-1A4AB5A9AFC3} = {8904C536-C67D-420F-9971-51B26574C3AA}
{2E399654-26A2-46F6-B9CA-1B496A3F370A} = {92470CBD-9047-4C3C-8EA3-D972D6622D84}
{8A279EE4-4537-4656-9C93-44945E594556} = {EC730FD9-F623-4B6C-B503-95CDCFBCF277}
{D5D91152-CB01-4F24-A503-304D3A94408B} = {2E399654-26A2-46F6-B9CA-1B496A3F370A}
{256F9E44-0AF5-4D97-A2F9-DA26080C0A5D} = {2E399654-26A2-46F6-B9CA-1B496A3F370A}
{E71F3053-056C-4381-9638-048ED73BDFF6} = {D10CA4A9-F866-40E1-B658-F69051236C71}
{599E0201-420A-4C3E-A7BA-5349F72E0B15} = {D10CA4A9-F866-40E1-B658-F69051236C71}
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545} = {D10CA4A9-F866-40E1-B658-F69051236C71}
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39} = {8904C536-C67D-420F-9971-51B26574C3AA}
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0} = {8904C536-C67D-420F-9971-51B26574C3AA}
{F8C3F648-EA5A-4719-8005-85D1690B1655} = {D10CA4A9-F866-40E1-B658-F69051236C71}
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A} = {D10CA4A9-F866-40E1-B658-F69051236C71}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {318CB2DF-0118-43A3-AC83-56BADCF71CCD}
SolutionGuid = {7D436EA3-8B7E-45D2-8D14-0730BD2E0410}
EndGlobalSection
EndGlobal

345
build.cake Normal file
View File

@@ -0,0 +1,345 @@
#addin nuget:?package=Cake.FileHelpers&version=5.0.0
#addin nuget:?package=Cake.AndroidAppManifest&version=1.1.2
#addin nuget:?package=Cake.Plist&version=0.7.0
#addin nuget:?package=Cake.Incubator&version=7.0.0
#tool dotnet:?package=GitVersion.Tool&version=5.10.3
using Path = System.IO.Path;
var debugScript = Argument<bool>("debugScript", false);
var target = Argument("target", "Default");
var configuration = Argument("configuration", "Release");
var variant = Argument("variant", "dev");
abstract record VariantConfig(
string AppName,
string AndroidPackageName,
string iOSBundleId,
string ApsEnvironment
);
const string BASE_BUNDLE_ID_DROID = "com.x8bit.bitwarden";
const string BASE_BUNDLE_ID_IOS = "com.8bit.bitwarden";
record Dev(): VariantConfig("Bitwarden Dev", $"{BASE_BUNDLE_ID_DROID}.dev", $"{BASE_BUNDLE_ID_IOS}.dev", "development");
record QA(): VariantConfig("Bitwarden QA", $"{BASE_BUNDLE_ID_DROID}.qa", $"{BASE_BUNDLE_ID_IOS}.qa", "development");
record Beta(): VariantConfig("Bitwarden Beta", $"{BASE_BUNDLE_ID_DROID}.beta", $"{BASE_BUNDLE_ID_IOS}.beta", "production");
record Prod(): VariantConfig("Bitwarden", $"{BASE_BUNDLE_ID_DROID}", $"{BASE_BUNDLE_ID_IOS}", "production");
VariantConfig GetVariant() => variant.ToLower() switch{
"qa" => new QA(),
"beta" => new Beta(),
"prod" => new Prod(),
_ => new Dev()
};
GitVersion _gitVersion; //will be set by GetGitInfo task
var _slnPath = Path.Combine(""); //base path used to access files. If build.cake file is moved, just update this
string _androidPackageName = string.Empty; //will be set by UpdateAndroidManifest task
string CreateFeatureBranch(string prevVersionName, GitVersion git) => $"{prevVersionName}-{git.BranchName.Replace("/","-")}";
string GetVersionName(string prevVersionName, VariantConfig buildVariant, GitVersion git) => buildVariant is Prod? prevVersionName : CreateFeatureBranch(prevVersionName, git);
int CreateBuildNumber(int previousNumber) => ++previousNumber;
Task("GetGitInfo")
.Does(()=> {
_gitVersion = GitVersion(new GitVersionSettings());
if(debugScript)
{
Information($"GitVersion Dump:\n{_gitVersion.Dump()}");
}
Information("Git data Load successfully.");
});
#region Android
Task("UpdateAndroidAppIcon")
.Does(()=>{
//TODO we'll implement variant icons later
//manifest.ApplicationIcon = "@mipmap/ic_launcher";
Information($"Updated Androix App Icon with success");
});
Task("UpdateAndroidManifest")
.IsDependentOn("GetGitInfo")
.Does(()=>
{
var buildVariant = GetVariant();
var manifestPath = Path.Combine(_slnPath, "src", "Android", "Properties", "AndroidManifest.xml");
// Cake.AndroidAppManifest doesn't currently enable us to access nested items so, quick (not ideal) fix:
var manifestText = FileReadText(manifestPath);
manifestText = manifestText.Replace("com.x8bit.bitwarden.", buildVariant.AndroidPackageName + ".");
manifestText = manifestText.Replace("android:label=\"Bitwarden\"", $"android:label=\"{buildVariant.AppName}\"");
FileWriteText(manifestPath, manifestText);
var manifest = DeserializeAppManifest(manifestPath);
var prevVersionCode = manifest.VersionCode;
var prevVersionName = manifest.VersionName;
_androidPackageName = manifest.PackageName;
//manifest.VersionCode = CreateBuildNumber(prevVersionCode);
manifest.VersionName = GetVersionName(prevVersionName, buildVariant, _gitVersion);
manifest.PackageName = buildVariant.AndroidPackageName;
manifest.ApplicationLabel = buildVariant.AppName;
//Information($"AndroidManigest.xml VersionCode from {prevVersionCode} to {manifest.VersionCode}");
Information($"AndroidManigest.xml VersionName from {prevVersionName} to {manifest.VersionName}");
Information($"AndroidManigest.xml PackageName from {_androidPackageName} to {buildVariant.AndroidPackageName}");
Information($"AndroidManigest.xml ApplicationLabel to {buildVariant.AppName}");
SerializeAppManifest(manifestPath, manifest);
Information("AndroidManifest updated with success!");
});
void ReplaceInFile(string filePath, string oldtext, string newtext)
{
var fileText = FileReadText(filePath);
if(string.IsNullOrEmpty(fileText) || !fileText.Contains(oldtext))
{
throw new Exception($"Couldn't find {filePath} or it didn't contain: {oldtext}");
}
fileText = fileText.Replace(oldtext, newtext);
FileWriteText(filePath, fileText);
Information($"{filePath} modified successfully.");
}
Task("UpdateAndroidCodeFiles")
.IsDependentOn("UpdateAndroidManifest")
.Does(()=> {
var buildVariant = GetVariant();
//We're not using _androidPackageName here because the codefile is currently slightly different string than the one in AndroidManifest.xml
var keyName = "com.8bit.bitwarden";
var fixedPackageName = buildVariant.AndroidPackageName.Replace("x8bit", "8bit");
var filePath = Path.Combine(_slnPath, "src", "Android", "Services", "BiometricService.cs");
ReplaceInFile(filePath, keyName, fixedPackageName);
var packageFileList = new string[] {
Path.Combine(_slnPath, "src", "Android", "MainActivity.cs"),
Path.Combine(_slnPath, "src", "Android", "MainApplication.cs"),
Path.Combine(_slnPath, "src", "Android", "Constants.cs"),
Path.Combine(_slnPath, "src", "Android", "Accessibility", "AccessibilityService.cs"),
Path.Combine(_slnPath, "src", "Android", "Autofill", "AutofillHelpers.cs"),
Path.Combine(_slnPath, "src", "Android", "Autofill", "AutofillService.cs"),
Path.Combine(_slnPath, "src", "Android", "Receivers", "ClearClipboardAlarmReceiver.cs"),
Path.Combine(_slnPath, "src", "Android", "Receivers", "EventUploadReceiver.cs"),
Path.Combine(_slnPath, "src", "Android", "Receivers", "PackageReplacedReceiver.cs"),
Path.Combine(_slnPath, "src", "Android", "Receivers", "RestrictionsChangedReceiver.cs"),
Path.Combine(_slnPath, "src", "Android", "Services", "DeviceActionService.cs"),
Path.Combine(_slnPath, "src", "Android", "Tiles", "AutofillTileService.cs"),
Path.Combine(_slnPath, "src", "Android", "Tiles", "GeneratorTileService.cs"),
Path.Combine(_slnPath, "src", "Android", "Tiles", "MyVaultTileService.cs"),
Path.Combine(_slnPath, "src", "Android", "google-services.json"),
Path.Combine(_slnPath, "store", "google", "Publisher", "Program.cs"),
};
foreach(string path in packageFileList)
{
ReplaceInFile(path, "com.x8bit.bitwarden", buildVariant.AndroidPackageName);
}
var labelFileList = new string[] {
Path.Combine(_slnPath, "src", "Android", "Autofill", "AutofillService.cs"),
};
foreach(string path in labelFileList)
{
ReplaceInFile(path, "Bitwarden\"", $"{buildVariant.AppName}\"");
}
});
#endregion Android
#region iOS
enum iOSProjectType
{
Null,
MainApp,
Autofill,
Extension,
ShareExtension
}
string GetiOSBundleId(VariantConfig buildVariant, iOSProjectType projectType) => projectType switch
{
iOSProjectType.Autofill => $"{buildVariant.iOSBundleId}.autofill",
iOSProjectType.Extension => $"{buildVariant.iOSBundleId}.find-login-action-extension",
iOSProjectType.ShareExtension => $"{buildVariant.iOSBundleId}.share-extension",
_ => buildVariant.iOSBundleId
};
string GetiOSBundleName(VariantConfig buildVariant, iOSProjectType projectType) => projectType switch
{
iOSProjectType.Autofill => $"{buildVariant.AppName} Autofill",
iOSProjectType.Extension => $"{buildVariant.AppName} Extension",
iOSProjectType.ShareExtension => $"{buildVariant.AppName} Share Extension",
_ => buildVariant.AppName
};
private void UpdateiOSInfoPlist(string plistPath, VariantConfig buildVariant, GitVersion git, iOSProjectType projectType = iOSProjectType.MainApp)
{
var plistFile = File(plistPath);
dynamic plist = DeserializePlist(plistFile);
var prevVersionName = plist["CFBundleShortVersionString"];
var prevVersionString = plist["CFBundleVersion"];
var prevVersion = int.Parse(plist["CFBundleVersion"]);
var prevBundleId = plist["CFBundleIdentifier"];
var prevBundleName = plist["CFBundleName"];
//var newVersion = CreateBuildNumber(prevVersion).ToString();
var newVersionName = GetVersionName(prevVersionName, buildVariant, git);
var newBundleId = GetiOSBundleId(buildVariant, projectType);
var newBundleName = GetiOSBundleName(buildVariant, projectType);
plist["CFBundleName"] = newBundleName;
plist["CFBundleDisplayName"] = newBundleName;
//plist["CFBundleVersion"] = newVersion;
plist["CFBundleShortVersionString"] = newVersionName;
plist["CFBundleIdentifier"] = newBundleId;
if(projectType == iOSProjectType.MainApp)
{
plist["CFBundleURLTypes"][0]["CFBundleURLName"] = $"{buildVariant.iOSBundleId}.url";
}
if(projectType == iOSProjectType.Extension)
{
var keyText = plist["NSExtension"]["NSExtensionAttributes"]["NSExtensionActivationRule"];
plist["NSExtension"]["NSExtensionAttributes"]["NSExtensionActivationRule"] = keyText.Replace("com.8bit.bitwarden", buildVariant.iOSBundleId);
}
SerializePlist(plistFile, plist);
Information($"Changed app name from {prevBundleName} to {newBundleName}");
//Information($"Changed Bundle Version from {prevVersion} to {newVersion}");
Information($"Changed Bundle Short Version name from {prevVersionName} to {newVersionName}");
Information($"Changed Bundle Identifier from {prevBundleId} to {newBundleId}");
Information($"{plistPath} updated with success!");
}
private void UpdateiOSEntitlementsPlist(string entitlementsPath, VariantConfig buildVariant)
{
var EntitlementlistFile = File(entitlementsPath);
dynamic Entitlements = DeserializePlist(EntitlementlistFile);
Entitlements["aps-environment"] = buildVariant.ApsEnvironment;
Entitlements["keychain-access-groups"] = new List<string>() { "$(AppIdentifierPrefix)" + buildVariant.iOSBundleId };
Entitlements["com.apple.security.application-groups"] = new List<string>() { $"group.{buildVariant.iOSBundleId}" };;
Information($"Changed ApsEnvironment name to {buildVariant.ApsEnvironment}");
Information($"Changed keychain-access-groups bundleID to {buildVariant.iOSBundleId}");
SerializePlist(EntitlementlistFile, Entitlements);
Information($"{entitlementsPath} updated with success!");
}
Task("UpdateiOSIcon")
.Does(()=>{
//TODO we'll implement variant icons later
Information($"Updating IOS App Icon");
});
Task("UpdateiOSPlist")
.IsDependentOn("GetGitInfo")
.Does(()=> {
var buildVariant = GetVariant();
var infoPath = Path.Combine(_slnPath, "src", "iOS", "Info.plist");
var entitlementsPath = Path.Combine(_slnPath, "src", "iOS", "Entitlements.plist");
UpdateiOSInfoPlist(infoPath, buildVariant, _gitVersion, iOSProjectType.MainApp);
UpdateiOSEntitlementsPlist(entitlementsPath, buildVariant);
});
Task("UpdateiOSAutofillPlist")
.IsDependentOn("GetGitInfo")
.IsDependentOn("UpdateiOSPlist")
.Does(()=> {
var buildVariant = GetVariant();
var infoPath = Path.Combine(_slnPath, "src", "iOS.Autofill", "Info.plist");
var entitlementsPath = Path.Combine(_slnPath, "src", "iOS.Autofill", "Entitlements.plist");
UpdateiOSInfoPlist(infoPath, buildVariant, _gitVersion, iOSProjectType.Autofill);
UpdateiOSEntitlementsPlist(entitlementsPath, buildVariant);
});
Task("UpdateiOSExtensionPlist")
.IsDependentOn("GetGitInfo")
.IsDependentOn("UpdateiOSPlist")
.Does(()=> {
var buildVariant = GetVariant();
var infoPath = Path.Combine(_slnPath, "src", "iOS.Extension", "Info.plist");
var entitlementsPath = Path.Combine(_slnPath, "src", "iOS.Extension", "Entitlements.plist");
UpdateiOSInfoPlist(infoPath, buildVariant, _gitVersion, iOSProjectType.Extension);
UpdateiOSEntitlementsPlist(entitlementsPath, buildVariant);
});
Task("UpdateiOSShareExtensionPlist")
.IsDependentOn("GetGitInfo")
.IsDependentOn("UpdateiOSPlist")
.Does(()=> {
var buildVariant = GetVariant();
var infoPath = Path.Combine(_slnPath, "src", "iOS.ShareExtension", "Info.plist");
var entitlementsPath = Path.Combine(_slnPath, "src", "iOS.ShareExtension", "Entitlements.plist");
UpdateiOSInfoPlist(infoPath, buildVariant, _gitVersion, iOSProjectType.ShareExtension);
UpdateiOSEntitlementsPlist(entitlementsPath, buildVariant);
});
Task("UpdateiOSCodeFiles")
.IsDependentOn("UpdateiOSPlist")
.Does(()=> {
var buildVariant = GetVariant();
var fileList = new string[] {
Path.Combine(_slnPath, "src", "iOS.Core", "Utilities", "iOSCoreHelpers.cs"),
Path.Combine(_slnPath, "src", "iOS.Core", "Constants.cs"),
Path.Combine(".github", "resources", "export-options-ad-hoc.plist"),
Path.Combine(".github", "resources", "export-options-app-store.plist"),
};
foreach(string path in fileList)
{
ReplaceInFile(path, "com.8bit.bitwarden", buildVariant.iOSBundleId);
}
});
#endregion iOS
#region Main Tasks
Task("Android")
//.IsDependentOn("UpdateAndroidAppIcon")
.IsDependentOn("UpdateAndroidManifest")
.IsDependentOn("UpdateAndroidCodeFiles")
.Does(()=>
{
Information("Android app updated");
});
Task("iOS")
//.IsDependentOn("UpdateiOSIcon")
.IsDependentOn("UpdateiOSPlist")
.IsDependentOn("UpdateiOSAutofillPlist")
.IsDependentOn("UpdateiOSExtensionPlist")
.IsDependentOn("UpdateiOSShareExtensionPlist")
.IsDependentOn("UpdateiOSCodeFiles")
.Does(()=>
{
Information("iOS app updated");
});
Task("Default")
.Does(() => {
var usage = @"Missing target.
Usage:
dotnet cake build.cake --target (Android | iOS) --variant (dev | qa | beta | prod)
Options:
--debugScript=<bool> Script debug mode.
";
Information(usage);
});
#endregion Main Tasks
RunTarget(target);

View File

@@ -1,5 +1,9 @@
project_id_env: _CROWDIN_PROJECT_ID
api_token_env: CROWDIN_API_TOKEN
preserve_hierarchy: true
files:
- source: /src/App/Resources/AppResources.resx
dest: /src/App/Resources/%original_file_name%
translation: /src/App/Resources/AppResources.%two_letters_code%.resx
update_option: update_as_unapproved
languages_mapping:
@@ -8,7 +12,10 @@ files:
zh-TW: zh-Hant
pt-PT: pt-PT
pt-BR: pt-BR
en-GB: en-GB
en-IN: en-IN
- source: /store/apple/en/copy.resx
dest: /store/apple/en/%original_file_name%
translation: /store/apple/%two_letters_code%/copy.resx
update_option: update_as_unapproved
languages_mapping:
@@ -17,7 +24,10 @@ files:
zh-TW: zh-Hant
pt-PT: pt-PT
pt-BR: pt-BR
en-GB: en-GB
en-IN: en-IN
- source: /store/google/en/copy.resx
dest: /store/google/en/%original_file_name%
translation: /store/google/%two_letters_code%/copy.resx
update_option: update_as_unapproved
languages_mapping:
@@ -26,3 +36,5 @@ files:
zh-TW: zh-Hant
pt-BR: pt-BR
pt-PT: pt-PT
en-GB: en-GB
en-IN: en-IN

816
package-lock.json generated Normal file
View File

@@ -0,0 +1,816 @@
{
"name": "bitwarden-mobile",
"version": "0.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "bitwarden-mobile",
"version": "0.0.0",
"devDependencies": {
"gh-pages": "^3.2.3"
}
},
"node_modules/array-union": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
"integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
"dev": true,
"dependencies": {
"array-uniq": "^1.0.1"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/array-uniq": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
"integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/async": {
"version": "2.6.3",
"resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
"integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
"dev": true,
"dependencies": {
"lodash": "^4.17.14"
}
},
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
},
"node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"node_modules/commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"dev": true
},
"node_modules/commondir": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
"integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
"dev": true
},
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
"dev": true
},
"node_modules/email-addresses": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-3.1.0.tgz",
"integrity": "sha512-k0/r7GrWVL32kZlGwfPNgB2Y/mMXVTq/decgLczm/j34whdaspNrZO8CnXPf1laaHxI6ptUlsnAxN+UAPw+fzg==",
"dev": true
},
"node_modules/escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"dev": true,
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/filename-reserved-regex": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz",
"integrity": "sha1-q/c9+rc10EVECr/qLZHzieu/oik=",
"dev": true,
"engines": {
"node": ">=4"
}
},
"node_modules/filenamify": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz",
"integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==",
"dev": true,
"dependencies": {
"filename-reserved-regex": "^2.0.0",
"strip-outer": "^1.0.1",
"trim-repeated": "^1.0.0"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/find-cache-dir": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz",
"integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==",
"dev": true,
"dependencies": {
"commondir": "^1.0.1",
"make-dir": "^3.0.2",
"pkg-dir": "^4.1.0"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/avajs/find-cache-dir?sponsor=1"
}
},
"node_modules/find-up": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
"dev": true,
"dependencies": {
"locate-path": "^5.0.0",
"path-exists": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/fs-extra": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
"dev": true,
"dependencies": {
"graceful-fs": "^4.2.0",
"jsonfile": "^4.0.0",
"universalify": "^0.1.0"
},
"engines": {
"node": ">=6 <7 || >=8"
}
},
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
"dev": true
},
"node_modules/gh-pages": {
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-3.2.3.tgz",
"integrity": "sha512-jA1PbapQ1jqzacECfjUaO9gV8uBgU6XNMV0oXLtfCX3haGLe5Atq8BxlrADhbD6/UdG9j6tZLWAkAybndOXTJg==",
"dev": true,
"dependencies": {
"async": "^2.6.1",
"commander": "^2.18.0",
"email-addresses": "^3.0.1",
"filenamify": "^4.3.0",
"find-cache-dir": "^3.3.1",
"fs-extra": "^8.1.0",
"globby": "^6.1.0"
},
"bin": {
"gh-pages": "bin/gh-pages.js",
"gh-pages-clean": "bin/gh-pages-clean.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/glob": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
"dev": true,
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
},
"engines": {
"node": "*"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/globby": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
"integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=",
"dev": true,
"dependencies": {
"array-union": "^1.0.1",
"glob": "^7.0.3",
"object-assign": "^4.0.1",
"pify": "^2.0.0",
"pinkie-promise": "^2.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/graceful-fs": {
"version": "4.2.8",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz",
"integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==",
"dev": true
},
"node_modules/inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"dev": true,
"dependencies": {
"once": "^1.3.0",
"wrappy": "1"
}
},
"node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"dev": true
},
"node_modules/jsonfile": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
"dev": true,
"optionalDependencies": {
"graceful-fs": "^4.1.6"
}
},
"node_modules/locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
"dev": true,
"dependencies": {
"p-locate": "^4.1.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"dev": true
},
"node_modules/make-dir": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
"integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
"dev": true,
"dependencies": {
"semver": "^6.0.0"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dev": true,
"dependencies": {
"brace-expansion": "^1.1.7"
},
"engines": {
"node": "*"
}
},
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dev": true,
"dependencies": {
"wrappy": "1"
}
},
"node_modules/p-limit": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"dev": true,
"dependencies": {
"p-try": "^2.0.0"
},
"engines": {
"node": ">=6"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/p-locate": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
"dev": true,
"dependencies": {
"p-limit": "^2.2.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/p-try": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
"dev": true,
"engines": {
"node": ">=6"
}
},
"node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"dev": true,
"engines": {
"node": ">=8"
}
},
"node_modules/path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/pify": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/pinkie": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
"integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/pinkie-promise": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
"integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
"dev": true,
"dependencies": {
"pinkie": "^2.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/pkg-dir": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
"integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
"dev": true,
"dependencies": {
"find-up": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/strip-outer": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz",
"integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==",
"dev": true,
"dependencies": {
"escape-string-regexp": "^1.0.2"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/trim-repeated": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz",
"integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=",
"dev": true,
"dependencies": {
"escape-string-regexp": "^1.0.2"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/universalify": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
"dev": true,
"engines": {
"node": ">= 4.0.0"
}
},
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
"dev": true
}
},
"dependencies": {
"array-union": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
"integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
"dev": true,
"requires": {
"array-uniq": "^1.0.1"
}
},
"array-uniq": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
"integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
"dev": true
},
"async": {
"version": "2.6.3",
"resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
"integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
"dev": true,
"requires": {
"lodash": "^4.17.14"
}
},
"balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"dev": true
},
"commondir": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
"integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
"dev": true
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
"dev": true
},
"email-addresses": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-3.1.0.tgz",
"integrity": "sha512-k0/r7GrWVL32kZlGwfPNgB2Y/mMXVTq/decgLczm/j34whdaspNrZO8CnXPf1laaHxI6ptUlsnAxN+UAPw+fzg==",
"dev": true
},
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"dev": true
},
"filename-reserved-regex": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz",
"integrity": "sha1-q/c9+rc10EVECr/qLZHzieu/oik=",
"dev": true
},
"filenamify": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz",
"integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==",
"dev": true,
"requires": {
"filename-reserved-regex": "^2.0.0",
"strip-outer": "^1.0.1",
"trim-repeated": "^1.0.0"
}
},
"find-cache-dir": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz",
"integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==",
"dev": true,
"requires": {
"commondir": "^1.0.1",
"make-dir": "^3.0.2",
"pkg-dir": "^4.1.0"
}
},
"find-up": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
"dev": true,
"requires": {
"locate-path": "^5.0.0",
"path-exists": "^4.0.0"
}
},
"fs-extra": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
"dev": true,
"requires": {
"graceful-fs": "^4.2.0",
"jsonfile": "^4.0.0",
"universalify": "^0.1.0"
}
},
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
"dev": true
},
"gh-pages": {
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-3.2.3.tgz",
"integrity": "sha512-jA1PbapQ1jqzacECfjUaO9gV8uBgU6XNMV0oXLtfCX3haGLe5Atq8BxlrADhbD6/UdG9j6tZLWAkAybndOXTJg==",
"dev": true,
"requires": {
"async": "^2.6.1",
"commander": "^2.18.0",
"email-addresses": "^3.0.1",
"filenamify": "^4.3.0",
"find-cache-dir": "^3.3.1",
"fs-extra": "^8.1.0",
"globby": "^6.1.0"
}
},
"glob": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
"dev": true,
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
}
},
"globby": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
"integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=",
"dev": true,
"requires": {
"array-union": "^1.0.1",
"glob": "^7.0.3",
"object-assign": "^4.0.1",
"pify": "^2.0.0",
"pinkie-promise": "^2.0.0"
}
},
"graceful-fs": {
"version": "4.2.8",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz",
"integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==",
"dev": true
},
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"dev": true,
"requires": {
"once": "^1.3.0",
"wrappy": "1"
}
},
"inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"dev": true
},
"jsonfile": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
"dev": true,
"requires": {
"graceful-fs": "^4.1.6"
}
},
"locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
"dev": true,
"requires": {
"p-locate": "^4.1.0"
}
},
"lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"dev": true
},
"make-dir": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
"integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
"dev": true,
"requires": {
"semver": "^6.0.0"
}
},
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dev": true,
"requires": {
"brace-expansion": "^1.1.7"
}
},
"object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
"dev": true
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dev": true,
"requires": {
"wrappy": "1"
}
},
"p-limit": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"dev": true,
"requires": {
"p-try": "^2.0.0"
}
},
"p-locate": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
"dev": true,
"requires": {
"p-limit": "^2.2.0"
}
},
"p-try": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
"dev": true
},
"path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"dev": true
},
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"dev": true
},
"pify": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
"dev": true
},
"pinkie": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
"integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
"dev": true
},
"pinkie-promise": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
"integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
"dev": true,
"requires": {
"pinkie": "^2.0.0"
}
},
"pkg-dir": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
"integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
"dev": true,
"requires": {
"find-up": "^4.0.0"
}
},
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true
},
"strip-outer": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz",
"integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==",
"dev": true,
"requires": {
"escape-string-regexp": "^1.0.2"
}
},
"trim-repeated": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz",
"integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=",
"dev": true,
"requires": {
"escape-string-regexp": "^1.0.2"
}
},
"universalify": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
"dev": true
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
"dev": true
}
}
}

11
package.json Normal file
View File

@@ -0,0 +1,11 @@
{
"name": "bitwarden-mobile",
"version": "0.0.0",
"scripts": {
"deploy": "gh-pages --dist dist",
"clean:l10n": "git push origin --delete l10n_master"
},
"devDependencies": {
"gh-pages": "^3.2.3"
}
}

View File

@@ -3,26 +3,30 @@ using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using System;
using Bit.Core.Abstractions;
using Bit.Core.Utilities;
using Bit.Droid.Utilities;
namespace Bit.Android
namespace Bit.Droid.Accessibility
{
[Activity(Theme = "@style/BitwardenTheme.Splash", WindowSoftInputMode = SoftInput.StateHidden)]
public class AutofillActivity : Activity
[Activity(Theme = "@style/BaseTheme", WindowSoftInputMode = SoftInput.StateHidden)]
public class AccessibilityActivity : Activity
{
private DateTime? _lastLaunch = null;
private string _lastQueriedUri;
public static AutofillCredentials LastCredentials { get; set; }
protected override void OnCreate(Bundle bundle)
{
Intent?.Validate();
base.OnCreate(bundle);
LaunchMainActivity(Intent, 932473);
HandleIntent(Intent, 932473);
}
protected override void OnNewIntent(Intent intent)
{
base.OnNewIntent(intent);
LaunchMainActivity(intent, 489729);
HandleIntent(intent, 489729);
}
protected override void OnDestroy()
@@ -33,37 +37,35 @@ namespace Bit.Android
protected override void OnResume()
{
base.OnResume();
if(!Intent.HasExtra("uri"))
if (!Intent.HasExtra("uri"))
{
Finish();
return;
}
Intent.RemoveExtra("uri");
}
protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
if(data == null)
if (data == null)
{
LastCredentials = null;
AccessibilityHelpers.LastCredentials = null;
}
else
{
try
{
if(data.GetStringExtra("canceled") != null)
if (data.GetStringExtra("canceled") != null)
{
LastCredentials = null;
AccessibilityHelpers.LastCredentials = null;
}
else
{
var uri = data.GetStringExtra("uri");
var username = data.GetStringExtra("username");
var password = data.GetStringExtra("password");
LastCredentials = new AutofillCredentials
AccessibilityHelpers.LastCredentials = new Credentials
{
Username = username,
Password = password,
@@ -74,24 +76,44 @@ namespace Bit.Android
}
catch
{
LastCredentials = null;
AccessibilityHelpers.LastCredentials = null;
}
}
Finish();
}
private void HandleIntent(Intent callingIntent, int requestCode)
{
if (callingIntent?.GetBooleanExtra("autofillTileClicked", false) ?? false)
{
Intent.RemoveExtra("autofillTileClicked");
var messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
messagingService.Send("OnAutofillTileClick");
Finish();
}
else
{
LaunchMainActivity(callingIntent, requestCode);
}
}
private void LaunchMainActivity(Intent callingIntent, int requestCode)
{
_lastQueriedUri = callingIntent?.GetStringExtra("uri");
if(_lastQueriedUri == null)
if (_lastQueriedUri == null)
{
Finish();
return;
}
var now = DateTime.UtcNow;
if (_lastLaunch.HasValue && (now - _lastLaunch.Value) <= TimeSpan.FromSeconds(2))
{
return;
}
_lastLaunch = now;
var intent = new Intent(this, typeof(MainActivity));
if(!callingIntent.Flags.HasFlag(ActivityFlags.LaunchedFromHistory))
if (!callingIntent.Flags.HasFlag(ActivityFlags.LaunchedFromHistory))
{
intent.PutExtra("uri", _lastQueriedUri);
}

View File

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

View File

@@ -0,0 +1,472 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Views.Accessibility;
using Android.Widget;
using Bit.App.Resources;
using Bit.Core.Abstractions;
using Bit.Core.Utilities;
namespace Bit.Droid.Accessibility
{
[Service(Permission = Android.Manifest.Permission.BindAccessibilityService, Label = "Bitwarden", Exported = true)]
[IntentFilter(new string[] { "android.accessibilityservice.AccessibilityService" })]
[MetaData("android.accessibilityservice", Resource = "@xml/accessibilityservice")]
[Register("com.x8bit.bitwarden.Accessibility.AccessibilityService")]
public class AccessibilityService : Android.AccessibilityServices.AccessibilityService
{
private const string BitwardenPackage = "com.x8bit.bitwarden";
private const string BitwardenWebsite = "vault.bitwarden.com";
private IStateService _stateService;
private IBroadcasterService _broadcasterService;
private DateTime? _lastSettingsReload = null;
private TimeSpan _settingsReloadSpan = TimeSpan.FromMinutes(1);
private HashSet<string> _blacklistedUris;
private AccessibilityNodeInfo _anchorNode = null;
private int _lastAnchorX = 0;
private int _lastAnchorY = 0;
private bool _isOverlayAboveAnchor = false;
private static bool _overlayAnchorObserverRunning = false;
private IWindowManager _windowManager = null;
private LinearLayout _overlayView = null;
private int _overlayViewHeight = 0;
private long _lastAutoFillTime = 0;
private Java.Lang.Runnable _overlayAnchorObserverRunnable = null;
private Handler _handler = new Handler(Looper.MainLooper);
private HashSet<string> _launcherPackageNames = null;
private DateTime? _lastLauncherSetBuilt = null;
private TimeSpan _rebuildLauncherSpan = TimeSpan.FromHours(1);
public override void OnCreate()
{
base.OnCreate();
LoadServices();
var settingsTask = LoadSettingsAsync();
_broadcasterService.Subscribe(nameof(AccessibilityService), (message) =>
{
if (message.Command == "OnAutofillTileClick")
{
var runnable = new Java.Lang.Runnable(OnAutofillTileClick);
_handler.PostDelayed(runnable, 250);
}
});
AccessibilityHelpers.IsAccessibilityBroadcastReady = true;
}
public override void OnDestroy()
{
AccessibilityHelpers.IsAccessibilityBroadcastReady = false;
_broadcasterService.Unsubscribe(nameof(AccessibilityService));
}
public override void OnAccessibilityEvent(AccessibilityEvent e)
{
try
{
var powerManager = GetSystemService(PowerService) as PowerManager;
if (Build.VERSION.SdkInt > BuildVersionCodes.KitkatWatch && !powerManager.IsInteractive)
{
return;
}
else if (Build.VERSION.SdkInt < BuildVersionCodes.Lollipop && !powerManager.IsScreenOn)
{
return;
}
if (SkipPackage(e?.PackageName))
{
if (e?.PackageName != "com.android.systemui")
{
CancelOverlayPrompt();
}
return;
}
// AccessibilityHelpers.PrintTestData(RootInActiveWindow, e);
LoadServices();
var settingsTask = LoadSettingsAsync();
AccessibilityNodeInfo root = null;
switch (e.EventType)
{
case EventTypes.ViewFocused:
case EventTypes.ViewClicked:
if (e.Source == null || e.PackageName == BitwardenPackage)
{
CancelOverlayPrompt();
break;
}
root = RootInActiveWindow;
if (root == null || root.PackageName != e.PackageName)
{
break;
}
if (!(e.Source?.Password ?? false) && !AccessibilityHelpers.IsUsernameEditText(root, e))
{
CancelOverlayPrompt();
break;
}
if (ScanAndAutofill(root, e))
{
CancelOverlayPrompt();
}
else
{
OverlayPromptToAutofill(root, e);
}
break;
case EventTypes.WindowContentChanged:
case EventTypes.WindowStateChanged:
if (AccessibilityHelpers.LastCredentials == null)
{
break;
}
if (e.PackageName == BitwardenPackage)
{
CancelOverlayPrompt();
break;
}
root = RootInActiveWindow;
if (root == null || root.PackageName != e.PackageName)
{
break;
}
if (ScanAndAutofill(root, e))
{
CancelOverlayPrompt();
}
break;
default:
break;
}
}
// Suppress exceptions so that service doesn't crash.
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(">>> {0}: {1}", ex.GetType(), ex.StackTrace);
}
}
public override void OnInterrupt()
{
// Do nothing.
}
public bool ScanAndAutofill(AccessibilityNodeInfo root, AccessibilityEvent e)
{
var filled = false;
var uri = AccessibilityHelpers.GetUri(root);
if (uri != null && !uri.Contains(BitwardenWebsite) &&
AccessibilityHelpers.NeedToAutofill(AccessibilityHelpers.LastCredentials, uri))
{
var allEditTexts = AccessibilityHelpers.GetWindowNodes(root, e, n => AccessibilityHelpers.EditText(n), false);
var usernameEditText = AccessibilityHelpers.GetUsernameEditText(uri, allEditTexts);
var passwordNodes = AccessibilityHelpers.GetWindowNodes(root, e, n => n.Password, false);
if (usernameEditText != null || passwordNodes.Count > 0)
{
AccessibilityHelpers.FillCredentials(usernameEditText, passwordNodes);
filled = true;
_lastAutoFillTime = Java.Lang.JavaSystem.CurrentTimeMillis();
AccessibilityHelpers.LastCredentials = null;
}
allEditTexts.Dispose();
passwordNodes.Dispose();
}
if (AccessibilityHelpers.LastCredentials != null)
{
Task.Run(async () =>
{
await Task.Delay(1000);
AccessibilityHelpers.LastCredentials = null;
});
}
return filled;
}
private void OnAutofillTileClick()
{
CancelOverlayPrompt();
var root = RootInActiveWindow;
if (root != null && root.PackageName != BitwardenPackage &&
root.PackageName != AccessibilityHelpers.SystemUiPackage &&
!SkipPackage(root.PackageName))
{
var uri = AccessibilityHelpers.GetUri(root);
if (!string.IsNullOrWhiteSpace(uri))
{
var intent = new Intent(this, typeof(AccessibilityActivity));
intent.PutExtra("uri", uri);
intent.SetFlags(ActivityFlags.NewTask | ActivityFlags.SingleTop | ActivityFlags.ClearTop);
StartActivity(intent);
return;
}
}
Toast.MakeText(this, AppResources.AutofillTileUriNotFound, ToastLength.Long).Show();
}
private void CancelOverlayPrompt()
{
_overlayAnchorObserverRunning = false;
if (_windowManager != null && _overlayView != null)
{
try
{
_windowManager.RemoveViewImmediate(_overlayView);
System.Diagnostics.Debug.WriteLine(">>> Accessibility Overlay View Removed");
}
catch { }
}
_overlayView = null;
_lastAnchorX = 0;
_lastAnchorY = 0;
_isOverlayAboveAnchor = false;
if (_anchorNode != null)
{
_anchorNode.Recycle();
_anchorNode = null;
}
}
private void OverlayPromptToAutofill(AccessibilityNodeInfo root, AccessibilityEvent e)
{
if (Java.Lang.JavaSystem.CurrentTimeMillis() - _lastAutoFillTime < 1000 ||
AccessibilityHelpers.IsAutofillServicePromptVisible(Windows))
{
return;
}
if (!AccessibilityHelpers.OverlayPermitted())
{
if (Build.VERSION.SdkInt <= BuildVersionCodes.M)
{
// The user has the option of only using the autofill tile and leaving the overlay permission
// disabled, so only show this toast if they're using accessibility without overlay permission on
// a version of Android without quick-action tile support
System.Diagnostics.Debug.WriteLine(">>> Overlay Permission not granted");
Toast.MakeText(this, AppResources.AccessibilityDrawOverPermissionAlert, ToastLength.Long).Show();
}
return;
}
if (_overlayView != null || _anchorNode != null || _overlayAnchorObserverRunning)
{
CancelOverlayPrompt();
}
var uri = AccessibilityHelpers.GetUri(root);
var fillable = !string.IsNullOrWhiteSpace(uri);
if (fillable)
{
if (_blacklistedUris != null && _blacklistedUris.Any())
{
if (Uri.TryCreate(uri, UriKind.Absolute, out var parsedUri) && parsedUri.Scheme.StartsWith("http"))
{
fillable = !_blacklistedUris.Contains(
string.Format("{0}://{1}", parsedUri.Scheme, parsedUri.Host));
}
else
{
fillable = !_blacklistedUris.Contains(uri);
}
}
}
if (!fillable)
{
return;
}
var intent = new Intent(this, typeof(AccessibilityActivity));
intent.PutExtra("uri", uri);
intent.SetFlags(ActivityFlags.NewTask | ActivityFlags.SingleTop | ActivityFlags.ClearTop);
_overlayView = AccessibilityHelpers.GetOverlayView(this);
_overlayView.Measure(View.MeasureSpec.MakeMeasureSpec(0, 0),
View.MeasureSpec.MakeMeasureSpec(0, 0));
_overlayViewHeight = _overlayView.MeasuredHeight;
_overlayView.Click += (sender, eventArgs) =>
{
CancelOverlayPrompt();
StartActivity(intent);
};
var layoutParams = AccessibilityHelpers.GetOverlayLayoutParams();
var anchorPosition = AccessibilityHelpers.GetOverlayAnchorPosition(this, e.Source,
_overlayViewHeight, _isOverlayAboveAnchor);
layoutParams.X = anchorPosition.X;
layoutParams.Y = anchorPosition.Y;
if (_windowManager == null)
{
_windowManager = GetSystemService(WindowService).JavaCast<IWindowManager>();
}
_anchorNode = e.Source;
_lastAnchorX = anchorPosition.X;
_lastAnchorY = anchorPosition.Y;
_windowManager.AddView(_overlayView, layoutParams);
System.Diagnostics.Debug.WriteLine(">>> Accessibility Overlay View Added at X:{0} Y:{1}",
layoutParams.X, layoutParams.Y);
StartOverlayAnchorObserver();
}
private void StartOverlayAnchorObserver()
{
if (_overlayAnchorObserverRunning)
{
return;
}
_overlayAnchorObserverRunning = true;
_overlayAnchorObserverRunnable = new Java.Lang.Runnable(() =>
{
if (_overlayAnchorObserverRunning)
{
AdjustOverlayForScroll();
_handler.PostDelayed(_overlayAnchorObserverRunnable, 250);
}
});
_handler.PostDelayed(_overlayAnchorObserverRunnable, 250);
}
private void AdjustOverlayForScroll()
{
if (_overlayView == null || _anchorNode == null ||
AccessibilityHelpers.IsAutofillServicePromptVisible(Windows))
{
CancelOverlayPrompt();
return;
}
var root = RootInActiveWindow;
IEnumerable<AccessibilityWindowInfo> windows = null;
if (Build.VERSION.SdkInt > BuildVersionCodes.Kitkat)
{
windows = Windows;
}
var anchorPosition = AccessibilityHelpers.GetOverlayAnchorPosition(this, _anchorNode, root,
windows, _overlayViewHeight, _isOverlayAboveAnchor);
if (anchorPosition == null)
{
CancelOverlayPrompt();
return;
}
else if (anchorPosition.X == -1 && anchorPosition.Y == -1)
{
if (_overlayView.Visibility != ViewStates.Gone)
{
_overlayView.Visibility = ViewStates.Gone;
System.Diagnostics.Debug.WriteLine(">>> Accessibility Overlay View Hidden");
}
return;
}
else if (anchorPosition.X == -1)
{
_isOverlayAboveAnchor = false;
System.Diagnostics.Debug.WriteLine(">>> Accessibility Overlay View Below Anchor");
return;
}
else if (anchorPosition.Y == -1)
{
_isOverlayAboveAnchor = true;
System.Diagnostics.Debug.WriteLine(">>> Accessibility Overlay View Above Anchor");
return;
}
else if (anchorPosition.X == _lastAnchorX && anchorPosition.Y == _lastAnchorY)
{
if (_overlayView.Visibility != ViewStates.Visible)
{
_overlayView.Visibility = ViewStates.Visible;
}
return;
}
var layoutParams = AccessibilityHelpers.GetOverlayLayoutParams();
layoutParams.X = anchorPosition.X;
layoutParams.Y = anchorPosition.Y;
_lastAnchorX = anchorPosition.X;
_lastAnchorY = anchorPosition.Y;
_windowManager.UpdateViewLayout(_overlayView, layoutParams);
if (_overlayView.Visibility != ViewStates.Visible)
{
_overlayView.Visibility = ViewStates.Visible;
}
System.Diagnostics.Debug.WriteLine(">>> Accessibility Overlay View Updated to X:{0} Y:{1}",
layoutParams.X, layoutParams.Y);
}
private bool SkipPackage(string eventPackageName)
{
if (string.IsNullOrWhiteSpace(eventPackageName) ||
AccessibilityHelpers.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);
}
private void LoadServices()
{
if (_stateService == null)
{
_stateService = ServiceContainer.Resolve<IStateService>("stateService");
}
if (_broadcasterService == null)
{
_broadcasterService = ServiceContainer.Resolve<IBroadcasterService>("broadcasterService");
}
}
private async Task LoadSettingsAsync()
{
var now = DateTime.UtcNow;
if (_lastSettingsReload == null || (now - _lastSettingsReload.Value) > _settingsReloadSpan)
{
_lastSettingsReload = now;
var uris = await _stateService.GetAutofillBlacklistedUrisAsync();
if (uris != null)
{
_blacklistedUris = new HashSet<string>(uris);
}
var isAutoFillTileAdded = await _stateService.GetAutofillTileAddedAsync();
AccessibilityHelpers.IsAutofillTileAdded = isAutoFillTileAdded.GetValueOrDefault();
}
}
}
}

View File

@@ -0,0 +1,23 @@
using System;
namespace Bit.Droid.Accessibility
{
public class Browser
{
public Browser(string packageName, string uriViewId)
{
PackageName = packageName;
UriViewId = uriViewId;
}
public Browser(string packageName, string uriViewId, Func<string, string> getUriFunction)
: this(packageName, uriViewId)
{
GetUriFunction = getUriFunction;
}
public string PackageName { get; set; }
public string UriViewId { get; set; }
public Func<string, string> GetUriFunction { get; set; } = (s) => s;
}
}

View File

@@ -1,6 +1,6 @@
namespace Bit.Android
namespace Bit.Droid.Accessibility
{
public class AutofillCredentials
public class Credentials
{
public string Username { get; set; }
public string Password { get; set; }

View File

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

View File

@@ -0,0 +1,18 @@
using Android.Views.Accessibility;
using System;
using System.Collections.Generic;
namespace Bit.Droid.Accessibility
{
public class NodeList : List<AccessibilityNodeInfo>, IDisposable
{
public void Dispose()
{
foreach (var item in this)
{
item.Recycle();
item.Dispose();
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,19 +0,0 @@
Any raw assets you want to be deployed with your application can be placed in
this directory (and child directories) and given a Build Action of "AndroidAsset".
These files will be deployed with you package and will be accessible using Android's
AssetManager, like this:
public class ReadAsset : Activity
{
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
InputStream input = Assets.Open ("my_asset.txt");
}
}
Additionally, some Android functions will automatically load asset files:
Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf");

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

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

View File

@@ -1,113 +1,163 @@
using Android;
using System;
using System.Collections.Generic;
using System.Linq;
using Android;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Service.Autofill;
using Android.Widget;
using Bit.App;
using Bit.App.Abstractions;
using Bit.App.Enums;
using System.Collections.Generic;
using System.Linq;
using XLabs.Ioc;
using Bit.Core;
using Bit.Core.Abstractions;
using Bit.Core.Enums;
using Bit.Core.Utilities;
namespace Bit.Android.Autofill
namespace Bit.Droid.Autofill
{
[Service(Permission = Manifest.Permission.BindAutofillService, Label = "Bitwarden")]
[Service(Permission = Manifest.Permission.BindAutofillService, Label = "Bitwarden", Exported = true)]
[IntentFilter(new string[] { "android.service.autofill.AutofillService" })]
[MetaData("android.autofill", Resource = "@xml/autofillservice")]
[Register("com.x8bit.bitwarden.Autofill.AutofillService")]
public class AutofillService : global::Android.Service.Autofill.AutofillService
public class AutofillService : Android.Service.Autofill.AutofillService
{
private ICipherService _cipherService;
private ILockService _lockService;
private IVaultTimeoutService _vaultTimeoutService;
private IPolicyService _policyService;
private IStateService _stateService;
private LazyResolve<ILogger> _logger = new LazyResolve<ILogger>("logger");
public async override void OnFillRequest(FillRequest request, CancellationSignal cancellationSignal, FillCallback callback)
public async override void OnFillRequest(FillRequest request, CancellationSignal cancellationSignal,
FillCallback callback)
{
var structure = request.FillContexts?.LastOrDefault()?.Structure;
if(structure == null)
try
{
return;
}
var parser = new Parser(structure);
parser.Parse();
if(string.IsNullOrWhiteSpace(parser.Uri) || parser.Uri == "androidapp://com.x8bit.bitwarden" ||
parser.Uri == "androidapp://android" || !parser.FieldCollection.Fillable)
{
return;
}
if(_lockService == null)
{
_lockService = Resolver.Resolve<ILockService>();
}
List<FilledItem> items = null;
var locked = (await _lockService.GetLockTypeAsync(false)) != LockType.None;
if(!locked)
{
if(_cipherService == null)
var structure = request.FillContexts?.LastOrDefault()?.Structure;
if (structure == null)
{
_cipherService = Resolver.Resolve<ICipherService>();
return;
}
items = await AutofillHelpers.GetFillItemsAsync(parser, _cipherService);
}
var parser = new Parser(structure, ApplicationContext);
parser.Parse();
// build response
var response = AutofillHelpers.BuildFillResponse(this, parser, items, locked);
callback.OnSuccess(response);
if (_stateService == null)
{
_stateService = ServiceContainer.Resolve<IStateService>("stateService");
}
var shouldAutofill = await parser.ShouldAutofillAsync(_stateService);
if (!shouldAutofill)
{
return;
}
var inlineAutofillEnabled = await _stateService.GetInlineAutofillEnabledAsync() ?? true;
if (_vaultTimeoutService == null)
{
_vaultTimeoutService = ServiceContainer.Resolve<IVaultTimeoutService>("vaultTimeoutService");
}
List<FilledItem> items = null;
await _vaultTimeoutService.CheckVaultTimeoutAsync();
var locked = await _vaultTimeoutService.IsLockedAsync();
if (!locked)
{
if (_cipherService == null)
{
_cipherService = ServiceContainer.Resolve<ICipherService>("cipherService");
}
items = await AutofillHelpers.GetFillItemsAsync(parser, _cipherService);
}
// build response
var response = AutofillHelpers.CreateFillResponse(parser, items, locked, inlineAutofillEnabled, request);
var disableSavePrompt = await _stateService.GetAutofillDisableSavePromptAsync();
if (!disableSavePrompt.GetValueOrDefault())
{
AutofillHelpers.AddSaveInfo(parser, request, response, parser.FieldCollection);
}
callback.OnSuccess(response.Build());
}
catch (Exception e)
{
_logger.Value.Exception(e);
}
}
public override void OnSaveRequest(SaveRequest request, SaveCallback callback)
public async override void OnSaveRequest(SaveRequest request, SaveCallback callback)
{
var structure = request.FillContexts?.LastOrDefault()?.Structure;
if(structure == null)
try
{
return;
}
var parser = new Parser(structure);
parser.Parse();
var savedItem = parser.FieldCollection.GetSavedItem();
if(savedItem == null)
{
Toast.MakeText(this, "Unable to save this form.", ToastLength.Short).Show();
return;
}
var intent = new Intent(this, typeof(MainActivity));
intent.SetFlags(ActivityFlags.NewTask | ActivityFlags.ClearTop);
intent.PutExtra("autofillFramework", true);
intent.PutExtra("autofillFrameworkSave", true);
intent.PutExtra("autofillFrameworkType", (int)savedItem.Type);
switch(savedItem.Type)
{
case CipherType.Login:
intent.PutExtra("autofillFrameworkName", parser.Uri
.Replace(Constants.AndroidAppProtocol, string.Empty)
.Replace("https://", string.Empty)
.Replace("http://", string.Empty));
intent.PutExtra("autofillFrameworkUri", parser.Uri);
intent.PutExtra("autofillFrameworkUsername", savedItem.Login.Username);
intent.PutExtra("autofillFrameworkPassword", savedItem.Login.Password);
break;
case CipherType.Card:
intent.PutExtra("autofillFrameworkCardName", savedItem.Card.Name);
intent.PutExtra("autofillFrameworkCardNumber", savedItem.Card.Number);
intent.PutExtra("autofillFrameworkCardExpMonth", savedItem.Card.ExpMonth);
intent.PutExtra("autofillFrameworkCardExpYear", savedItem.Card.ExpYear);
intent.PutExtra("autofillFrameworkCardCode", savedItem.Card.Code);
break;
default:
Toast.MakeText(this, "Unable to save this type of form.", ToastLength.Short).Show();
var structure = request.FillContexts?.LastOrDefault()?.Structure;
if (structure == null)
{
return;
}
if (_stateService == null)
{
_stateService = ServiceContainer.Resolve<IStateService>("stateService");
}
var disableSavePrompt = await _stateService.GetAutofillDisableSavePromptAsync();
if (disableSavePrompt.GetValueOrDefault())
{
return;
}
_policyService ??= ServiceContainer.Resolve<IPolicyService>("policyService");
var personalOwnershipPolicyApplies = await _policyService.PolicyAppliesToUser(PolicyType.PersonalOwnership);
if (personalOwnershipPolicyApplies)
{
return;
}
var parser = new Parser(structure, ApplicationContext);
parser.Parse();
var savedItem = parser.FieldCollection.GetSavedItem();
if (savedItem == null)
{
Toast.MakeText(this, "Unable to save this form.", ToastLength.Short).Show();
return;
}
var intent = new Intent(this, typeof(MainActivity));
intent.SetFlags(ActivityFlags.NewTask | ActivityFlags.ClearTop);
intent.PutExtra("autofillFramework", true);
intent.PutExtra("autofillFrameworkSave", true);
intent.PutExtra("autofillFrameworkType", (int)savedItem.Type);
switch (savedItem.Type)
{
case CipherType.Login:
intent.PutExtra("autofillFrameworkName", parser.Uri
.Replace(Core.Constants.AndroidAppProtocol, string.Empty)
.Replace("https://", string.Empty)
.Replace("http://", string.Empty));
intent.PutExtra("autofillFrameworkUri", parser.Uri);
intent.PutExtra("autofillFrameworkUsername", savedItem.Login.Username);
intent.PutExtra("autofillFrameworkPassword", savedItem.Login.Password);
break;
case CipherType.Card:
intent.PutExtra("autofillFrameworkCardName", savedItem.Card.Name);
intent.PutExtra("autofillFrameworkCardNumber", savedItem.Card.Number);
intent.PutExtra("autofillFrameworkCardExpMonth", savedItem.Card.ExpMonth);
intent.PutExtra("autofillFrameworkCardExpYear", savedItem.Card.ExpYear);
intent.PutExtra("autofillFrameworkCardCode", savedItem.Card.Code);
break;
default:
Toast.MakeText(this, "Unable to save this type of form.", ToastLength.Short).Show();
return;
}
StartActivity(intent);
}
catch (Exception e)
{
_logger.Value.Exception(e);
}
StartActivity(intent);
}
}
}

View File

@@ -7,7 +7,7 @@ using static Android.App.Assist.AssistStructure;
using Android.Text;
using static Android.Views.ViewStructure;
namespace Bit.Android.Autofill
namespace Bit.Droid.Autofill
{
public class Field
{
@@ -31,26 +31,26 @@ namespace Bit.Android.Autofill
HtmlInfo = node.HtmlInfo;
Node = node;
if(node.AutofillValue != null)
if (node.AutofillValue != null)
{
if(node.AutofillValue.IsList)
if (node.AutofillValue.IsList)
{
var autofillOptions = node.GetAutofillOptions();
if(autofillOptions != null && autofillOptions.Length > 0)
if (autofillOptions != null && autofillOptions.Length > 0)
{
ListValue = node.AutofillValue.ListValue;
TextValue = autofillOptions[node.AutofillValue.ListValue];
}
}
else if(node.AutofillValue.IsDate)
else if (node.AutofillValue.IsDate)
{
DateValue = node.AutofillValue.DateValue;
}
else if(node.AutofillValue.IsText)
else if (node.AutofillValue.IsText)
{
TextValue = node.AutofillValue.TextValue;
}
else if(node.AutofillValue.IsToggle)
else if (node.AutofillValue.IsToggle)
{
ToggleValue = node.AutofillValue.ToggleValue;
}
@@ -86,17 +86,80 @@ namespace Bit.Android.Autofill
public HtmlInfo HtmlInfo { get; private set; }
public ViewNode Node { get; private set; }
public bool ValueIsNull()
{
return TextValue == null && DateValue == null && ToggleValue == null;
}
public override bool Equals(object obj)
{
if (this == obj)
{
return true;
}
if (obj == null || GetType() != obj.GetType())
{
return false;
}
var field = obj as Field;
if (TextValue != null ? !TextValue.Equals(field.TextValue) : field.TextValue != null)
{
return false;
}
if (DateValue != null ? !DateValue.Equals(field.DateValue) : field.DateValue != null)
{
return false;
}
return ToggleValue != null ? ToggleValue.Equals(field.ToggleValue) : field.ToggleValue == null;
}
public override int GetHashCode()
{
var result = TextValue != null ? TextValue.GetHashCode() : 0;
result = 31 * result + (DateValue != null ? DateValue.GetHashCode() : 0);
result = 31 * result + (ToggleValue != null ? ToggleValue.GetHashCode() : 0);
return result;
}
private static List<string> FilterForSupportedHints(string[] hints)
{
return hints?.Where(h => IsValidHint(h)).ToList() ?? new List<string>();
}
private static bool IsValidHint(string hint)
{
switch (hint)
{
case View.AutofillHintCreditCardExpirationDate:
case View.AutofillHintCreditCardExpirationDay:
case View.AutofillHintCreditCardExpirationMonth:
case View.AutofillHintCreditCardExpirationYear:
case View.AutofillHintCreditCardNumber:
case View.AutofillHintCreditCardSecurityCode:
case View.AutofillHintEmailAddress:
case View.AutofillHintPhone:
case View.AutofillHintName:
case View.AutofillHintPassword:
case View.AutofillHintPostalAddress:
case View.AutofillHintPostalCode:
case View.AutofillHintUsername:
return true;
default:
return false;
}
}
private void UpdateSaveTypeFromHints()
{
SaveType = SaveDataType.Generic;
if(_hints == null)
if (_hints == null)
{
return;
}
foreach(var hint in _hints)
foreach (var hint in _hints)
{
switch(hint)
switch (hint)
{
case View.AutofillHintCreditCardExpirationDate:
case View.AutofillHintCreditCardExpirationDay:
@@ -128,72 +191,5 @@ namespace Bit.Android.Autofill
}
}
}
public bool ValueIsNull()
{
return TextValue == null && DateValue == null && ToggleValue == null;
}
public override bool Equals(object obj)
{
if(this == obj)
{
return true;
}
if(obj == null || GetType() != obj.GetType())
{
return false;
}
var field = obj as Field;
if(TextValue != null ? !TextValue.Equals(field.TextValue) : field.TextValue != null)
{
return false;
}
if(DateValue != null ? !DateValue.Equals(field.DateValue) : field.DateValue != null)
{
return false;
}
return ToggleValue != null ? ToggleValue.Equals(field.ToggleValue) : field.ToggleValue == null;
}
public override int GetHashCode()
{
var result = TextValue != null ? TextValue.GetHashCode() : 0;
result = 31 * result + (DateValue != null ? DateValue.GetHashCode() : 0);
result = 31 * result + (ToggleValue != null ? ToggleValue.GetHashCode() : 0);
return result;
}
private static List<string> FilterForSupportedHints(string[] hints)
{
return hints?.Where(h => IsValidHint(h)).ToList() ?? new List<string>();
}
private static bool IsValidHint(string hint)
{
switch(hint)
{
case View.AutofillHintCreditCardExpirationDate:
case View.AutofillHintCreditCardExpirationDay:
case View.AutofillHintCreditCardExpirationMonth:
case View.AutofillHintCreditCardExpirationYear:
case View.AutofillHintCreditCardNumber:
case View.AutofillHintCreditCardSecurityCode:
case View.AutofillHintEmailAddress:
case View.AutofillHintPhone:
case View.AutofillHintName:
case View.AutofillHintPassword:
case View.AutofillHintPostalAddress:
case View.AutofillHintPostalCode:
case View.AutofillHintUsername:
return true;
default:
return false;
}
}
}
}

View File

@@ -5,7 +5,7 @@ using System.Linq;
using Android.Text;
using Android.Views;
namespace Bit.Android.Autofill
namespace Bit.Droid.Autofill
{
public class FieldCollection
{
@@ -19,11 +19,11 @@ namespace Bit.Android.Autofill
{
get
{
if(FillableForLogin)
if (FillableForLogin)
{
return SaveDataType.Password;
}
else if(FillableForCard)
else if (FillableForCard)
{
return SaveDataType.CreditCard;
}
@@ -43,15 +43,14 @@ namespace Bit.Android.Autofill
{
get
{
if(_passwordFields != null)
if (_passwordFields != null)
{
return _passwordFields;
}
if(Hints.Any())
if (Hints.Any())
{
_passwordFields = new List<Field>();
if(HintToFieldsMap.ContainsKey(View.AutofillHintPassword))
if (HintToFieldsMap.ContainsKey(View.AutofillHintPassword))
{
_passwordFields.AddRange(HintToFieldsMap[View.AutofillHintPassword]);
}
@@ -59,12 +58,11 @@ namespace Bit.Android.Autofill
else
{
_passwordFields = Fields.Where(f => FieldIsPassword(f)).ToList();
if(!_passwordFields.Any())
if (!_passwordFields.Any())
{
_passwordFields = Fields.Where(f => FieldHasPasswordTerms(f)).ToList();
}
}
return _passwordFields;
}
}
@@ -73,80 +71,85 @@ namespace Bit.Android.Autofill
{
get
{
if(_usernameFields != null)
if (_usernameFields != null)
{
return _usernameFields;
}
_usernameFields = new List<Field>();
if(Hints.Any())
if (Hints.Any())
{
if(HintToFieldsMap.ContainsKey(View.AutofillHintEmailAddress))
if (HintToFieldsMap.ContainsKey(View.AutofillHintEmailAddress))
{
_usernameFields.AddRange(HintToFieldsMap[View.AutofillHintEmailAddress]);
}
if(HintToFieldsMap.ContainsKey(View.AutofillHintUsername))
if (HintToFieldsMap.ContainsKey(View.AutofillHintUsername))
{
_usernameFields.AddRange(HintToFieldsMap[View.AutofillHintUsername]);
}
}
else
{
foreach(var passwordField in PasswordFields)
foreach (var passwordField in PasswordFields)
{
var usernameField = Fields.TakeWhile(f => f.AutofillId != passwordField.AutofillId)
.LastOrDefault();
if(usernameField != null)
if (usernameField != null)
{
_usernameFields.Add(usernameField);
}
}
}
return _usernameFields;
}
}
public bool FillableForLogin => FocusedHintsContain(
new string[] { View.AutofillHintUsername, View.AutofillHintEmailAddress, View.AutofillHintPassword }) ||
UsernameFields.Any(f => f.Focused) || PasswordFields.Any(f => f.Focused);
public bool FillableForCard => FocusedHintsContain(
new string[] { View.AutofillHintCreditCardNumber, View.AutofillHintCreditCardExpirationMonth,
View.AutofillHintCreditCardExpirationYear, View.AutofillHintCreditCardSecurityCode});
public bool FillableForIdentity => FocusedHintsContain(
new string[] { View.AutofillHintName, View.AutofillHintPhone, View.AutofillHintPostalAddress,
View.AutofillHintPostalCode });
public bool FillableForLogin => FocusedHintsContain(new string[] {
View.AutofillHintUsername,
View.AutofillHintEmailAddress,
View.AutofillHintPassword
}) || UsernameFields.Any(f => f.Focused) || PasswordFields.Any(f => f.Focused);
public bool FillableForCard => FocusedHintsContain(new string[] {
View.AutofillHintCreditCardNumber,
View.AutofillHintCreditCardExpirationMonth,
View.AutofillHintCreditCardExpirationYear,
View.AutofillHintCreditCardSecurityCode
});
public bool FillableForIdentity => FocusedHintsContain(new string[] {
View.AutofillHintName,
View.AutofillHintPhone,
View.AutofillHintPostalAddress,
View.AutofillHintPostalCode
});
public bool Fillable => FillableForLogin || FillableForCard || FillableForIdentity;
public void Add(Field field)
{
if(field == null || FieldTrackingIds.Contains(field.TrackingId))
if (field == null || FieldTrackingIds.Contains(field.TrackingId))
{
return;
}
_passwordFields = _usernameFields = null;
FieldTrackingIds.Add(field.TrackingId);
Fields.Add(field);
AutofillIds.Add(field.AutofillId);
if(field.Hints != null)
if (field.Hints != null)
{
foreach(var hint in field.Hints)
foreach (var hint in field.Hints)
{
Hints.Add(hint);
if(field.Focused)
if (field.Focused)
{
FocusedHints.Add(hint);
}
if(!HintToFieldsMap.ContainsKey(hint))
if (!HintToFieldsMap.ContainsKey(hint))
{
HintToFieldsMap.Add(hint, new List<Field>());
}
HintToFieldsMap[hint].Add(field);
}
}
@@ -154,17 +157,17 @@ namespace Bit.Android.Autofill
public SavedItem GetSavedItem()
{
if(SaveType == SaveDataType.Password)
if (SaveType == SaveDataType.Password)
{
var passwordField = PasswordFields.FirstOrDefault(f => !string.IsNullOrWhiteSpace(f.TextValue));
if(passwordField == null)
if (passwordField == null)
{
return null;
}
var savedItem = new SavedItem
{
Type = App.Enums.CipherType.Login,
Type = Core.Enums.CipherType.Login,
Login = new SavedItem.LoginItem
{
Password = GetFieldValue(passwordField)
@@ -173,14 +176,13 @@ namespace Bit.Android.Autofill
var usernameField = Fields.TakeWhile(f => f.AutofillId != passwordField.AutofillId).LastOrDefault();
savedItem.Login.Username = GetFieldValue(usernameField);
return savedItem;
}
else if(SaveType == SaveDataType.CreditCard)
else if (SaveType == SaveDataType.CreditCard)
{
var savedItem = new SavedItem
{
Type = App.Enums.CipherType.Card,
Type = Core.Enums.CipherType.Card,
Card = new SavedItem.CardItem
{
Number = GetFieldValue(View.AutofillHintCreditCardNumber),
@@ -190,55 +192,51 @@ namespace Bit.Android.Autofill
Code = GetFieldValue(View.AutofillHintCreditCardSecurityCode)
}
};
return savedItem;
}
return null;
}
public AutofillId[] GetOptionalSaveIds()
{
if(SaveType == SaveDataType.Password)
if (SaveType == SaveDataType.Password)
{
return UsernameFields.Select(f => f.AutofillId).ToArray();
}
else if(SaveType == SaveDataType.CreditCard)
else if (SaveType == SaveDataType.CreditCard)
{
var fieldList = new List<Field>();
if(HintToFieldsMap.ContainsKey(View.AutofillHintCreditCardSecurityCode))
if (HintToFieldsMap.ContainsKey(View.AutofillHintCreditCardSecurityCode))
{
fieldList.AddRange(HintToFieldsMap[View.AutofillHintCreditCardSecurityCode]);
}
if(HintToFieldsMap.ContainsKey(View.AutofillHintCreditCardExpirationYear))
if (HintToFieldsMap.ContainsKey(View.AutofillHintCreditCardExpirationYear))
{
fieldList.AddRange(HintToFieldsMap[View.AutofillHintCreditCardExpirationYear]);
}
if(HintToFieldsMap.ContainsKey(View.AutofillHintCreditCardExpirationMonth))
if (HintToFieldsMap.ContainsKey(View.AutofillHintCreditCardExpirationMonth))
{
fieldList.AddRange(HintToFieldsMap[View.AutofillHintCreditCardExpirationMonth]);
}
if(HintToFieldsMap.ContainsKey(View.AutofillHintName))
if (HintToFieldsMap.ContainsKey(View.AutofillHintName))
{
fieldList.AddRange(HintToFieldsMap[View.AutofillHintName]);
}
return fieldList.Select(f => f.AutofillId).ToArray();
}
return new AutofillId[0];
}
public AutofillId[] GetRequiredSaveFields()
{
if(SaveType == SaveDataType.Password)
if (SaveType == SaveDataType.Password)
{
return PasswordFields.Select(f => f.AutofillId).ToArray();
}
else if(SaveType == SaveDataType.CreditCard && HintToFieldsMap.ContainsKey(View.AutofillHintCreditCardNumber))
else if (SaveType == SaveDataType.CreditCard && HintToFieldsMap.ContainsKey(View.AutofillHintCreditCardNumber))
{
return HintToFieldsMap[View.AutofillHintCreditCardNumber].Select(f => f.AutofillId).ToArray();
}
return new AutofillId[0];
}
@@ -249,52 +247,49 @@ namespace Bit.Android.Autofill
private string GetFieldValue(string hint, bool monthValue = false)
{
if(HintToFieldsMap.ContainsKey(hint))
if (HintToFieldsMap.ContainsKey(hint))
{
foreach(var field in HintToFieldsMap[hint])
foreach (var field in HintToFieldsMap[hint])
{
var val = GetFieldValue(field, monthValue);
if(!string.IsNullOrWhiteSpace(val))
if (!string.IsNullOrWhiteSpace(val))
{
return val;
}
}
}
return null;
}
private string GetFieldValue(Field field, bool monthValue = false)
{
if(field == null)
if (field == null)
{
return null;
}
if(!string.IsNullOrWhiteSpace(field.TextValue))
if (!string.IsNullOrWhiteSpace(field.TextValue))
{
if(field.AutofillType == AutofillType.List && field.ListValue.HasValue && monthValue)
if (field.AutofillType == AutofillType.List && field.ListValue.HasValue && monthValue)
{
if(field.AutofillOptions.Count == 13)
if (field.AutofillOptions.Count == 13)
{
return field.ListValue.ToString();
}
else if(field.AutofillOptions.Count == 12)
else if (field.AutofillOptions.Count == 12)
{
return (field.ListValue + 1).ToString();
}
}
return field.TextValue;
}
else if(field.DateValue.HasValue)
else if (field.DateValue.HasValue)
{
return field.DateValue.Value.ToString();
}
else if(field.ToggleValue.HasValue)
else if (field.ToggleValue.HasValue)
{
return field.ToggleValue.Value.ToString();
}
return null;
}
@@ -304,14 +299,21 @@ namespace Bit.Android.Autofill
f.InputType.HasFlag(InputTypes.TextVariationVisiblePassword) ||
f.InputType.HasFlag(InputTypes.TextVariationWebPassword);
if(!inputTypePassword && f.HtmlInfo != null && f.HtmlInfo.Tag == "input" &&
// For whatever reason, multi-line input types are coming through with TextVariationPassword flags
if (inputTypePassword && f.InputType.HasFlag(InputTypes.TextVariationPassword) &&
f.InputType.HasFlag(InputTypes.TextFlagMultiLine))
{
inputTypePassword = false;
}
if (!inputTypePassword && f.HtmlInfo != null && f.HtmlInfo.Tag == "input" &&
(f.HtmlInfo.Attributes?.Any() ?? false))
{
foreach(var a in f.HtmlInfo.Attributes)
foreach (var a in f.HtmlInfo.Attributes)
{
var key = a.First as Java.Lang.String;
var val = a.Second as Java.Lang.String;
if(key != null && val != null && key.ToString() == "type" && val.ToString() == "password")
if (key != null && val != null && key.ToString() == "type" && val.ToString() == "password")
{
return true;
}
@@ -329,11 +331,10 @@ namespace Bit.Android.Autofill
private bool ValueContainsAnyTerms(string value, HashSet<string> terms)
{
if(string.IsNullOrWhiteSpace(value))
if (string.IsNullOrWhiteSpace(value))
{
return false;
}
var lowerValue = value.ToLowerInvariant();
return terms.Any(t => lowerValue.Contains(t));
}

View File

@@ -1,107 +1,56 @@
using System;
using Android.Service.Autofill;
using Android.Service.Autofill;
using Android.Views.Autofill;
using System.Linq;
using Bit.App.Models;
using Bit.App.Enums;
using Bit.Core.Enums;
using Android.Views;
using Bit.Core.Models.View;
namespace Bit.Android.Autofill
namespace Bit.Droid.Autofill
{
public class FilledItem
{
private Lazy<string> _password;
private Lazy<string> _cardName;
private string _password;
private string _cardName;
private string _cardNumber;
private Lazy<string> _cardExpMonth;
private Lazy<string> _cardExpYear;
private Lazy<string> _cardCode;
private Lazy<string> _idPhone;
private Lazy<string> _idEmail;
private Lazy<string> _idUsername;
private Lazy<string> _idAddress;
private Lazy<string> _idPostalCode;
private string _cardExpMonth;
private string _cardExpYear;
private string _cardCode;
private string _idPhone;
private string _idEmail;
private string _idUsername;
private string _idAddress;
private string _idPostalCode;
public FilledItem(Cipher cipher)
public FilledItem(CipherView cipher)
{
Name = cipher.Name?.Decrypt(cipher.OrganizationId) ?? "--";
Name = cipher.Name;
Type = cipher.Type;
Subtitle = cipher.SubTitle;
switch(Type)
switch (Type)
{
case CipherType.Login:
Subtitle = cipher.Login.Username?.Decrypt(cipher.OrganizationId) ?? string.Empty;
Icon = Resource.Drawable.login;
_password = new Lazy<string>(() => cipher.Login.Password?.Decrypt(cipher.OrganizationId));
_password = cipher.Login.Password;
break;
case CipherType.Card:
Subtitle = cipher.Card.Brand?.Decrypt(cipher.OrganizationId);
_cardNumber = cipher.Card.Number?.Decrypt(cipher.OrganizationId);
if(!string.IsNullOrWhiteSpace(_cardNumber) && _cardNumber.Length >= 4)
{
if(!string.IsNullOrWhiteSpace(_cardNumber))
{
Subtitle += ", ";
}
Subtitle += ("*" + _cardNumber.Substring(_cardNumber.Length - 4));
}
_cardNumber = cipher.Card.Number;
Icon = Resource.Drawable.card;
_cardName = new Lazy<string>(() => cipher.Card.CardholderName?.Decrypt(cipher.OrganizationId));
_cardCode = new Lazy<string>(() => cipher.Card.Code?.Decrypt(cipher.OrganizationId));
_cardExpMonth = new Lazy<string>(() => cipher.Card.ExpMonth?.Decrypt(cipher.OrganizationId));
_cardExpYear = new Lazy<string>(() => cipher.Card.ExpYear?.Decrypt(cipher.OrganizationId));
_cardName = cipher.Card.CardholderName;
_cardCode = cipher.Card.Code;
_cardExpMonth = cipher.Card.ExpMonth;
_cardExpYear = cipher.Card.ExpYear;
break;
case CipherType.Identity:
var firstName = cipher.Identity?.FirstName?.Decrypt(cipher.OrganizationId) ?? " ";
var lastName = cipher.Identity?.LastName?.Decrypt(cipher.OrganizationId) ?? " ";
Subtitle = " ";
if(!string.IsNullOrWhiteSpace(firstName))
{
Subtitle = firstName;
}
if(!string.IsNullOrWhiteSpace(lastName))
{
if(!string.IsNullOrWhiteSpace(Subtitle))
{
Subtitle += " ";
}
Subtitle += lastName;
}
Icon = Resource.Drawable.id;
_idPhone = new Lazy<string>(() => cipher.Identity.Phone?.Decrypt(cipher.OrganizationId));
_idEmail = new Lazy<string>(() => cipher.Identity.Email?.Decrypt(cipher.OrganizationId));
_idUsername = new Lazy<string>(() => cipher.Identity.Username?.Decrypt(cipher.OrganizationId));
_idAddress = new Lazy<string>(() =>
{
var address = cipher.Identity.Address1?.Decrypt(cipher.OrganizationId);
var address2 = cipher.Identity.Address2?.Decrypt(cipher.OrganizationId);
if(!string.IsNullOrWhiteSpace(address2))
{
if(!string.IsNullOrWhiteSpace(address))
{
address += ", ";
}
address += address2;
}
var address3 = cipher.Identity.Address3?.Decrypt(cipher.OrganizationId);
if(!string.IsNullOrWhiteSpace(address3))
{
if(!string.IsNullOrWhiteSpace(address))
{
address += ", ";
}
address += address3;
}
return address;
});
_idPostalCode = new Lazy<string>(() => cipher.Identity.PostalCode?.Decrypt(cipher.OrganizationId));
_idPhone = cipher.Identity.Phone;
_idEmail = cipher.Identity.Email;
_idUsername = cipher.Identity.Username;
_idAddress = cipher.Identity.FullAddress;
_idPostalCode = cipher.Identity.PostalCode;
break;
default:
Icon = Resource.Drawable.login;
break;
}
}
@@ -113,33 +62,32 @@ namespace Bit.Android.Autofill
public bool ApplyToFields(FieldCollection fieldCollection, Dataset.Builder datasetBuilder)
{
if(!fieldCollection?.Fields.Any() ?? true)
if (!fieldCollection?.Fields.Any() ?? true)
{
return false;
}
var setValues = false;
if(Type == CipherType.Login)
if (Type == CipherType.Login)
{
if(fieldCollection.PasswordFields.Any() && !string.IsNullOrWhiteSpace(_password.Value))
if (fieldCollection.PasswordFields.Any() && !string.IsNullOrWhiteSpace(_password))
{
foreach(var f in fieldCollection.PasswordFields)
foreach (var f in fieldCollection.PasswordFields)
{
var val = ApplyValue(f, _password.Value);
if(val != null)
var val = ApplyValue(f, _password);
if (val != null)
{
setValues = true;
datasetBuilder.SetValue(f.AutofillId, val);
}
}
}
if(fieldCollection.UsernameFields.Any() && !string.IsNullOrWhiteSpace(Subtitle))
if (fieldCollection.UsernameFields.Any() && !string.IsNullOrWhiteSpace(Subtitle))
{
foreach(var f in fieldCollection.UsernameFields)
foreach (var f in fieldCollection.UsernameFields)
{
var val = ApplyValue(f, Subtitle);
if(val != null)
if (val != null)
{
setValues = true;
datasetBuilder.SetValue(f.AutofillId, val);
@@ -147,71 +95,76 @@ namespace Bit.Android.Autofill
}
}
}
else if(Type == CipherType.Card)
else if (Type == CipherType.Card)
{
if(ApplyValue(datasetBuilder, fieldCollection, View.AutofillHintCreditCardNumber,
new Lazy<string>(() => _cardNumber)))
if (ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintCreditCardNumber,
_cardNumber))
{
setValues = true;
}
if(ApplyValue(datasetBuilder, fieldCollection, View.AutofillHintCreditCardSecurityCode, _cardCode))
if (ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintCreditCardSecurityCode,
_cardCode))
{
setValues = true;
}
if(ApplyValue(datasetBuilder, fieldCollection, View.AutofillHintCreditCardExpirationMonth, _cardExpMonth, true))
if (ApplyValue(datasetBuilder, fieldCollection,
Android.Views.View.AutofillHintCreditCardExpirationMonth, _cardExpMonth, true))
{
setValues = true;
}
if(ApplyValue(datasetBuilder, fieldCollection, View.AutofillHintCreditCardExpirationYear, _cardExpYear))
if (ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintCreditCardExpirationYear,
_cardExpYear))
{
setValues = true;
}
if(ApplyValue(datasetBuilder, fieldCollection, View.AutofillHintName, _cardName))
if (ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintName, _cardName))
{
setValues = true;
}
}
else if(Type == CipherType.Identity)
else if (Type == CipherType.Identity)
{
if(ApplyValue(datasetBuilder, fieldCollection, View.AutofillHintPhone, _idPhone))
if (ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintPhone, _idPhone))
{
setValues = true;
}
if(ApplyValue(datasetBuilder, fieldCollection, View.AutofillHintEmailAddress, _idEmail))
if (ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintEmailAddress, _idEmail))
{
setValues = true;
}
if(ApplyValue(datasetBuilder, fieldCollection, View.AutofillHintUsername, _idUsername))
if (ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintUsername,
_idUsername))
{
setValues = true;
}
if(ApplyValue(datasetBuilder, fieldCollection, View.AutofillHintPostalAddress, _idAddress))
if (ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintPostalAddress,
_idAddress))
{
setValues = true;
}
if(ApplyValue(datasetBuilder, fieldCollection, View.AutofillHintPostalCode, _idPostalCode))
if (ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintPostalCode,
_idPostalCode))
{
setValues = true;
}
if(ApplyValue(datasetBuilder, fieldCollection, View.AutofillHintName, new Lazy<string>(() => Subtitle)))
if (ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintName, Subtitle))
{
setValues = true;
}
}
return setValues;
}
private static bool ApplyValue(Dataset.Builder builder, FieldCollection fieldCollection,
string hint, Lazy<string> value, bool monthValue = false)
string hint, string value, bool monthValue = false)
{
bool setValues = false;
if(fieldCollection.HintToFieldsMap.ContainsKey(hint) && !string.IsNullOrWhiteSpace(value.Value))
if (fieldCollection.HintToFieldsMap.ContainsKey(hint) && !string.IsNullOrWhiteSpace(value))
{
foreach(var f in fieldCollection.HintToFieldsMap[hint])
foreach (var f in fieldCollection.HintToFieldsMap[hint])
{
var val = ApplyValue(f, value.Value, monthValue);
if(val != null)
var val = ApplyValue(f, value, monthValue);
if (val != null)
{
setValues = true;
builder.SetValue(f.AutofillId, val);
@@ -223,32 +176,31 @@ namespace Bit.Android.Autofill
private static AutofillValue ApplyValue(Field field, string value, bool monthValue = false)
{
switch(field.AutofillType)
switch (field.AutofillType)
{
case AutofillType.Date:
if(long.TryParse(value, out long dateValue))
if (long.TryParse(value, out long dateValue))
{
return AutofillValue.ForDate(dateValue);
}
break;
case AutofillType.List:
if(field.AutofillOptions != null)
if (field.AutofillOptions != null)
{
if(monthValue && int.TryParse(value, out int monthIndex))
if (monthValue && int.TryParse(value, out int monthIndex))
{
if(field.AutofillOptions.Count == 13)
if (field.AutofillOptions.Count == 13)
{
return AutofillValue.ForList(monthIndex);
}
else if(field.AutofillOptions.Count >= monthIndex)
else if (field.AutofillOptions.Count >= monthIndex)
{
return AutofillValue.ForList(monthIndex - 1);
}
}
for(var i = 0; i < field.AutofillOptions.Count; i++)
for (var i = 0; i < field.AutofillOptions.Count; i++)
{
if(field.AutofillOptions[i].Equals(value))
if (field.AutofillOptions[i].Equals(value))
{
return AutofillValue.ForList(i);
}
@@ -258,7 +210,7 @@ namespace Bit.Android.Autofill
case AutofillType.Text:
return AutofillValue.ForText(value);
case AutofillType.Toggle:
if(bool.TryParse(value, out bool toggleValue))
if (bool.TryParse(value, out bool toggleValue))
{
return AutofillValue.ForToggle(toggleValue);
}
@@ -266,8 +218,7 @@ namespace Bit.Android.Autofill
default:
break;
}
return null;
}
}
}
}

View File

@@ -1,101 +1,120 @@
using static Android.App.Assist.AssistStructure;
using Android.App.Assist;
using Bit.App;
using System.Collections.Generic;
using Bit.Core;
using Android.Content;
using Bit.Core.Abstractions;
using System.Threading.Tasks;
using Android.OS;
namespace Bit.Android.Autofill
namespace Bit.Droid.Autofill
{
public class Parser
{
public static HashSet<string> TrustedBrowsers = new HashSet<string>
{
"org.mozilla.focus","org.mozilla.firefox","org.mozilla.firefox_beta","com.microsoft.emmx",
"com.android.chrome","com.chrome.beta","com.android.browser","com.brave.browser","com.opera.browser",
"com.opera.browser.beta","com.opera.mini.native","com.chrome.dev","com.chrome.canary",
"com.google.android.apps.chrome","com.google.android.apps.chrome_dev","com.yandex.browser",
"com.sec.android.app.sbrowser","com.sec.android.app.sbrowser.beta","org.codeaurora.swe.browser",
"com.amazon.cloud9","org.mozilla.klar","com.duckduckgo.mobile.android","mark.via.gp","org.bromite.bromite"
};
public static HashSet<string> ExcludedPackageIds = new HashSet<string>
public static HashSet<string> _excludedPackageIds = new HashSet<string>
{
"android"
};
private readonly AssistStructure _structure;
private string _uri;
private string _packageName;
private string _webDomain;
private string _website;
public Parser(AssistStructure structure)
public Parser(AssistStructure structure, Context applicationContext)
{
_structure = structure;
ApplicationContext = applicationContext;
}
public Context ApplicationContext { get; set; }
public FieldCollection FieldCollection { get; private set; } = new FieldCollection();
public string Uri
{
get
{
if(!string.IsNullOrWhiteSpace(_uri))
if (!string.IsNullOrWhiteSpace(_uri))
{
return _uri;
}
if(string.IsNullOrWhiteSpace(WebDomain) && string.IsNullOrWhiteSpace(PackageName))
var websiteNull = string.IsNullOrWhiteSpace(Website);
if (websiteNull && string.IsNullOrWhiteSpace(PackageName))
{
_uri = null;
}
else if(!string.IsNullOrWhiteSpace(WebDomain))
else if (!websiteNull)
{
_uri = string.Concat("http://", WebDomain);
_uri = Website;
}
else
{
_uri = string.Concat(Constants.AndroidAppProtocol, PackageName);
_uri = string.Concat(Core.Constants.AndroidAppProtocol, PackageName);
}
return _uri;
}
}
public string PackageName
{
get => _packageName;
set
{
if(string.IsNullOrWhiteSpace(value))
if (string.IsNullOrWhiteSpace(value))
{
_packageName = _uri = null;
}
_packageName = value;
}
}
public string WebDomain
public string Website
{
get => _webDomain;
get => _website;
set
{
if(string.IsNullOrWhiteSpace(value))
if (string.IsNullOrWhiteSpace(value))
{
_webDomain = _uri = null;
_website = _uri = null;
}
_webDomain = value;
_website = value;
}
}
public async Task<bool> ShouldAutofillAsync(IStateService stateService)
{
var fillable = !string.IsNullOrWhiteSpace(Uri) && !AutofillHelpers.BlacklistedUris.Contains(Uri) &&
FieldCollection != null && FieldCollection.Fillable;
if (fillable)
{
var blacklistedUris = await stateService.GetAutofillBlacklistedUrisAsync();
if (blacklistedUris != null && blacklistedUris.Count > 0)
{
fillable = !new HashSet<string>(blacklistedUris).Contains(Uri);
}
}
return fillable;
}
public void Parse()
{
for(var i = 0; i < _structure.WindowNodeCount; i++)
string titlePackageId = null;
for (var i = 0; i < _structure.WindowNodeCount; i++)
{
var node = _structure.GetWindowNodeAt(i);
if (i == 0)
{
titlePackageId = GetTitlePackageId(node);
}
ParseNode(node.RootViewNode);
}
if(!TrustedBrowsers.Contains(PackageName))
if (string.IsNullOrWhiteSpace(PackageName) && string.IsNullOrWhiteSpace(Website))
{
WebDomain = null;
PackageName = titlePackageId;
}
if (!AutofillHelpers.TrustedBrowsers.Contains(PackageName) &&
!AutofillHelpers.CompatBrowsers.Contains(PackageName))
{
Website = null;
}
}
@@ -104,7 +123,7 @@ namespace Bit.Android.Autofill
SetPackageAndDomain(node);
var hints = node.GetAutofillHints();
var isEditText = node.ClassName == "android.widget.EditText" || node?.HtmlInfo?.Tag == "input";
if(isEditText || (hints?.Length ?? 0) > 0)
if (isEditText || (hints?.Length ?? 0) > 0)
{
FieldCollection.Add(new Field(node));
}
@@ -113,7 +132,7 @@ namespace Bit.Android.Autofill
FieldCollection.IgnoreAutofillIds.Add(node.AutofillId);
}
for(var i = 0; i < node.ChildCount; i++)
for (var i = 0; i < node.ChildCount; i++)
{
ParseNode(node.GetChildAt(i));
}
@@ -121,15 +140,37 @@ namespace Bit.Android.Autofill
private void SetPackageAndDomain(ViewNode node)
{
if(string.IsNullOrWhiteSpace(PackageName) && !string.IsNullOrWhiteSpace(node.IdPackage) &&
!ExcludedPackageIds.Contains(node.IdPackage))
if (string.IsNullOrWhiteSpace(PackageName) && !string.IsNullOrWhiteSpace(node.IdPackage) &&
!_excludedPackageIds.Contains(node.IdPackage))
{
PackageName = node.IdPackage;
}
if(string.IsNullOrWhiteSpace(WebDomain) && !string.IsNullOrWhiteSpace(node.WebDomain))
if (string.IsNullOrWhiteSpace(Website) && !string.IsNullOrWhiteSpace(node.WebDomain))
{
WebDomain = node.WebDomain;
var scheme = "http";
if ((int)Build.VERSION.SdkInt >= 28)
{
scheme = node.WebScheme;
}
Website = string.Format("{0}://{1}", scheme, node.WebDomain);
}
}
private string GetTitlePackageId(WindowNode node)
{
if (node != null && !string.IsNullOrWhiteSpace(node.Title))
{
var slashPosition = node.Title.IndexOf('/');
if (slashPosition > -1)
{
var packageId = node.Title.Substring(0, slashPosition);
if (packageId.Contains("."))
{
return packageId;
}
}
}
return null;
}
}
}
}

View File

@@ -1,6 +1,6 @@
using Bit.App.Enums;
using Bit.Core.Enums;
namespace Bit.Android.Autofill
namespace Bit.Droid.Autofill
{
public class SavedItem
{

View File

@@ -1,541 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Android.AccessibilityServices;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Views.Accessibility;
using Bit.App.Abstractions;
using XLabs.Ioc;
using Bit.App.Resources;
namespace Bit.Android
{
[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 = "vault.bitwarden.com";
private static Dictionary<string, Browser> SupportedBrowsers => new List<Browser>
{
new Browser("com.android.chrome", "url_bar"),
new Browser("com.chrome.beta", "url_bar"),
new Browser("com.android.browser", "url"),
new Browser("com.brave.browser", "url_bar"),
new Browser("com.opera.browser", "url_field"),
new Browser("com.opera.browser.beta", "url_field"),
new Browser("com.opera.mini.native", "url_field"),
new Browser("com.chrome.dev", "url_bar"),
new Browser("com.chrome.canary", "url_bar"),
new Browser("com.google.android.apps.chrome", "url_bar"),
new Browser("com.google.android.apps.chrome_dev", "url_bar"),
new Browser("org.codeaurora.swe.browser", "url_bar"),
new Browser("org.iron.srware", "url_bar"),
new Browser("com.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(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"),
new Browser("com.amazon.cloud9", "url"),
new Browser("mobi.mgeek.TunnyBrowser", "title"),
new Browser("com.nubelacorp.javelin", "enterUrl"),
new Browser("com.jerky.browser2", "enterUrl"),
new Browser("com.mx.browser", "address_editor_with_progress"),
new Browser("com.mx.browser.tablet", "address_editor_with_progress"),
new Browser("com.linkbubble.playstore", "url_text"),
new Browser("com.ksmobile.cb", "address_bar_edit_text"),
new Browser("acr.browser.lightning", "search"),
new Browser("acr.browser.barebones", "search"),
new Browser("com.microsoft.emmx", "url_bar"),
new Browser("com.duckduckgo.mobile.android", "omnibarTextInput"),
new Browser("mark.via.gp", "aw"),
new Browser("org.bromite.bromite", "url_bar"),
}.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()
{
_appSettings = Resolver.Resolve<IAppSettingsService>();
}
public override void OnAccessibilityEvent(AccessibilityEvent e)
{
var powerManager = (PowerManager)GetSystemService(PowerService);
if(Build.VERSION.SdkInt > BuildVersionCodes.KitkatWatch && !powerManager.IsInteractive)
{
return;
}
else if(Build.VERSION.SdkInt < BuildVersionCodes.Lollipop && !powerManager.IsScreenOn)
{
return;
}
try
{
if(SkipPackage(e?.PackageName))
{
return;
}
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;
switch(e.EventType)
{
case EventTypes.ViewFocused:
if(e.Source == null || !e.Source.Password || !_appSettings.AutofillPasswordField)
{
break;
}
if(e.PackageName == BitwardenPackage)
{
CancelNotification(notificationManager);
break;
}
if(ScanAndAutofill(root, e, notificationManager, cancelNotification))
{
CancelNotification(notificationManager);
}
break;
case EventTypes.WindowContentChanged:
case EventTypes.WindowStateChanged:
if(_appSettings.AutofillPasswordField && e.Source.Password)
{
break;
}
else if(_appSettings.AutofillPasswordField && AutofillActivity.LastCredentials == null)
{
if(string.IsNullOrWhiteSpace(_lastNotificationUri))
{
CancelNotification(notificationManager);
break;
}
var uri = GetUri(root);
if(uri != _lastNotificationUri)
{
CancelNotification(notificationManager);
}
else if(uri.StartsWith(App.Constants.AndroidAppProtocol))
{
CancelNotification(notificationManager, 30000);
}
break;
}
if(e.PackageName == BitwardenPackage)
{
CancelNotification(notificationManager);
break;
}
if(_appSettings.AutofillPersistNotification)
{
var uri = GetUri(root);
if(uri != null && !uri.Contains(BitwardenWebsite))
{
var needToFill = NeedToAutofill(AutofillActivity.LastCredentials, uri);
if(needToFill)
{
var passwordNodes = GetWindowNodes(root, e, n => n.Password, false);
needToFill = passwordNodes.Any();
if(needToFill)
{
var allEditTexts = GetWindowNodes(root, e, n => EditText(n), false);
var usernameEditText = allEditTexts.TakeWhile(n => !n.Password).LastOrDefault();
FillCredentials(usernameEditText, passwordNodes);
allEditTexts.Dispose();
usernameEditText.Dispose();
}
passwordNodes.Dispose();
}
if(!needToFill)
{
NotifyToAutofill(uri, notificationManager);
cancelNotification = false;
}
}
AutofillActivity.LastCredentials = null;
}
else
{
cancelNotification = ScanAndAutofill(root, e, notificationManager, cancelNotification);
}
if(cancelNotification)
{
CancelNotification(notificationManager);
}
break;
default:
break;
}
notificationManager?.Dispose();
root.Dispose();
e.Dispose();
}
// Suppress exceptions so that service doesn't crash
catch { }
}
public override void OnInterrupt()
{
}
public bool ScanAndAutofill(AccessibilityNodeInfo root, AccessibilityEvent e,
NotificationManager notificationManager, bool cancelNotification)
{
var passwordNodes = GetWindowNodes(root, e, n => n.Password, false);
if(passwordNodes.Count > 0)
{
var uri = GetUri(root);
if(uri != null && !uri.Contains(BitwardenWebsite))
{
if(NeedToAutofill(AutofillActivity.LastCredentials, uri))
{
var allEditTexts = GetWindowNodes(root, e, n => EditText(n), false);
var usernameEditText = allEditTexts.TakeWhile(n => !n.Password).LastOrDefault();
FillCredentials(usernameEditText, passwordNodes);
allEditTexts.Dispose();
usernameEditText.Dispose();
}
else
{
NotifyToAutofill(uri, notificationManager);
cancelNotification = false;
}
}
AutofillActivity.LastCredentials = null;
}
else if(AutofillActivity.LastCredentials != null)
{
System.Threading.Tasks.Task.Run(async () =>
{
await System.Threading.Tasks.Task.Delay(1000);
AutofillActivity.LastCredentials = null;
});
}
passwordNodes.Dispose();
return cancelNotification;
}
public void CancelNotification(NotificationManager notificationManager, long limit = 250)
{
if(Java.Lang.JavaSystem.CurrentTimeMillis() - _lastNotificationTime < limit)
{
return;
}
_lastNotificationUri = null;
notificationManager?.Cancel(AutoFillNotificationId);
}
private string GetUri(AccessibilityNodeInfo root)
{
var uri = string.Concat(App.Constants.AndroidAppProtocol, root.PackageName);
if(SupportedBrowsers.ContainsKey(root.PackageName))
{
var addressNode = root.FindAccessibilityNodeInfosByViewId(
$"{root.PackageName}:id/{SupportedBrowsers[root.PackageName].UriViewId}").FirstOrDefault();
if(addressNode != null)
{
uri = ExtractUri(uri, addressNode, SupportedBrowsers[root.PackageName]);
addressNode.Dispose();
}
}
return uri;
}
private string ExtractUri(string uri, AccessibilityNodeInfo addressNode, Browser browser)
{
if(addressNode?.Text != null)
{
uri = browser.GetUriFunction(addressNode.Text).Trim();
if(uri != null && uri.Contains("."))
{
if(!uri.Contains("://") && !uri.Contains(" "))
{
uri = string.Concat("http://", uri);
}
else if(Build.VERSION.SdkInt <= BuildVersionCodes.KitkatWatch)
{
var parts = uri.Split(new string[] { ". " }, StringSplitOptions.None);
if(parts.Length > 1)
{
var urlPart = parts.FirstOrDefault(p => p.StartsWith("http"));
if(urlPart != null)
{
uri = urlPart.Trim();
}
}
}
}
}
return uri;
}
/// <summary>
/// Check to make sure it is ok to autofill still on the current screen
/// </summary>
private bool NeedToAutofill(AutofillCredentials creds, string currentUriString)
{
if(creds == null)
{
return false;
}
Uri lastUri, currentUri;
if(Uri.TryCreate(creds.LastUri, UriKind.Absolute, out lastUri) &&
Uri.TryCreate(currentUriString, UriKind.Absolute, out currentUri) &&
lastUri.Host == currentUri.Host)
{
return true;
}
return false;
}
private static bool EditText(AccessibilityNodeInfo n)
{
return n?.ClassName?.Contains("EditText") ?? false;
}
private void NotifyToAutofill(string uri, NotificationManager notificationManager)
{
if(notificationManager == null || string.IsNullOrWhiteSpace(uri))
{
return;
}
var now = Java.Lang.JavaSystem.CurrentTimeMillis();
var intent = new Intent(this, typeof(AutofillActivity));
intent.PutExtra("uri", uri);
intent.SetFlags(ActivityFlags.NewTask | ActivityFlags.SingleTop | ActivityFlags.ClearTop);
var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.UpdateCurrent);
var notificationContent = Build.VERSION.SdkInt > BuildVersionCodes.KitkatWatch ?
AppResources.BitwardenAutofillServiceNotificationContent :
AppResources.BitwardenAutofillServiceNotificationContentOld;
var builder = new Notification.Builder(this);
builder.SetSmallIcon(Resource.Drawable.notification_sm)
.SetContentTitle(AppResources.BitwardenAutofillService)
.SetContentText(notificationContent)
.SetTicker(notificationContent)
.SetWhen(now)
.SetContentIntent(pendingIntent);
if(Build.VERSION.SdkInt > BuildVersionCodes.KitkatWatch)
{
builder.SetVisibility(NotificationVisibility.Secret)
.SetColor(global::Android.Support.V4.Content.ContextCompat.GetColor(ApplicationContext,
Resource.Color.primary));
}
if(Build.VERSION.SdkInt >= BuildVersionCodes.O)
{
if(_notificationChannel == null)
{
_notificationChannel = new NotificationChannel("bitwarden_autofill_service",
AppResources.AutofillService, NotificationImportance.Low);
notificationManager.CreateNotificationChannel(_notificationChannel);
}
builder.SetChannelId(_notificationChannel.Id);
}
if(/*Build.VERSION.SdkInt <= BuildVersionCodes.N && */_appSettings.AutofillPersistNotification)
{
builder.SetPriority(-2);
}
_lastNotificationTime = now;
_lastNotificationUri = uri;
notificationManager.Notify(AutoFillNotificationId, builder.Build());
builder.Dispose();
}
private void FillCredentials(AccessibilityNodeInfo usernameNode, IEnumerable<AccessibilityNodeInfo> passwordNodes)
{
FillEditText(usernameNode, AutofillActivity.LastCredentials?.Username);
foreach(var n in passwordNodes)
{
FillEditText(n, AutofillActivity.LastCredentials?.Password);
}
}
private static void FillEditText(AccessibilityNodeInfo editTextNode, string value)
{
if(editTextNode == null || value == null)
{
return;
}
var bundle = new Bundle();
bundle.PutString(AccessibilityNodeInfo.ActionArgumentSetTextCharsequence, value);
editTextNode.PerformAction(global::Android.Views.Accessibility.Action.SetText, bundle);
}
private NodeList GetWindowNodes(AccessibilityNodeInfo n, AccessibilityEvent e,
Func<AccessibilityNodeInfo, bool> condition, bool disposeIfUnused, NodeList nodes = null,
int recursionDepth = 0)
{
if(nodes == null)
{
nodes = new NodeList();
}
var dispose = disposeIfUnused;
if(n != null && recursionDepth < 50)
{
if(n.WindowId == e.WindowId && !(n.ViewIdResourceName?.StartsWith(SystemUiPackage) ?? false) && condition(n))
{
dispose = false;
nodes.Add(n);
}
for(var i = 0; i < n.ChildCount; i++)
{
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)
{
PackageName = packageName;
UriViewId = uriViewId;
}
public Browser(string packageName, string uriViewId, Func<string, string> getUriFunction)
: this(packageName, uriViewId)
{
GetUriFunction = getUriFunction;
}
public string PackageName { get; set; }
public string UriViewId { get; set; }
public Func<string, string> GetUriFunction { get; set; } = (s) => s;
}
public class NodeList : List<AccessibilityNodeInfo>, IDisposable
{
public void Dispose()
{
foreach(var item in this)
{
item.Dispose();
}
}
}
}
}

7
src/Android/Constants.cs Normal file
View File

@@ -0,0 +1,7 @@
namespace Bit.Droid
{
public static class Constants
{
public const string PACKAGE_NAME = "com.x8bit.bitwarden";
}
}

View File

@@ -1,35 +0,0 @@
using System;
using System.ComponentModel;
using Android.Content;
using Bit.Android.Controls;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(Button), typeof(CustomButtonRenderer))]
namespace Bit.Android.Controls
{
public class CustomButtonRenderer : ButtonRenderer
{
public CustomButtonRenderer(Context context)
: base(context)
{ }
protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
{
base.OnElementChanged(e);
if(Control.TextSize == (float)Device.GetNamedSize(NamedSize.Default, typeof(Button)))
{
Control.TextSize = (float)Device.GetNamedSize(NamedSize.Medium, typeof(Button));
}
// This will prevent all screen overlay apps from being able to interact with buttons.
// Ex: apps that change the screen color for "night mode"
// Control.FilterTouchesWhenObscured = true;
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
}
}
}

View File

@@ -1,21 +0,0 @@
using Android.Content;
using Bit.Android.Controls;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(Label), typeof(CustomLabelRenderer))]
namespace Bit.Android.Controls
{
public class CustomLabelRenderer : LabelRenderer
{
public CustomLabelRenderer(Context context)
: base(context)
{ }
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
Control.SetMaxLines(int.MaxValue);
}
}
}

View File

@@ -1,23 +0,0 @@
using System;
using System.ComponentModel;
using Android.Content;
using Bit.Android.Controls;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(SearchBar), typeof(CustomSearchBarRenderer))]
namespace Bit.Android.Controls
{
public class CustomSearchBarRenderer : SearchBarRenderer
{
public CustomSearchBarRenderer(Context context)
: base(context)
{ }
protected override void OnElementChanged(ElementChangedEventArgs<SearchBar> e)
{
base.OnElementChanged(e);
Control.SetPadding((int)global::Android.App.Application.Context.ToPixels(-8), 0, 0, 0);
}
}
}

View File

@@ -1,27 +0,0 @@
using System;
using Bit.Android.Controls;
using Xamarin.Forms;
using Android.Content;
using Xamarin.Forms.Platform.Android;
using Android.Support.V4.Content.Res;
[assembly: ExportRenderer(typeof(Slider), typeof(CustomSliderRenderer))]
namespace Bit.Android.Controls
{
public class CustomSliderRenderer : SliderRenderer
{
public CustomSliderRenderer(Context context)
: base(context)
{ }
protected override void OnElementChanged(ElementChangedEventArgs<Slider> e)
{
base.OnElementChanged(e);
if(Control != null)
{
var thumb = ResourcesCompat.GetDrawable(Resources, Resource.Drawable.slider_thumb, null);
Control.SetThumb(thumb);
}
}
}
}

View File

@@ -1,67 +0,0 @@
using System;
using System.ComponentModel;
using Android.Content;
using Bit.Android.Controls;
using Bit.App.Controls;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(ExtendedButton), typeof(ExtendedButtonRenderer))]
namespace Bit.Android.Controls
{
public class ExtendedButtonRenderer : CustomButtonRenderer
{
public ExtendedButtonRenderer(Context context)
: base(context)
{ }
protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
{
base.OnElementChanged(e);
SetPadding();
SetUppercase();
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if(e.PropertyName == ExtendedButton.PaddingProperty.PropertyName)
{
SetPadding();
}
else if(e.PropertyName == ExtendedButton.UppercaseProperty.PropertyName)
{
SetUppercase();
}
}
private void SetPadding()
{
var element = Element as ExtendedButton;
if(element != null)
{
Control.SetPadding(
(int)element.Padding.Left,
(int)element.Padding.Top,
(int)element.Padding.Right,
(int)element.Padding.Bottom);
}
}
private void SetUppercase()
{
var element = Element as ExtendedButton;
if(element != null && !string.IsNullOrWhiteSpace(element.Text))
{
if(element.Uppercase)
{
element.Text = element.Text.ToUpperInvariant();
}
else
{
Control.TransformationMethod = null;
}
}
}
}
}

View File

@@ -1,86 +0,0 @@
using System;
using System.ComponentModel;
using Bit.Android.Controls;
using Bit.App.Controls;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using Android.Text.Method;
using Android.Views;
using Android.Content;
[assembly: ExportRenderer(typeof(ExtendedEditor), typeof(ExtendedEditorRenderer))]
namespace Bit.Android.Controls
{
public class ExtendedEditorRenderer : EditorRenderer
{
public ExtendedEditorRenderer(Context context)
: base(context)
{ }
protected override void OnElementChanged(ElementChangedEventArgs<Editor> e)
{
base.OnElementChanged(e);
var view = (ExtendedEditor)Element;
SetBorder(view);
SetScrollable();
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
var view = (ExtendedEditor)Element;
if(e.PropertyName == ExtendedEditor.HasBorderProperty.PropertyName)
{
SetBorder(view);
}
else
{
base.OnElementPropertyChanged(sender, e);
if(e.PropertyName == VisualElement.BackgroundColorProperty.PropertyName)
{
Control.SetBackgroundColor(view.BackgroundColor.ToAndroid());
}
}
}
private void SetBorder(ExtendedEditor view)
{
if(!view.HasBorder)
{
Control.SetBackgroundColor(global::Android.Graphics.Color.Transparent);
}
}
private void SetScrollable()
{
// While scrolling inside Editor stop scrolling parent view.
Control.OverScrollMode = OverScrollMode.Always;
Control.ScrollBarStyle = ScrollbarStyles.InsideInset;
Control.SetOnTouchListener(new EditorTouchListener());
// For Scrolling in Editor innner area
Control.VerticalScrollBarEnabled = true;
Control.ScrollBarStyle = ScrollbarStyles.InsideInset;
// Force scrollbars to be displayed
var arr = Control.Context.Theme.ObtainStyledAttributes(new int[0]);
InitializeScrollbars(arr);
arr.Recycle();
}
public class EditorTouchListener : Java.Lang.Object, IOnTouchListener
{
public bool OnTouch(global::Android.Views.View v, MotionEvent e)
{
v.Parent?.RequestDisallowInterceptTouchEvent(true);
if((e.Action & MotionEventActions.Up) != 0 && (e.ActionMasked & MotionEventActions.Up) != 0)
{
v.Parent?.RequestDisallowInterceptTouchEvent(false);
}
return false;
}
}
}
}

View File

@@ -1,212 +0,0 @@
using System;
using System.ComponentModel;
using Android.Content;
using Android.Graphics;
using Android.Text;
using Android.Text.Method;
using Android.Views.InputMethods;
using Android.Widget;
using Bit.Android.Controls;
using Bit.App.Controls;
using Bit.App.Enums;
using Plugin.CurrentActivity;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(ExtendedEntry), typeof(ExtendedEntryRenderer))]
namespace Bit.Android.Controls
{
public class ExtendedEntryRenderer : EntryRenderer
{
public ExtendedEntryRenderer(Context context)
: base(context)
{ }
private bool _isPassword;
private bool _toggledPassword;
private bool _isDisposed;
private ExtendedEntry _view;
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
_view = (ExtendedEntry)Element;
_isPassword = _view.IsPassword;
if(Control != null)
{
Control.SetIncludeFontPadding(false);
if(e.NewElement != null && e.NewElement.IsPassword)
{
Control.SetTypeface(Typeface.Default, TypefaceStyle.Normal);
Control.TransformationMethod = new PasswordTransformationMethod();
}
}
SetBorder(_view);
SetMaxLength(_view);
SetReturnType(_view);
// Editor Action is called when the return button is pressed
Control.EditorAction += Control_EditorAction;
if(_view.DisableAutocapitalize)
{
Control.SetRawInputType(Control.InputType |= InputTypes.TextVariationEmailAddress);
}
if(_view.Autocorrect.HasValue)
{
Control.SetRawInputType(Control.InputType |= InputTypes.TextFlagNoSuggestions);
}
if(_view.IsPassword)
{
Control.SetRawInputType(InputTypes.TextFlagNoSuggestions | InputTypes.TextVariationVisiblePassword);
}
_view.ToggleIsPassword += ToggleIsPassword;
if(_view.FontFamily == "monospace")
{
Control.Typeface = Typeface.Monospace;
}
if(_view.HideCursor)
{
Control.SetCursorVisible(false);
}
}
private void ToggleIsPassword(object sender, EventArgs e)
{
var cursorStart = Control.SelectionStart;
var cursorEnd = Control.SelectionEnd;
Control.TransformationMethod = _isPassword ? null : new PasswordTransformationMethod();
Control.SetRawInputType(InputTypes.TextFlagNoSuggestions | InputTypes.TextVariationVisiblePassword);
// set focus
Control.RequestFocus();
if(_toggledPassword)
{
// restore cursor position
Control.SetSelection(cursorStart, cursorEnd);
}
else
{
// set cursor to end
Control.SetSelection(Control.Text.Length);
}
// show keyboard
var imm = CrossCurrentActivity.Current.Activity.GetSystemService(Context.InputMethodService) as InputMethodManager;
imm.ShowSoftInput(Control, ShowFlags.Forced);
imm.ToggleSoftInput(ShowFlags.Forced, HideSoftInputFlags.ImplicitOnly);
_isPassword = _view.IsPasswordFromToggled = !_isPassword;
_toggledPassword = true;
}
private void Control_EditorAction(object sender, TextView.EditorActionEventArgs e)
{
if(_view.ReturnType != ReturnType.Next)
{
_view.Unfocus();
}
// Call all the methods attached to base_entry event handler Completed
_view.InvokeCompleted();
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
var view = (ExtendedEntry)Element;
if(e.PropertyName == ExtendedEntry.HasBorderProperty.PropertyName
|| e.PropertyName == ExtendedEntry.HasOnlyBottomBorderProperty.PropertyName
|| e.PropertyName == ExtendedEntry.BottomBorderColorProperty.PropertyName)
{
SetBorder(view);
}
else
{
base.OnElementPropertyChanged(sender, e);
if(e.PropertyName == VisualElement.BackgroundColorProperty.PropertyName)
{
Control.SetBackgroundColor(view.BackgroundColor.ToAndroid());
}
}
if(view.FontFamily == "monospace")
{
Control.Typeface = Typeface.Monospace;
}
}
protected override void Dispose(bool disposing)
{
if(_isDisposed)
{
return;
}
_isDisposed = true;
if(disposing && Control != null)
{
_view.ToggleIsPassword -= ToggleIsPassword;
Control.EditorAction -= Control_EditorAction;
}
base.Dispose(disposing);
}
private void SetReturnType(ExtendedEntry view)
{
if(view.ReturnType.HasValue)
{
switch(view.ReturnType.Value)
{
case ReturnType.Go:
Control.ImeOptions = ImeAction.Go;
Control.SetImeActionLabel("Go", ImeAction.Go);
break;
case ReturnType.Next:
Control.ImeOptions = ImeAction.Next;
Control.SetImeActionLabel("Next", ImeAction.Next);
break;
case ReturnType.Search:
Control.ImeOptions = ImeAction.Search;
Control.SetImeActionLabel("Search", ImeAction.Search);
break;
case ReturnType.Send:
Control.ImeOptions = ImeAction.Send;
Control.SetImeActionLabel("Send", ImeAction.Send);
break;
default:
Control.SetImeActionLabel("Done", ImeAction.Done);
break;
}
}
}
private void SetBorder(ExtendedEntry view)
{
if(!view.HasBorder)
{
Control.SetBackgroundColor(global::Android.Graphics.Color.Transparent);
}
else
{
Control.SetBackgroundColor(view.BottomBorderColor.ToAndroid());
}
}
private void SetMaxLength(ExtendedEntry view)
{
Control.SetFilters(new IInputFilter[] { new InputFilterLengthFilter(view.MaxLength) });
}
}
}

View File

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

View File

@@ -1,54 +0,0 @@
using System;
using System.ComponentModel;
using Android.Content;
using Bit.Android.Controls;
using Bit.App.Controls;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(ExtendedPicker), typeof(ExtendedPickerRenderer))]
namespace Bit.Android.Controls
{
public class ExtendedPickerRenderer : PickerRenderer
{
public ExtendedPickerRenderer(Context context)
: base(context)
{ }
protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
{
base.OnElementChanged(e);
var view = (ExtendedPicker)Element;
Control.TextSize = (float)Device.GetNamedSize(NamedSize.Medium, typeof(Picker));
SetBorder(view);
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
var view = (ExtendedPicker)Element;
if(e.PropertyName == ExtendedPicker.HasBorderProperty.PropertyName)
{
SetBorder(view);
}
else
{
base.OnElementPropertyChanged(sender, e);
if(e.PropertyName == VisualElement.BackgroundColorProperty.PropertyName)
{
Control.SetBackgroundColor(view.BackgroundColor.ToAndroid());
}
}
}
private void SetBorder(ExtendedPicker view)
{
if(!view.HasBorder)
{
Control.SetBackgroundColor(global::Android.Graphics.Color.Transparent);
}
}
}
}

View File

@@ -1,72 +0,0 @@
using Android.Content;
using System.ComponentModel;
using Android.Views;
using Bit.Android.Controls;
using Bit.App.Controls;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using AView = Android.Views.View;
using Android.Widget;
[assembly: ExportRenderer(typeof(ExtendedSwitchCell), typeof(ExtendedSwitchCellRenderer))]
namespace Bit.Android.Controls
{
public class ExtendedSwitchCellRenderer : SwitchCellRenderer
{
protected BaseCellView View { get; private set; }
protected override AView GetCellCore(Cell item, AView convertView, ViewGroup parent, Context context)
{
var View = base.GetCellCore(item, convertView, parent, context) as SwitchCellView;
var extendedCell = (ExtendedSwitchCell)item;
if(View != null)
{
if(extendedCell.BackgroundColor != Color.White)
{
View.SetBackgroundColor(extendedCell.BackgroundColor.ToAndroid());
}
else
{
View.SetBackgroundResource(Resource.Drawable.list_selector);
}
if(item.IsEnabled)
{
View.SetMainTextColor(Color.Black);
}
else
{
View.SetMainTextColor(Color.FromHex("777777"));
}
if(View.ChildCount > 1)
{
var layout = View.GetChildAt(1) as LinearLayout;
if(layout != null && layout.ChildCount > 0)
{
var textView = layout.GetChildAt(0) as TextView;
if(textView != null)
{
textView.TextSize = (float)Device.GetNamedSize(NamedSize.Medium, typeof(Label));
}
}
}
}
return View;
}
protected override void OnCellPropertyChanged(object sender, PropertyChangedEventArgs args)
{
base.OnCellPropertyChanged(sender, args);
var cell = (ExtendedSwitchCell)Cell;
if(args.PropertyName == ExtendedSwitchCell.BackgroundColorProperty.PropertyName)
{
View.SetBackgroundColor(cell.BackgroundColor.ToAndroid());
}
}
}
}

View File

@@ -1,441 +0,0 @@
using System;
using Bit.Android.Controls;
using Bit.App.Controls;
using Xamarin.Forms;
using Com.Ittianyu.Bottomnavigationviewex;
using Xamarin.Forms.Platform.Android;
using RelativeLayout = Android.Widget.RelativeLayout;
using Platform = Xamarin.Forms.Platform.Android.Platform;
using Android.Content;
using Android.Views;
using Android.Widget;
using Android.Support.Design.Internal;
using System.IO;
using System.Linq;
using System.ComponentModel;
using Android.Support.Design.Widget;
[assembly: ExportRenderer(typeof(ExtendedTabbedPage), typeof(ExtendedTabbedPageRenderer))]
namespace Bit.Android.Controls
{
public class ExtendedTabbedPageRenderer : VisualElementRenderer<ExtendedTabbedPage>,
BottomNavigationView.IOnNavigationItemSelectedListener
{
public static bool ShouldUpdateSelectedIcon;
public static Action<IMenuItem, FileImageSource, bool> MenuItemIconSetter;
public static float? BottomBarHeight = 50;
private RelativeLayout _rootLayout;
private FrameLayout _pageContainer;
private BottomNavigationViewEx _bottomNav;
private readonly int _barId;
public static global::Android.Graphics.Color? BackgroundColor;
public ExtendedTabbedPageRenderer(Context context)
: base(context)
{
AutoPackage = false;
_barId = GenerateViewId();
}
IPageController TabbedController => Element as IPageController;
public int LastSelectedIndex { get; internal set; }
public bool OnNavigationItemSelected(IMenuItem item)
{
this.SwitchPage(item);
return true;
}
internal void SetupTabItems()
{
this.SetupTabItems(_bottomNav);
}
internal void SetupBottomBar()
{
_bottomNav = this.SetupBottomBar(_rootLayout, _bottomNav, _barId);
}
public static readonly Action<IMenuItem, FileImageSource, bool> DefaultMenuItemIconSetter = (menuItem, icon, selected) =>
{
var tabIconId = ResourceUtils.IdFromTitle(icon, ResourceManager.DrawableClass);
menuItem.SetIcon(tabIconId);
};
protected override void OnElementChanged(ElementChangedEventArgs<ExtendedTabbedPage> e)
{
base.OnElementChanged(e);
if(e.OldElement != null)
{
e.OldElement.ChildAdded -= PagesChanged;
e.OldElement.ChildRemoved -= PagesChanged;
e.OldElement.ChildrenReordered -= PagesChanged;
}
if(e.NewElement == null)
{
return;
}
UpdateIgnoreContainerAreas();
if(_rootLayout == null)
{
SetupNativeView();
}
this.HandlePagesChanged();
SwitchContent(Element.CurrentPage);
Element.ChildAdded += PagesChanged;
Element.ChildRemoved += PagesChanged;
Element.ChildrenReordered += PagesChanged;
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if(e.PropertyName == nameof(TabbedPage.CurrentPage))
{
SwitchContent(Element.CurrentPage);
}
}
void PagesChanged(object sender, EventArgs e)
{
this.HandlePagesChanged();
}
protected override void OnAttachedToWindow()
{
base.OnAttachedToWindow();
TabbedController?.SendAppearing();
}
protected override void OnDetachedFromWindow()
{
base.OnDetachedFromWindow();
TabbedController?.SendDisappearing();
}
protected override void OnLayout(bool changed, int left, int top, int right, int bottom)
{
var width = right - left;
var height = bottom - top;
base.OnLayout(changed, left, top, right, bottom);
if(width <= 0 || height <= 0)
{
return;
}
this.Layout(width, height);
}
protected override void Dispose(bool disposing)
{
if(disposing)
{
Element.ChildAdded -= PagesChanged;
Element.ChildRemoved -= PagesChanged;
Element.ChildrenReordered -= PagesChanged;
if(_rootLayout != null)
{
RemoveAllViews();
foreach(Page pageToRemove in Element.Children)
{
var pageRenderer = Platform.GetRenderer(pageToRemove);
if(pageRenderer != null)
{
pageRenderer.View.RemoveFromParent();
pageRenderer.Dispose();
}
}
if(_bottomNav != null)
{
_bottomNav.SetOnNavigationItemSelectedListener(null);
_bottomNav.Dispose();
_bottomNav = null;
}
_rootLayout.Dispose();
_rootLayout = null;
}
}
base.Dispose(disposing);
}
internal void SetupNativeView()
{
_rootLayout = this.CreateRoot(_barId, GenerateViewId(), out _pageContainer);
AddView(_rootLayout);
}
void SwitchContent(Page page)
{
this.ChangePage(_pageContainer, page);
}
void UpdateIgnoreContainerAreas()
{
foreach(var child in Element.Children)
{
child.IgnoresContainerArea = false;
}
}
}
internal static class TabExtensions
{
public static Rectangle CreateRect(this Context context, int width, int height)
{
return new Rectangle(0, 0, context.FromPixels(width), context.FromPixels(height));
}
public static void HandlePagesChanged(this ExtendedTabbedPageRenderer renderer)
{
renderer.SetupBottomBar();
renderer.SetupTabItems();
if(renderer.Element.Children.Count == 0)
{
return;
}
EnsureTabIndex(renderer);
}
static void EnsureTabIndex(ExtendedTabbedPageRenderer renderer)
{
var rootLayout = (RelativeLayout)renderer.GetChildAt(0);
var bottomNav = (BottomNavigationViewEx)rootLayout.GetChildAt(1);
var menu = (BottomNavigationMenu)bottomNav.Menu;
var itemIndex = menu.FindItemIndex(bottomNav.SelectedItemId);
var pageIndex = renderer.Element.Children.IndexOf(renderer.Element.CurrentPage);
if(pageIndex >= 0 && pageIndex != itemIndex && pageIndex < bottomNav.ItemCount)
{
var menuItem = menu.GetItem(pageIndex);
bottomNav.SelectedItemId = menuItem.ItemId;
if(ExtendedTabbedPageRenderer.ShouldUpdateSelectedIcon && ExtendedTabbedPageRenderer.MenuItemIconSetter != null)
{
ExtendedTabbedPageRenderer.MenuItemIconSetter?.Invoke(menuItem, renderer.Element.CurrentPage.Icon, true);
if(renderer.LastSelectedIndex != pageIndex)
{
var lastSelectedPage = renderer.Element.Children[renderer.LastSelectedIndex];
var lastSelectedMenuItem = menu.GetItem(renderer.LastSelectedIndex);
ExtendedTabbedPageRenderer.MenuItemIconSetter?.Invoke(lastSelectedMenuItem, lastSelectedPage.Icon, false);
renderer.LastSelectedIndex = pageIndex;
}
}
}
}
public static void SwitchPage(this ExtendedTabbedPageRenderer renderer, IMenuItem item)
{
var rootLayout = (RelativeLayout)renderer.GetChildAt(0);
var bottomNav = (BottomNavigationViewEx)rootLayout.GetChildAt(1);
var menu = (BottomNavigationMenu)bottomNav.Menu;
var index = menu.FindItemIndex(item.ItemId);
var pageIndex = index % renderer.Element.Children.Count;
var currentPageIndex = renderer.Element.Children.IndexOf(renderer.Element.CurrentPage);
if(currentPageIndex != pageIndex)
{
renderer.Element.CurrentPage = renderer.Element.Children[pageIndex];
}
}
public static void Layout(this ExtendedTabbedPageRenderer renderer, int width, int height)
{
var rootLayout = (RelativeLayout)renderer.GetChildAt(0);
var bottomNav = (BottomNavigationViewEx)rootLayout.GetChildAt(1);
var Context = renderer.Context;
rootLayout.Measure(MakeMeasureSpec(width, MeasureSpecMode.Exactly),
MakeMeasureSpec(height, MeasureSpecMode.AtMost));
((IPageController)renderer.Element).ContainerArea =
Context.CreateRect(rootLayout.MeasuredWidth, rootLayout.GetChildAt(0).MeasuredHeight);
rootLayout.Measure(MakeMeasureSpec(width, MeasureSpecMode.Exactly),
MakeMeasureSpec(height, MeasureSpecMode.Exactly));
rootLayout.Layout(0, 0, rootLayout.MeasuredWidth, rootLayout.MeasuredHeight);
if(renderer.Element.Children.Count == 0)
{
return;
}
int tabsHeight = bottomNav.MeasuredHeight;
var item = (ViewGroup)bottomNav.GetChildAt(0);
item.Measure(MakeMeasureSpec(width, MeasureSpecMode.Exactly),
MakeMeasureSpec(tabsHeight, MeasureSpecMode.Exactly));
item.Layout(0, 0, width, tabsHeight);
int item_w = width / item.ChildCount;
for(int i = 0; i < item.ChildCount; i++)
{
var frame = (FrameLayout)item.GetChildAt(i);
frame.Measure(MakeMeasureSpec(item_w, MeasureSpecMode.Exactly),
MakeMeasureSpec(tabsHeight, MeasureSpecMode.Exactly));
frame.Layout(i * item_w, 0, i * item_w + item_w, tabsHeight);
}
}
public static void SetupTabItems(this ExtendedTabbedPageRenderer renderer, BottomNavigationViewEx bottomNav)
{
var element = renderer.Element;
var menu = (BottomNavigationMenu)bottomNav.Menu;
menu.ClearAll();
var tabsCount = Math.Min(element.Children.Count, bottomNav.MaxItemCount);
for(int i = 0; i < tabsCount; i++)
{
var page = element.Children[i];
var menuItem = menu.Add(0, i, 0, page.Title);
var setter = ExtendedTabbedPageRenderer.MenuItemIconSetter ?? ExtendedTabbedPageRenderer.DefaultMenuItemIconSetter;
setter.Invoke(menuItem, page.Icon, renderer.LastSelectedIndex == i);
}
if(element.Children.Count > 0)
{
bottomNav.EnableShiftingMode(false);
bottomNav.EnableItemShiftingMode(false);
bottomNav.EnableAnimation(false);
bottomNav.SetTextVisibility(false);
bottomNav.SetBackgroundResource(Resource.Drawable.bottom_nav_bg);
bottomNav.SetIconSize(24, 24);
bottomNav.SetIconsMarginTop(32);
if(element.Children.Count > 3)
{
bottomNav.SetIconSizeAt(3, 29, 29);
bottomNav.SetIconMarginTop(3, 28);
}
var stateList = new global::Android.Content.Res.ColorStateList(
new int[][] {
new int[] { global::Android.Resource.Attribute.StateChecked },
new int[] { global::Android.Resource.Attribute.StateEnabled}
},
new int[] {
element.TintColor.ToAndroid(), // Selected
Color.FromHex("A1A1A1").ToAndroid() // Normal
});
bottomNav.ItemIconTintList = stateList;
}
}
public static BottomNavigationViewEx SetupBottomBar(this ExtendedTabbedPageRenderer renderer,
global::Android.Widget.RelativeLayout rootLayout, BottomNavigationViewEx bottomNav, int barId)
{
if(bottomNav != null)
{
rootLayout.RemoveView(bottomNav);
bottomNav.SetOnNavigationItemSelectedListener(null);
}
var barParams = new global::Android.Widget.RelativeLayout.LayoutParams(
ViewGroup.LayoutParams.MatchParent,
ExtendedTabbedPageRenderer.BottomBarHeight.HasValue ?
(int)rootLayout.Context.ToPixels(ExtendedTabbedPageRenderer.BottomBarHeight.Value) :
ViewGroup.LayoutParams.WrapContent);
barParams.AddRule(LayoutRules.AlignParentBottom);
bottomNav = new BottomNavigationViewEx(rootLayout.Context)
{
LayoutParameters = barParams,
Id = barId
};
if(ExtendedTabbedPageRenderer.BackgroundColor.HasValue)
{
bottomNav.SetBackgroundColor(ExtendedTabbedPageRenderer.BackgroundColor.Value);
}
bottomNav.SetOnNavigationItemSelectedListener(renderer);
rootLayout.AddView(bottomNav, 1, barParams);
return bottomNav;
}
public static void ChangePage(this ExtendedTabbedPageRenderer renderer, FrameLayout pageContainer, Page page)
{
renderer.Context.HideKeyboard(renderer);
if(page == null)
{
return;
}
if(Platform.GetRenderer(page) == null)
{
Platform.SetRenderer(page, Platform.CreateRendererWithContext(page, renderer.Context));
}
var pageContent = Platform.GetRenderer(page).View;
pageContainer.AddView(pageContent);
if(pageContainer.ChildCount > 1)
{
pageContainer.RemoveViewAt(0);
}
EnsureTabIndex(renderer);
}
public static RelativeLayout CreateRoot(this ExtendedTabbedPageRenderer renderer, int barId, int pageContainerId, out FrameLayout pageContainer)
{
var rootLayout = new RelativeLayout(renderer.Context)
{
LayoutParameters = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent),
};
var pageParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent);
pageParams.AddRule(LayoutRules.Above, barId);
pageContainer = new FrameLayout(renderer.Context)
{
LayoutParameters = pageParams,
Id = pageContainerId
};
rootLayout.AddView(pageContainer, 0, pageParams);
return rootLayout;
}
private static int MakeMeasureSpec(int size, MeasureSpecMode mode)
{
return size + (int)mode;
}
}
public static class ResourceUtils
{
public static int IdFromTitle(string title, Type type)
{
var name = Path.GetFileNameWithoutExtension(title);
var id = GetId(type, name);
return id;
}
public static int GetId(Type type, string propertyName)
{
var props = type.GetFields();
var prop = props.Select(p => p).FirstOrDefault(p => p.Name == propertyName);
if(prop != null)
{
return (int)prop.GetValue(type);
}
return 0;
}
}
}

View File

@@ -1,179 +0,0 @@
using System;
using Android.Widget;
using Bit.Android.Controls;
using Bit.App.Controls;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using Android.Content;
using AView = Android.Views.View;
using AListView = Android.Widget.ListView;
using Android.Views;
[assembly: ExportRenderer(typeof(ExtendedTableView), typeof(ExtendedTableViewRenderer))]
namespace Bit.Android.Controls
{
public class ExtendedTableViewRenderer : TableViewRenderer
{
public ExtendedTableViewRenderer(Context context)
: base(context)
{ }
protected override void OnElementChanged(ElementChangedEventArgs<TableView> e)
{
base.OnElementChanged(e);
Control.Divider = null;
Control.DividerHeight = 0;
if(e.NewElement is ExtendedTableView tableView)
{
if(tableView.BottomPadding > 0)
{
Control.SetPadding(0, 0, 0, tableView.BottomPadding);
Control.SetClipToPadding(false);
Control.ScrollBarStyle = ScrollbarStyles.OutsideOverlay;
}
}
}
protected override TableViewModelRenderer GetModelRenderer(AListView listView, TableView view)
{
return new CustomTableViewModelRenderer(Context, listView, view);
}
public override SizeRequest GetDesiredSize(int widthConstraint, int heightConstraint)
{
var baseSize = base.GetDesiredSize(widthConstraint, heightConstraint);
var height = ComputeHeight(Control, Convert.ToInt32(baseSize.Request.Width));
return new SizeRequest(new Size(baseSize.Request.Width, height));
}
private int ComputeHeight(AListView listView, int width)
{
var element = Element as ExtendedTableView;
var adapter = listView.Adapter;
var totalHeight = listView.PaddingTop + listView.PaddingBottom;
var desiredWidth = MeasureSpec.MakeMeasureSpec(width, MeasureSpecMode.AtMost);
for(var i = 0; i < adapter.Count; i++)
{
if(i == 0 && (element?.NoHeader ?? false))
{
totalHeight += 1;
continue;
}
var view = adapter.GetView(i, null, listView);
view.LayoutParameters = new LayoutParams(LayoutParams.WrapContent, LayoutParams.WrapContent);
view.Measure(desiredWidth, MeasureSpec.MakeMeasureSpec(0, MeasureSpecMode.Unspecified));
totalHeight += view.MeasuredHeight;
}
return totalHeight + (listView.DividerHeight * (adapter.Count - 1));
}
private class CustomTableViewModelRenderer : TableViewModelRenderer
{
private readonly ExtendedTableView _view;
private readonly AListView _listView;
public CustomTableViewModelRenderer(Context context, AListView listView, TableView view)
: base(context, listView, view)
{
_view = view as ExtendedTableView;
_listView = listView;
}
private ITableViewController Controller => _view;
// ref http://bit.ly/2b9cjnQ
public override AView GetView(int position, AView convertView, ViewGroup parent)
{
var baseView = base.GetView(position, convertView, parent);
var layout = baseView as LinearLayout;
if(layout == null)
{
return baseView;
}
bool isHeader, nextIsHeader;
var cell = GetCellForPosition(position, out isHeader, out nextIsHeader);
if(layout.ChildCount > 0)
{
layout.RemoveViewAt(0);
var cellView = CellFactory.GetCell(cell, convertView, parent, Context, _view);
layout.AddView(cellView, 0);
}
if(isHeader)
{
var textCell = layout.GetChildAt(0) as BaseCellView;
if(textCell != null)
{
if(position == 0 && _view.NoHeader)
{
textCell.Visibility = ViewStates.Gone;
}
else
{
textCell.MainText = textCell.MainText?.ToUpperInvariant();
textCell.SetMainTextColor(Color.FromHex("777777"));
}
}
}
var bline = layout.GetChildAt(1);
if(bline != null)
{
bline.SetBackgroundColor(_view.SeparatorColor.ToAndroid());
}
return layout;
}
// Copy/pasted from Xamarin source. Invoke via reflection instead maybe?
private Cell GetCellForPosition(int position, out bool isHeader, out bool nextIsHeader)
{
isHeader = false;
nextIsHeader = false;
var model = Controller.Model;
var sectionCount = model.GetSectionCount();
for(var sectionIndex = 0; sectionIndex < sectionCount; sectionIndex++)
{
var size = model.GetRowCount(sectionIndex) + 1;
if(position == 0)
{
isHeader = true;
nextIsHeader = size == 0 && sectionIndex < sectionCount - 1;
var header = model.GetHeaderCell(sectionIndex);
Cell resultCell = null;
if(header != null)
{
resultCell = header;
}
if(resultCell == null)
{
resultCell = new TextCell { Text = model.GetSectionTitle(sectionIndex) };
}
resultCell.Parent = _view;
return resultCell;
}
if(position < size)
{
nextIsHeader = position == size - 1;
return (Cell)model.GetItem(sectionIndex, position - 1);
}
position -= size;
}
return null;
}
}
}
}

View File

@@ -1,155 +0,0 @@
using Android.Content;
using System.ComponentModel;
using Android.Views;
using Bit.Android.Controls;
using Bit.App.Controls;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using AView = Android.Views.View;
using Android.Widget;
using Android.Text;
[assembly: ExportRenderer(typeof(ExtendedTextCell), typeof(ExtendedTextCellRenderer))]
namespace Bit.Android.Controls
{
public class ExtendedTextCellRenderer : TextCellRenderer
{
protected AView View { get; private set; }
protected override AView GetCellCore(Cell item, AView convertView, ViewGroup parent, Context context)
{
var View = (BaseCellView)base.GetCellCore(item, convertView, parent, context);
var extendedCell = (ExtendedTextCell)item;
if(View != null)
{
if(extendedCell.BackgroundColor != Color.White)
{
View.SetBackgroundColor(extendedCell.BackgroundColor.ToAndroid());
}
else
{
View.SetBackgroundResource(Resource.Drawable.list_selector);
}
if(extendedCell.ShowDisclousure)
{
var resourceId = Resource.Drawable.ion_chevron_right;
if(!string.IsNullOrWhiteSpace(extendedCell.DisclousureImage))
{
var fileName = System.IO.Path.GetFileNameWithoutExtension(extendedCell.DisclousureImage);
resourceId = context.Resources.GetIdentifier(fileName, "drawable", context.PackageName);
}
var image = new DisclosureImage(context, extendedCell);
image.SetImageResource(resourceId);
image.SetPadding(10, 10, 30, 10);
View.SetAccessoryView(image);
}
if(View.ChildCount > 1)
{
var layout = View.GetChildAt(1) as LinearLayout;
if(layout != null)
{
if(layout.ChildCount > 0)
{
var textView = layout.GetChildAt(0) as TextView;
if(textView != null)
{
textView.TextSize = (float)Device.GetNamedSize(NamedSize.Medium, typeof(Label));
}
}
if(layout.ChildCount > 1)
{
var detailView = layout.GetChildAt(1) as TextView;
if(detailView != null)
{
UpdateLineBreakMode(detailView, extendedCell.DetailLineBreakMode);
}
}
}
}
}
return View;
}
protected override void OnCellPropertyChanged(object sender, PropertyChangedEventArgs args)
{
base.OnCellPropertyChanged(sender, args);
var cell = (ExtendedTextCell)Cell;
if(args.PropertyName == ExtendedTextCell.BackgroundColorProperty.PropertyName)
{
View.SetBackgroundColor(cell.BackgroundColor.ToAndroid());
}
// TODO: other properties
}
private void UpdateLineBreakMode(TextView view, LineBreakMode lineBreakMode)
{
if(view == null)
{
return;
}
switch(lineBreakMode)
{
case LineBreakMode.NoWrap:
view.SetSingleLine(true);
view.Ellipsize = null;
break;
case LineBreakMode.WordWrap:
view.SetSingleLine(false);
view.Ellipsize = null;
view.SetMaxLines(100);
break;
case LineBreakMode.CharacterWrap:
view.SetSingleLine(false);
view.Ellipsize = null;
view.SetMaxLines(100);
break;
case LineBreakMode.HeadTruncation:
view.SetSingleLine(true);
view.Ellipsize = TextUtils.TruncateAt.Start;
break;
case LineBreakMode.TailTruncation:
view.SetSingleLine(true);
view.Ellipsize = TextUtils.TruncateAt.End;
break;
case LineBreakMode.MiddleTruncation:
view.SetSingleLine(true);
view.Ellipsize = TextUtils.TruncateAt.Middle;
break;
}
}
private class DisclosureImage : ImageView
{
private ExtendedTextCell _cell;
public DisclosureImage(Context context, ExtendedTextCell cell) : base(context)
{
_cell = cell;
}
public override bool OnTouchEvent(MotionEvent e)
{
switch(e.Action)
{
case MotionEventActions.Up:
_cell.OnDisclousureTapped();
break;
default:
break;
}
return true;
}
}
}
}

View File

@@ -1,49 +0,0 @@
using Android.Content;
using System.ComponentModel;
using Android.Views;
using Bit.Android.Controls;
using Bit.App.Controls;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using AView = Android.Views.View;
[assembly: ExportRenderer(typeof(ExtendedViewCell), typeof(ExtendedViewCellRenderer))]
namespace Bit.Android.Controls
{
public class ExtendedViewCellRenderer : ViewCellRenderer
{
protected AView View { get; private set; }
protected override AView GetCellCore(Cell item, AView convertView, ViewGroup parent, Context context)
{
var View = base.GetCellCore(item, convertView, parent, context);
var extendedCell = (ExtendedViewCell)item;
if(View != null)
{
if(extendedCell.BackgroundColor != Color.White)
{
View.SetBackgroundColor(extendedCell.BackgroundColor.ToAndroid());
}
else
{
View.SetBackgroundResource(Resource.Drawable.list_selector);
}
}
return View;
}
protected override void OnCellPropertyChanged(object sender, PropertyChangedEventArgs args)
{
base.OnCellPropertyChanged(sender, args);
var cell = (ExtendedViewCell)Cell;
if(args.PropertyName == ExtendedViewCell.BackgroundColorProperty.PropertyName)
{
View.SetBackgroundColor(cell.BackgroundColor.ToAndroid());
}
}
}
}

View File

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

View File

@@ -0,0 +1,23 @@
using Android.Widget;
using Bit.Droid.Effects;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportEffect(typeof(FixedSizeEffect), "FixedSizeEffect")]
namespace Bit.Droid.Effects
{
public class FixedSizeEffect : PlatformEffect
{
protected override void OnAttached()
{
if (Element is Label label && Control is TextView textView)
{
textView.SetTextSize(Android.Util.ComplexUnitType.Pt, (float)label.FontSize);
}
}
protected override void OnDetached()
{
}
}
}

View File

@@ -0,0 +1,24 @@
using Android.Widget;
using Bit.Droid.Effects;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportEffect(typeof(NoEmojiKeyboardEffect), nameof(NoEmojiKeyboardEffect))]
namespace Bit.Droid.Effects
{
public class NoEmojiKeyboardEffect : PlatformEffect
{
protected override void OnAttached()
{
if (Control is EditText editText)
{
editText.InputType = Android.Text.InputTypes.ClassText | Android.Text.InputTypes.TextVariationVisiblePassword | Android.Text.InputTypes.TextFlagMultiLine;
}
}
protected override void OnDetached()
{
}
}
}

View File

@@ -0,0 +1,23 @@
using Android.Widget;
using Bit.Droid.Effects;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportEffect(typeof(RemoveFontPaddingEffect), nameof(RemoveFontPaddingEffect))]
namespace Bit.Droid.Effects
{
public class RemoveFontPaddingEffect : PlatformEffect
{
protected override void OnAttached()
{
if (Control is TextView textView)
{
textView.SetIncludeFontPadding(false);
}
}
protected override void OnDetached()
{
}
}
}

View File

@@ -0,0 +1,30 @@
using Android.Views;
using Bit.Droid.Effects;
using Google.Android.Material.BottomNavigation;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ResolutionGroupName("Bitwarden")]
[assembly: ExportEffect(typeof(TabBarEffect), "TabBarEffect")]
namespace Bit.Droid.Effects
{
public class TabBarEffect : PlatformEffect
{
protected override void OnAttached()
{
if (!(Container.GetChildAt(0) is ViewGroup layout))
{
return;
}
if (!(layout.GetChildAt(1) is BottomNavigationView bottomNavigationView))
{
return;
}
bottomNavigationView.LabelVisibilityMode = LabelVisibilityMode.LabelVisibilityLabeled;
}
protected override void OnDetached()
{
}
}
}

View File

@@ -1,25 +0,0 @@
#if !FDROID
using System;
using Android.App;
using Android.Content;
using Bit.App;
using Bit.App.Abstractions;
using Firebase.Iid;
using Plugin.Settings.Abstractions;
using XLabs.Ioc;
namespace Bit.Android
{
[Service]
[IntentFilter(new[] { "com.google.firebase.INSTANCE_ID_EVENT" })]
public class FirebaseInstanceIdService : Firebase.Iid.FirebaseInstanceIdService
{
public override void OnTokenRefresh()
{
var settings = Resolver.Resolve<ISettings>();
settings.AddOrUpdateValue(Constants.PushRegisteredToken, FirebaseInstanceId.Instance.Token);
Resolver.Resolve<IPushNotificationService>()?.Register();
}
}
}
#endif

View File

@@ -1,44 +0,0 @@
#if !FDROID
using System;
using Android.App;
using Android.Content;
using Bit.App.Abstractions;
using Firebase.Messaging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Xamarin.Forms;
using XLabs.Ioc;
namespace Bit.Android
{
[Service]
[IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
public class FirebaseMessagingService : Firebase.Messaging.FirebaseMessagingService
{
public override void OnMessageReceived(RemoteMessage message)
{
if(message?.Data == null)
{
return;
}
var data = message.Data.ContainsKey("data") ? message.Data["data"] : null;
if(data == null)
{
return;
}
try
{
var obj = JObject.Parse(data);
var listener = Resolver.Resolve<IPushNotificationListener>();
listener.OnMessage(obj, Device.Android);
}
catch(JsonReaderException ex)
{
System.Diagnostics.Debug.WriteLine(ex.ToString());
}
}
}
}
#endif

View File

@@ -1,56 +0,0 @@
#if !FDROID
using HockeyApp.Android;
using Bit.App.Abstractions;
using Newtonsoft.Json;
using Android.Runtime;
namespace Bit.Android
{
public class HockeyAppCrashManagerListener : CrashManagerListener
{
private readonly IAppIdService _appIdService;
private readonly IAuthService _authService;
public HockeyAppCrashManagerListener()
{ }
public HockeyAppCrashManagerListener(System.IntPtr javaRef, JniHandleOwnership transfer)
: base(javaRef, transfer)
{ }
public HockeyAppCrashManagerListener(
IAppIdService appIdService,
IAuthService authService)
{
_appIdService = appIdService;
_authService = authService;
}
public override string Description
{
get
{
if(_appIdService != null && _authService != null)
{
var log = new
{
AppId = _appIdService.AppId,
UserId = _authService.UserId
};
return JsonConvert.SerializeObject(log, Formatting.Indented);
}
else
{
return null;
}
}
}
public override bool ShouldAutoUploadCrashes()
{
return true;
}
}
}
#endif

View File

@@ -1,259 +1,320 @@
using System;
using Android.App;
using Android.Content.PM;
using Android.Views;
using Android.OS;
using Bit.App.Abstractions;
using XLabs.Ioc;
using Plugin.Settings.Abstractions;
using Plugin.Connectivity.Abstractions;
using Android.Content;
using System.Reflection;
using Xamarin.Forms.Platform.Android;
using Xamarin.Forms;
using System.Threading.Tasks;
using Bit.App;
using Android.Nfc;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Android.App;
using Android.Content;
using Android.Content.PM;
using Android.Content.Res;
using Android.Nfc;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Bit.App.Abstractions;
using Bit.App.Models;
using Bit.App.Enums;
using Bit.App.Resources;
using Bit.App.Utilities;
using Bit.Core;
using Bit.Core.Abstractions;
using Bit.Core.Enums;
using Bit.Core.Utilities;
using Bit.Droid.Receivers;
using Bit.Droid.Utilities;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Xamarin.Essentials;
using ZXing.Net.Mobile.Android;
using FileProvider = AndroidX.Core.Content.FileProvider;
namespace Bit.Android
namespace Bit.Droid
{
[Activity(ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation, Exported = false)]
public class MainActivity : FormsAppCompatActivity
// Activity and IntentFilter declarations have been moved to Properties/AndroidManifest.xml
// They have been hardcoded so we can use the default LaunchMode on Android 11+
// LaunchMode defined in values/manifest.xml for Android 10- and values-v30/manifest.xml for Android 11+
// See https://github.com/bitwarden/mobile/pull/1673 for details
[Register("com.x8bit.bitwarden.MainActivity")]
public class MainActivity : Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
private const string HockeyAppId = "d3834185b4a643479047b86c65293d42";
private Java.Util.Regex.Pattern _otpPattern = Java.Util.Regex.Pattern.Compile("^.*?([cbdefghijklnrtuv]{32,64})$");
private IDeviceActionService _deviceActionService;
private IDeviceInfoService _deviceInfoService;
private IAppSettingsService _appSettingsService;
private ISettings _settings;
private IFileService _fileService;
private IMessagingService _messagingService;
private IBroadcasterService _broadcasterService;
private IStateService _stateService;
private IAppIdService _appIdService;
private IEventService _eventService;
private IPushNotificationListenerService _pushNotificationListenerService;
private ILogger _logger;
private PendingIntent _eventUploadPendingIntent;
private AppOptions _appOptions;
private string _activityKey = $"{nameof(MainActivity)}_{Java.Lang.JavaSystem.CurrentTimeMillis().ToString()}";
private Java.Util.Regex.Pattern _otpPattern =
Java.Util.Regex.Pattern.Compile("^.*?([cbdefghijklnrtuv]{32,64})$");
protected override void OnCreate(Bundle bundle)
protected override void OnCreate(Bundle savedInstanceState)
{
if(!Resolver.IsSet)
{
MainApplication.SetIoc(Application);
}
var eventUploadIntent = new Intent(this, typeof(EventUploadReceiver));
_eventUploadPendingIntent = PendingIntent.GetBroadcast(this, 0, eventUploadIntent,
AndroidHelpers.AddPendingIntentMutabilityFlag(PendingIntentFlags.UpdateCurrent, false));
var policy = new StrictMode.ThreadPolicy.Builder().PermitAll().Build();
StrictMode.SetThreadPolicy(policy);
ToolbarResource = Resource.Layout.toolbar;
TabLayoutResource = Resource.Layout.tabs;
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
_fileService = ServiceContainer.Resolve<IFileService>();
_messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
_broadcasterService = ServiceContainer.Resolve<IBroadcasterService>("broadcasterService");
_stateService = ServiceContainer.Resolve<IStateService>("stateService");
_appIdService = ServiceContainer.Resolve<IAppIdService>("appIdService");
_eventService = ServiceContainer.Resolve<IEventService>("eventService");
_pushNotificationListenerService = ServiceContainer.Resolve<IPushNotificationListenerService>();
_logger = ServiceContainer.Resolve<ILogger>("logger");
base.OnCreate(bundle);
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
// workaround for app compat bug
// ref https://forums.xamarin.com/discussion/62414/app-resuming-results-in-crash-with-formsappcompatactivity
Task.Delay(10).Wait();
// this needs to be called here before base.OnCreate(...)
Intent?.Validate();
Console.WriteLine("A OnCreate");
if(!App.Utilities.Helpers.InDebugMode())
base.OnCreate(savedInstanceState);
_deviceActionService.SetScreenCaptureAllowedAsync().FireAndForget(_ =>
{
Window.AddFlags(WindowManagerFlags.Secure);
Window.AddFlags(Android.Views.WindowManagerFlags.Secure);
});
_logger.InitAsync();
var toplayout = Window?.DecorView?.RootView;
if (toplayout != null)
{
toplayout.FilterTouchesWhenObscured = true;
}
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);
typeof(Color).GetProperty("Accent", BindingFlags.Public | BindingFlags.Static)
.SetValue(null, Color.FromHex("d2d6de"));
_deviceActionService = Resolver.Resolve<IDeviceActionService>();
_deviceInfoService = Resolver.Resolve<IDeviceInfoService>();
_appSettingsService = Resolver.Resolve<IAppSettingsService>();
_settings = Resolver.Resolve<ISettings>();
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
Xamarin.Forms.Forms.Init(this, savedInstanceState);
_appOptions = GetOptions();
LoadApplication(new App.App(
_appOptions,
Resolver.Resolve<IAuthService>(),
Resolver.Resolve<IConnectivity>(),
Resolver.Resolve<IDatabaseService>(),
Resolver.Resolve<ISyncService>(),
_settings,
Resolver.Resolve<ILockService>(),
Resolver.Resolve<ILocalizeService>(),
Resolver.Resolve<IAppInfoService>(),
_appSettingsService,
_deviceActionService));
CreateNotificationChannel();
LoadApplication(new App.App(_appOptions));
DisableAndroidFontScale();
if(_appOptions?.Uri == null)
_broadcasterService.Subscribe(_activityKey, (message) =>
{
MessagingCenter.Subscribe<Xamarin.Forms.Application, bool>(Xamarin.Forms.Application.Current,
"ListenYubiKeyOTP", (sender, listen) => ListenYubiKey(listen));
MessagingCenter.Subscribe<Xamarin.Forms.Application>(Xamarin.Forms.Application.Current,
"FinishMainActivity", (sender) => Finish());
}
if (message.Command == "startEventTimer")
{
StartEventAlarm();
}
else if (message.Command == "stopEventTimer")
{
var task = StopEventAlarmAsync();
}
else if (message.Command == "finishMainActivity")
{
Xamarin.Forms.Device.BeginInvokeOnMainThread(() => Finish());
}
else if (message.Command == "listenYubiKeyOTP")
{
ListenYubiKey((bool)message.Data);
}
else if (message.Command == "updatedTheme")
{
Xamarin.Forms.Device.BeginInvokeOnMainThread(() => AppearanceAdjustments());
}
else if (message.Command == "exit")
{
ExitApp();
}
});
}
protected override void OnPause()
{
Console.WriteLine("A OnPause");
base.OnPause();
ListenYubiKey(false);
}
protected override void OnDestroy()
{
Console.WriteLine("A OnDestroy");
base.OnDestroy();
}
protected override void OnRestart()
{
Console.WriteLine("A OnRestart");
base.OnRestart();
}
protected override void OnStart()
{
Console.WriteLine("A OnStart");
base.OnStart();
}
protected override void OnStop()
{
Console.WriteLine("A OnStop");
base.OnStop();
}
protected override void OnResume()
{
base.OnResume();
Console.WriteLine("A OnResume");
Xamarin.Essentials.Platform.OnResume();
AppearanceAdjustments();
// workaround for app compat bug
// ref https://bugzilla.xamarin.com/show_bug.cgi?id=36907
Task.Delay(10).Wait();
ThemeManager.UpdateThemeOnPagesAsync();
if(_deviceInfoService.NfcEnabled)
if (_deviceActionService.SupportsNfc())
{
try
{
MessagingCenter.Send(Xamarin.Forms.Application.Current, "ResumeYubiKey");
}
catch(Exception e)
{
System.Diagnostics.Debug.WriteLine(e);
_messagingService.Send("resumeYubiKey");
}
catch { }
}
AndroidHelpers.SetPreconfiguredRestrictionSettingsAsync(this)
.GetAwaiter()
.GetResult();
if(_appSettingsService.Locked)
if (Intent?.GetStringExtra(Core.Constants.NotificationData) is string notificationDataJson)
{
MessagingCenter.Send(Xamarin.Forms.Application.Current, "Resumed", false);
var notificationType = JToken.Parse(notificationDataJson).SelectToken(Core.Constants.NotificationDataType);
if (notificationType.ToString() == PasswordlessNotificationData.TYPE)
{
_pushNotificationListenerService.OnNotificationTapped(JsonConvert.DeserializeObject<PasswordlessNotificationData>(notificationDataJson)).FireAndForget();
}
}
}
protected override void OnNewIntent(Intent intent)
{
base.OnNewIntent(intent);
Console.WriteLine("A OnNewIntent");
ParseYubiKey(intent.DataString);
try
{
if (intent?.GetStringExtra("uri") is string uri)
{
_messagingService.Send("popAllAndGoToAutofillCiphers");
if (_appOptions != null)
{
_appOptions.Uri = uri;
}
}
else if (intent.GetBooleanExtra("generatorTile", false))
{
_messagingService.Send("popAllAndGoToTabGenerator");
if (_appOptions != null)
{
_appOptions.GeneratorTile = true;
}
}
else if (intent.GetBooleanExtra("myVaultTile", false))
{
_messagingService.Send("popAllAndGoToTabMyVault");
if (_appOptions != null)
{
_appOptions.MyVaultTile = true;
}
}
else if (intent.Action == Intent.ActionSend && intent.Type != null)
{
if (_appOptions != null)
{
_appOptions.CreateSend = GetCreateSendRequest(intent);
}
_messagingService.Send("popAllAndGoToTabSend");
}
else
{
ParseYubiKey(intent.DataString);
}
}
catch (Exception e)
{
System.Diagnostics.Debug.WriteLine(">>> {0}: {1}", e.GetType(), e.StackTrace);
}
}
public async override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
public async override void OnRequestPermissionsResult(int requestCode, string[] permissions,
[GeneratedEnum] Permission[] grantResults)
{
if(requestCode == Constants.SelectFilePermissionRequestCode)
if (requestCode == Core.Constants.SelectFilePermissionRequestCode)
{
if(grantResults.Any(r => r != Permission.Granted))
if (grantResults.Any(r => r != Permission.Granted))
{
MessagingCenter.Send(Xamarin.Forms.Application.Current, "SelectFileCameraPermissionDenied");
_messagingService.Send("selectFileCameraPermissionDenied");
}
await _deviceActionService.SelectFileAsync();
return;
await _fileService.SelectFileAsync();
}
ZXing.Net.Mobile.Forms.Android.PermissionsHandler.OnRequestPermissionsResult(requestCode, permissions, grantResults);
else
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
PermissionsHandler.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
if(requestCode == Constants.SelectFileRequestCode && resultCode == Result.Ok)
if (resultCode == Result.Ok &&
(requestCode == Core.Constants.SelectFileRequestCode || requestCode == Core.Constants.SaveFileRequestCode))
{
global::Android.Net.Uri uri = null;
Android.Net.Uri uri = null;
string fileName = null;
if(data != null && data.Data != null)
if (data != null && data.Data != null)
{
uri = data.Data;
fileName = Utilities.GetFileName(ApplicationContext, uri);
fileName = AndroidHelpers.GetFileName(ApplicationContext, uri);
}
else
{
// camera
var root = new Java.IO.File(global::Android.OS.Environment.ExternalStorageDirectory, "bitwarden");
var file = new Java.IO.File(root, "temp_camera_photo.jpg");
uri = global::Android.Net.Uri.FromFile(file);
var file = new Java.IO.File(FilesDir, "temp_camera_photo.jpg");
uri = FileProvider.GetUriForFile(this, "com.x8bit.bitwarden.fileprovider", file);
fileName = $"photo_{DateTime.UtcNow.ToString("yyyyMMddHHmmss")}.jpg";
}
if(uri == null)
if (uri == null)
{
return;
}
using(var stream = ContentResolver.OpenInputStream(uri))
using(var memoryStream = new MemoryStream())
if (requestCode == Core.Constants.SaveFileRequestCode)
{
stream.CopyTo(memoryStream);
MessagingCenter.Send(Xamarin.Forms.Application.Current, "SelectFileResult",
new Tuple<byte[], string>(memoryStream.ToArray(), fileName ?? "unknown_file_name"));
_messagingService.Send("selectSaveFileResult",
new Tuple<string, string>(uri.ToString(), fileName));
return;
}
try
{
using (var stream = ContentResolver.OpenInputStream(uri))
using (var memoryStream = new MemoryStream())
{
stream.CopyTo(memoryStream);
_messagingService.Send("selectFileResult",
new Tuple<byte[], string>(memoryStream.ToArray(), fileName ?? "unknown_file_name"));
}
}
catch (Java.IO.FileNotFoundException)
{
return;
}
}
}
protected override void OnDestroy()
{
base.OnDestroy();
_broadcasterService.Unsubscribe(_activityKey);
}
private void ListenYubiKey(bool listen)
{
if(!_deviceInfoService.NfcEnabled)
if (!_deviceActionService.SupportsNfc())
{
return;
}
var adapter = NfcAdapter.GetDefaultAdapter(this);
if(listen)
if (listen)
{
var intent = new Intent(this, Class);
intent.AddFlags(ActivityFlags.SingleTop);
var pendingIntent = PendingIntent.GetActivity(this, 0, intent, 0);
var pendingIntent = PendingIntent.GetActivity(this, 0, intent, AndroidHelpers.AddPendingIntentMutabilityFlag(0, true));
// register for all NDEF tags starting with http och https
var ndef = new IntentFilter(NfcAdapter.ActionNdefDiscovered);
ndef.AddDataScheme("http");
ndef.AddDataScheme("https");
var filters = new IntentFilter[] { ndef };
// register for foreground dispatch so we'll receive tags according to our intent filters
adapter.EnableForegroundDispatch(this, pendingIntent, filters, null);
try
{
// register for foreground dispatch so we'll receive tags according to our intent filters
adapter.EnableForegroundDispatch(this, pendingIntent, filters, null);
}
catch { }
}
else
{
adapter.DisableForegroundDispatch(this);
}
}
private void ParseYubiKey(string data)
{
if(data == null)
{
return;
}
var otpMatch = _otpPattern.Matcher(data);
if(otpMatch.Matches())
{
var otp = otpMatch.Group(1);
MessagingCenter.Send(Xamarin.Forms.Application.Current, "GotYubiKeyOTP", otp);
try
{
adapter.DisableForegroundDispatch(this);
}
catch { }
}
}
@@ -263,16 +324,16 @@ namespace Bit.Android
{
Uri = Intent.GetStringExtra("uri") ?? Intent.GetStringExtra("autofillFrameworkUri"),
MyVaultTile = Intent.GetBooleanExtra("myVaultTile", false),
FromAutofillFramework = Intent.GetBooleanExtra("autofillFramework", false)
GeneratorTile = Intent.GetBooleanExtra("generatorTile", false),
FromAutofillFramework = Intent.GetBooleanExtra("autofillFramework", false),
CreateSend = GetCreateSendRequest(Intent)
};
var fillType = Intent.GetIntExtra("autofillFrameworkFillType", 0);
if(fillType > 0)
if (fillType > 0)
{
options.FillType = (CipherType)fillType;
}
if(Intent.GetBooleanExtra("autofillFrameworkSave", false))
if (Intent.GetBooleanExtra("autofillFrameworkSave", false))
{
options.SaveType = (CipherType)Intent.GetIntExtra("autofillFrameworkType", 0);
options.SaveName = Intent.GetStringExtra("autofillFrameworkName");
@@ -284,8 +345,116 @@ namespace Bit.Android
options.SaveCardExpYear = Intent.GetStringExtra("autofillFrameworkCardExpYear");
options.SaveCardCode = Intent.GetStringExtra("autofillFrameworkCardCode");
}
return options;
}
private Tuple<SendType, string, byte[], string> GetCreateSendRequest(Intent intent)
{
if (intent.Action == Intent.ActionSend && intent.Type != null)
{
if ((intent.Flags & ActivityFlags.LaunchedFromHistory) == ActivityFlags.LaunchedFromHistory)
{
// don't re-deliver intent if resuming from app switcher
return null;
}
var type = intent.Type;
if (type.Contains("text/"))
{
var subject = intent.GetStringExtra(Intent.ExtraSubject);
var text = intent.GetStringExtra(Intent.ExtraText);
return new Tuple<SendType, string, byte[], string>(SendType.Text, subject, null, text);
}
else
{
var data = intent.ClipData?.GetItemAt(0);
var uri = data?.Uri;
var filename = AndroidHelpers.GetFileName(ApplicationContext, uri);
try
{
using (var stream = ContentResolver.OpenInputStream(uri))
using (var memoryStream = new MemoryStream())
{
stream.CopyTo(memoryStream);
return new Tuple<SendType, string, byte[], string>(SendType.File, filename, memoryStream.ToArray(), null);
}
}
catch (Java.IO.FileNotFoundException) { }
}
}
return null;
}
private void ParseYubiKey(string data)
{
if (data == null)
{
return;
}
var otpMatch = _otpPattern.Matcher(data);
if (otpMatch.Matches())
{
var otp = otpMatch.Group(1);
_messagingService.Send("gotYubiKeyOTP", otp);
}
}
private void AppearanceAdjustments()
{
Window?.SetStatusBarColor(ThemeHelpers.NavBarBackgroundColor);
Window?.DecorView.SetBackgroundColor(ThemeHelpers.BackgroundColor);
ThemeHelpers.SetAppearance(ThemeManager.GetTheme(), ThemeManager.OsDarkModeEnabled());
}
private void ExitApp()
{
FinishAffinity();
Java.Lang.JavaSystem.Exit(0);
}
private void StartEventAlarm()
{
var alarmManager = GetSystemService(AlarmService) as AlarmManager;
alarmManager.SetInexactRepeating(AlarmType.ElapsedRealtime, 120000, 300000, _eventUploadPendingIntent);
}
private async Task StopEventAlarmAsync()
{
var alarmManager = GetSystemService(AlarmService) as AlarmManager;
alarmManager.Cancel(_eventUploadPendingIntent);
await _eventService.UploadEventsAsync();
}
private void CreateNotificationChannel()
{
#if !FDROID
if (Build.VERSION.SdkInt < BuildVersionCodes.O)
{
// Notification channels are new in API 26 (and not a part of the
// support library). There is no need to create a notification
// channel on older versions of Android.
return;
}
var channel = new NotificationChannel(Core.Constants.AndroidNotificationChannelId, AppResources.AllNotifications, NotificationImportance.Default);
if(GetSystemService(NotificationService) is NotificationManager notificationManager)
{
notificationManager.CreateNotificationChannel(channel);
}
#endif
}
private void DisableAndroidFontScale()
{
try
{
//As we are using NamedSizes the xamarin will change the font size. So we are disabling the Android scaling.
Resources.Configuration.FontScale = 1f;
BaseContext.Resources.DisplayMetrics.ScaledDensity = Resources.Configuration.FontScale * (float)DeviceDisplay.MainDisplayInfo.Density;
}
catch (Exception e)
{
_logger.Exception(e);
}
}
}
}

View File

@@ -1,178 +1,209 @@
using System;
using System;
using System.IO;
using System.Threading.Tasks;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Bit.Android.Services;
using Bit.App.Abstractions;
using Bit.App.Repositories;
using Bit.App.Services;
using Plugin.Connectivity;
using Bit.Core;
using Bit.Core.Abstractions;
using Bit.Core.Services;
using Bit.Core.Utilities;
using Bit.Droid.Services;
using Plugin.CurrentActivity;
using Plugin.Fingerprint;
using Plugin.Settings;
using XLabs.Ioc;
using System.Threading.Tasks;
using FFImageLoading.Forms.Droid;
using XLabs.Ioc.SimpleInjectorContainer;
using SimpleInjector;
using Xamarin.Android.Net;
using System.Net.Http;
using System.Net;
using Bit.App.Utilities;
using Bit.App.Pages;
using Bit.App.Utilities.AccountManagement;
using Bit.App.Controls;
#if !FDROID
using Android.Gms.Security;
#endif
namespace Bit.Android
namespace Bit.Droid
{
#if DEBUG
[Application(Debuggable = true)]
#else
[Application(Debuggable = false)]
#endif
public class MainApplication : Application, Application.IActivityLifecycleCallbacks
[Register("com.x8bit.bitwarden.MainApplication")]
#if FDROID
public class MainApplication : Application
#else
public class MainApplication : Application, ProviderInstaller.IProviderInstallListener
#endif
{
private const string FirstLaunchKey = "firstLaunch";
private const string LastVersionCodeKey = "lastVersionCode";
public static Context AppContext;
public MainApplication(IntPtr handle, JniHandleOwnership transer)
: base(handle, transer)
{
//AndroidEnvironment.UnhandledExceptionRaiser += AndroidEnvironment_UnhandledExceptionRaiser;
if(!Resolver.IsSet)
if (ServiceContainer.RegisteredServices.Count == 0)
{
SetIoc(this);
}
}
RegisterLocalServices();
var deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
ServiceContainer.Init(deviceActionService.DeviceUserAgent, Core.Constants.ClearCiphersCacheKey,
Core.Constants.AndroidAllClearCipherCacheKeys);
InitializeAppSetup();
private void AndroidEnvironment_UnhandledExceptionRaiser(object sender, RaiseThrowableEventArgs e)
{
var message = Utilities.AppendExceptionToMessage("", e.Exception);
//Utilities.SaveCrashFile(message, true);
Utilities.SendCrashEmail(message, false);
// TODO: Update when https://github.com/bitwarden/mobile/pull/1662 gets merged
var deleteAccountActionFlowExecutioner = new DeleteAccountActionFlowExecutioner(
ServiceContainer.Resolve<IApiService>("apiService"),
ServiceContainer.Resolve<IMessagingService>("messagingService"),
ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService"),
ServiceContainer.Resolve<IDeviceActionService>("deviceActionService"),
ServiceContainer.Resolve<ILogger>("logger"));
ServiceContainer.Register<IDeleteAccountActionFlowExecutioner>("deleteAccountActionFlowExecutioner", deleteAccountActionFlowExecutioner);
var verificationActionsFlowHelper = new VerificationActionsFlowHelper(
ServiceContainer.Resolve<IKeyConnectorService>("keyConnectorService"),
ServiceContainer.Resolve<IPasswordRepromptService>("passwordRepromptService"),
ServiceContainer.Resolve<ICryptoService>("cryptoService"));
ServiceContainer.Register<IVerificationActionsFlowHelper>("verificationActionsFlowHelper", verificationActionsFlowHelper);
var accountsManager = new AccountsManager(
ServiceContainer.Resolve<IBroadcasterService>("broadcasterService"),
ServiceContainer.Resolve<IVaultTimeoutService>("vaultTimeoutService"),
ServiceContainer.Resolve<IStorageService>("secureStorageService"),
ServiceContainer.Resolve<IStateService>("stateService"),
ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService"),
ServiceContainer.Resolve<IAuthService>("authService"),
ServiceContainer.Resolve<ILogger>("logger"),
ServiceContainer.Resolve<IMessagingService>("messagingService"));
ServiceContainer.Register<IAccountsManager>("accountsManager", accountsManager);
}
#if !FDROID
if (Build.VERSION.SdkInt <= BuildVersionCodes.Kitkat)
{
ProviderInstaller.InstallIfNeededAsync(ApplicationContext, this);
}
#endif
}
public override void OnCreate()
{
base.OnCreate();
// workaround for app compat bug
// ref https://forums.xamarin.com/discussion/62414/app-resuming-results-in-crash-with-formsappcompatactivity
Task.Delay(10).Wait();
RegisterActivityLifecycleCallbacks(this);
AppContext = ApplicationContext;
Bootstrap();
CrossCurrentActivity.Current.Init(this);
}
public override void OnTerminate()
{
base.OnTerminate();
UnregisterActivityLifecycleCallbacks(this);
}
public void OnActivityCreated(Activity activity, Bundle savedInstanceState)
{
CrossCurrentActivity.Current.Activity = activity;
}
public void OnActivityDestroyed(Activity activity)
public void OnProviderInstallFailed(int errorCode, Intent recoveryIntent)
{
}
public void OnActivityPaused(Activity activity)
public void OnProviderInstalled()
{
}
public void OnActivityResumed(Activity activity)
private void RegisterLocalServices()
{
CrossCurrentActivity.Current.Activity = activity;
}
ServiceContainer.Register<INativeLogService>("nativeLogService", new AndroidLogService());
#if FDROID
var logger = new StubLogger();
#elif DEBUG
var logger = DebugLogger.Instance;
#else
var logger = Logger.Instance;
#endif
ServiceContainer.Register("logger", logger);
public void OnActivitySaveInstanceState(Activity activity, Bundle outState)
{
}
public void OnActivityStarted(Activity activity)
{
CrossCurrentActivity.Current.Activity = activity;
}
public void OnActivityStopped(Activity activity)
{
}
public static void SetIoc(Application application)
{
Refractored.FabControl.Droid.FloatingActionButtonViewRenderer.Init();
CachedImageRenderer.Init(true);
ZXing.Net.Mobile.Forms.Android.Platform.Init();
// Note: This might cause a race condition. Investigate more.
Task.Run(() =>
{
FFImageLoading.Forms.Platform.CachedImageRenderer.Init(true);
FFImageLoading.ImageService.Instance.Initialize(new FFImageLoading.Config.Configuration
{
FadeAnimationEnabled = false,
FadeAnimationForCachedImages = false,
HttpClient = new HttpClient(new AndroidClientHandler() { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate })
});
ZXing.Net.Mobile.Forms.Android.Platform.Init();
});
CrossFingerprint.SetCurrentActivityResolver(() => CrossCurrentActivity.Current.Activity);
//var container = new UnityContainer();
var container = new Container();
var preferencesStorage = new PreferencesStorageService(null);
var documentsPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
var liteDbStorage = new LiteDbStorageService(Path.Combine(documentsPath, "bitwarden.db"));
var localizeService = new LocalizeService();
var broadcasterService = new BroadcasterService(logger);
var messagingService = new MobileBroadcasterMessagingService(broadcasterService);
var i18nService = new MobileI18nService(localizeService.GetCurrentCultureInfo());
var secureStorageService = new SecureStorageService();
var cryptoPrimitiveService = new CryptoPrimitiveService();
var mobileStorageService = new MobileStorageService(preferencesStorage, liteDbStorage);
var stateService = new StateService(mobileStorageService, secureStorageService, messagingService);
var stateMigrationService =
new StateMigrationService(liteDbStorage, preferencesStorage, secureStorageService);
var clipboardService = new ClipboardService(stateService);
var deviceActionService = new DeviceActionService(stateService, messagingService);
var fileService = new FileService(stateService, broadcasterService);
var autofillHandler = new AutofillHandler(stateService, messagingService, clipboardService, new LazyResolve<IEventService>());
var platformUtilsService = new MobilePlatformUtilsService(deviceActionService, clipboardService,
messagingService, broadcasterService);
var biometricService = new BiometricService();
var cryptoFunctionService = new PclCryptoFunctionService(cryptoPrimitiveService);
var cryptoService = new CryptoService(stateService, cryptoFunctionService);
var passwordRepromptService = new MobilePasswordRepromptService(platformUtilsService, cryptoService);
// Android Stuff
container.RegisterSingleton(application.ApplicationContext);
container.RegisterSingleton<Application>(application);
// Services
container.RegisterSingleton<IDatabaseService, DatabaseService>();
container.RegisterSingleton<ISqlService, SqlService>();
container.RegisterSingleton<ISecureStorageService, AndroidKeyStoreStorageService>();
container.RegisterSingleton<ICryptoService, CryptoService>();
container.RegisterSingleton<IKeyDerivationService, BouncyCastleKeyDerivationService>();
container.RegisterSingleton<IAuthService, AuthService>();
container.RegisterSingleton<IFolderService, FolderService>();
container.RegisterSingleton<ICollectionService, CollectionService>();
container.RegisterSingleton<ICipherService, CipherService>();
container.RegisterSingleton<ISyncService, SyncService>();
container.RegisterSingleton<IDeviceActionService, DeviceActionService>();
container.RegisterSingleton<IAppIdService, AppIdService>();
container.RegisterSingleton<IPasswordGenerationService, PasswordGenerationService>();
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<IAppSettingsService, AppSettingsService>();
// Repositories
container.RegisterSingleton<IFolderRepository, FolderRepository>();
container.RegisterSingleton<IFolderApiRepository, FolderApiRepository>();
container.RegisterSingleton<ICipherRepository, CipherRepository>();
container.RegisterSingleton<IAttachmentRepository, AttachmentRepository>();
container.RegisterSingleton<IConnectApiRepository, ConnectApiRepository>();
container.RegisterSingleton<IDeviceApiRepository, DeviceApiRepository>();
container.RegisterSingleton<IAccountsApiRepository, AccountsApiRepository>();
container.RegisterSingleton<ICipherApiRepository, CipherApiRepository>();
container.RegisterSingleton<ISettingsRepository, SettingsRepository>();
container.RegisterSingleton<ISettingsApiRepository, SettingsApiRepository>();
container.RegisterSingleton<ITwoFactorApiRepository, TwoFactorApiRepository>();
container.RegisterSingleton<ISyncApiRepository, SyncApiRepository>();
container.RegisterSingleton<ICollectionRepository, CollectionRepository>();
container.RegisterSingleton<ICipherCollectionRepository, CipherCollectionRepository>();
// Other
container.RegisterSingleton(CrossSettings.Current);
container.RegisterSingleton(CrossConnectivity.Current);
container.RegisterSingleton(CrossFingerprint.Current);
ServiceContainer.Register<IBroadcasterService>("broadcasterService", broadcasterService);
ServiceContainer.Register<IMessagingService>("messagingService", messagingService);
ServiceContainer.Register<ILocalizeService>("localizeService", localizeService);
ServiceContainer.Register<II18nService>("i18nService", i18nService);
ServiceContainer.Register<ICryptoPrimitiveService>("cryptoPrimitiveService", cryptoPrimitiveService);
ServiceContainer.Register<IStorageService>("storageService", mobileStorageService);
ServiceContainer.Register<IStorageService>("secureStorageService", secureStorageService);
ServiceContainer.Register<IStateService>("stateService", stateService);
ServiceContainer.Register<IStateMigrationService>("stateMigrationService", stateMigrationService);
ServiceContainer.Register<IClipboardService>("clipboardService", clipboardService);
ServiceContainer.Register<IDeviceActionService>("deviceActionService", deviceActionService);
ServiceContainer.Register<IFileService>(fileService);
ServiceContainer.Register<IAutofillHandler>(autofillHandler);
ServiceContainer.Register<IPlatformUtilsService>("platformUtilsService", platformUtilsService);
ServiceContainer.Register<IBiometricService>("biometricService", biometricService);
ServiceContainer.Register<ICryptoFunctionService>("cryptoFunctionService", cryptoFunctionService);
ServiceContainer.Register<ICryptoService>("cryptoService", cryptoService);
ServiceContainer.Register<IPasswordRepromptService>("passwordRepromptService", passwordRepromptService);
ServiceContainer.Register<IAvatarImageSourcePool>("avatarImageSourcePool", new AvatarImageSourcePool());
// Push
#if FDROID
container.RegisterSingleton<IPushNotificationListener, NoopPushNotificationListener>();
container.RegisterSingleton<IPushNotificationService, NoopPushNotificationService>();
ServiceContainer.Register<IPushNotificationListenerService>(
"pushNotificationListenerService", new NoopPushNotificationListenerService());
ServiceContainer.Register<IPushNotificationService>(
"pushNotificationService", new NoopPushNotificationService());
#else
container.RegisterSingleton<IPushNotificationListener, PushNotificationListener>();
container.RegisterSingleton<IPushNotificationService, AndroidPushNotificationService>();
var notificationListenerService = new PushNotificationListenerService();
ServiceContainer.Register<IPushNotificationListenerService>(
"pushNotificationListenerService", notificationListenerService);
var androidPushNotificationService = new AndroidPushNotificationService(
stateService, notificationListenerService);
ServiceContainer.Register<IPushNotificationService>(
"pushNotificationService", androidPushNotificationService);
#endif
}
container.Verify();
Resolver.SetResolver(new SimpleInjectorResolver(container));
private void Bootstrap()
{
(ServiceContainer.Resolve<II18nService>("i18nService") as MobileI18nService).Init();
ServiceContainer.Resolve<IAuthService>("authService").Init();
// Note: This is not awaited
var bootstrapTask = BootstrapAsync();
}
private async Task BootstrapAsync()
{
await ServiceContainer.Resolve<IEnvironmentService>("environmentService").SetUrlsFromStorageAsync();
}
private void InitializeAppSetup()
{
var appSetup = new AppSetup();
appSetup.InitializeServicesLastChance();
ServiceContainer.Register<IAppSetup>("appSetup", appSetup);
}
}
}
}

View File

@@ -1,23 +0,0 @@
using Android.App;
using Android.Content;
using Bit.App.Abstractions;
using Bit.App.Utilities;
using Plugin.Settings.Abstractions;
using System;
using XLabs.Ioc;
namespace Bit.Android
{
[BroadcastReceiver(Name = "com.x8bit.bitwarden.PackageReplacedReceiver", Exported = false)]
[IntentFilter(new[] { Intent.ActionMyPackageReplaced })]
public class PackageReplacedReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
Console.WriteLine("Bitwarden App Updated!!");
Helpers.PerformUpdateTasks(Resolver.Resolve<ISettings>(),
Resolver.Resolve<IAppInfoService>(), Resolver.Resolve<IDatabaseService>(),
Resolver.Resolve<ISyncService>());
}
}
}

View File

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

View File

@@ -1,7 +1,5 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Android.App;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
@@ -9,9 +7,9 @@ using Android.App;
[assembly: AssemblyTitle("BitwardenAndroid")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("8bit Solutions LLC")]
[assembly: AssemblyCompany("Bitwarden Inc.")]
[assembly: AssemblyProduct("Bitwarden")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]

View File

@@ -0,0 +1,60 @@
#if !FDROID
using System;
using Android.App;
using Bit.App.Abstractions;
using Bit.Core.Abstractions;
using Bit.Core.Services;
using Bit.Core.Utilities;
using Firebase.Messaging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Xamarin.Forms;
namespace Bit.Droid.Push
{
[Service(Exported=false)]
[IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
public class FirebaseMessagingService : Firebase.Messaging.FirebaseMessagingService
{
public async override void OnNewToken(string token)
{
try {
var stateService = ServiceContainer.Resolve<IStateService>("stateService");
var pushNotificationService = ServiceContainer.Resolve<IPushNotificationService>("pushNotificationService");
await stateService.SetPushRegisteredTokenAsync(token);
await pushNotificationService.RegisterAsync();
}
catch (Exception ex)
{
Logger.Instance.Exception(ex);
}
}
public async override void OnMessageReceived(RemoteMessage message)
{
try
{
if (message?.Data == null)
{
return;
}
var data = message.Data.ContainsKey("data") ? message.Data["data"] : null;
if (data == null)
{
return;
}
var obj = JObject.Parse(data);
var listener = ServiceContainer.Resolve<IPushNotificationListenerService>(
"pushNotificationListenerService");
await listener.OnMessageAsync(obj, Device.Android);
}
catch (Exception ex)
{
Logger.Instance.Exception(ex);
}
}
}
}
#endif

View File

@@ -0,0 +1,14 @@
using Android.Content;
namespace Bit.Droid.Receivers
{
[BroadcastReceiver(Name = "com.x8bit.bitwarden.ClearClipboardAlarmReceiver", Exported = false)]
public class ClearClipboardAlarmReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
var clipboardManager = context.GetSystemService(Context.ClipboardService) as ClipboardManager;
clipboardManager.PrimaryClip = ClipData.NewPlainText("bitwarden", " ");
}
}
}

View File

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

View File

@@ -0,0 +1,41 @@
using Android.Content;
using Bit.App.Abstractions;
using Bit.App.Models;
using Bit.App.Services;
using Bit.Core;
using Bit.Core.Abstractions;
using Bit.Core.Services;
using Bit.Core.Utilities;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using CoreConstants = Bit.Core.Constants;
namespace Bit.Droid.Receivers
{
[BroadcastReceiver(Name = Constants.PACKAGE_NAME + "." + nameof(NotificationDismissReceiver), Exported = false)]
public class NotificationDismissReceiver : BroadcastReceiver
{
private readonly LazyResolve<IPushNotificationListenerService> _pushNotificationListenerService = new LazyResolve<IPushNotificationListenerService>();
private readonly LazyResolve<ILogger> _logger = new LazyResolve<ILogger>();
public override void OnReceive(Context context, Intent intent)
{
try
{
if (intent?.GetStringExtra(CoreConstants.NotificationData) is string notificationDataJson)
{
var notificationType = JToken.Parse(notificationDataJson).SelectToken(CoreConstants.NotificationDataType);
if (notificationType.ToString() == PasswordlessNotificationData.TYPE)
{
_pushNotificationListenerService.Value.OnNotificationDismissed(JsonConvert.DeserializeObject<PasswordlessNotificationData>(notificationDataJson)).FireAndForget();
}
}
}
catch (System.Exception ex)
{
_logger.Value.Exception(ex);
}
}
}
}

View File

@@ -0,0 +1,22 @@
using Android.App;
using Android.Content;
using Bit.App.Abstractions;
using Bit.App.Utilities;
using Bit.Core.Abstractions;
using Bit.Core.Utilities;
namespace Bit.Droid.Receivers
{
[BroadcastReceiver(Name = "com.x8bit.bitwarden.PackageReplacedReceiver", Exported = false)]
[IntentFilter(new[] { Intent.ActionMyPackageReplaced })]
public class PackageReplacedReceiver : BroadcastReceiver
{
public override async void OnReceive(Context context, Intent intent)
{
await AppHelpers.PerformUpdateTasksAsync(
ServiceContainer.Resolve<ISyncService>("syncService"),
ServiceContainer.Resolve<IDeviceActionService>("deviceActionService"),
ServiceContainer.Resolve<IStateService>("stateService"));
}
}
}

View File

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

View File

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

View File

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

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