diff --git a/src/App/Pages/Accounts/EnvironmentPage.xaml b/src/App/Pages/Accounts/EnvironmentPage.xaml
index 73a1beb04..0623ec722 100644
--- a/src/App/Pages/Accounts/EnvironmentPage.xaml
+++ b/src/App/Pages/Accounts/EnvironmentPage.xaml
@@ -95,6 +95,14 @@
+
+
+
+
diff --git a/src/App/Pages/Accounts/EnvironmentPageViewModel.cs b/src/App/Pages/Accounts/EnvironmentPageViewModel.cs
index abac94084..d37b64412 100644
--- a/src/App/Pages/Accounts/EnvironmentPageViewModel.cs
+++ b/src/App/Pages/Accounts/EnvironmentPageViewModel.cs
@@ -1,11 +1,15 @@
using System;
+using System.IO;
using System.Threading.Tasks;
using System.Windows.Input;
using Bit.App.Resources;
using Bit.Core.Abstractions;
using Bit.Core.Models.Data;
using Bit.Core.Utilities;
+using Newtonsoft.Json;
using Xamarin.CommunityToolkit.ObjectModel;
+using Xamarin.Essentials;
+using Xamarin.Forms;
namespace Bit.App.Pages
{
@@ -27,9 +31,13 @@ namespace Bit.App.Pages
IconsUrl = _environmentService.IconsUrl;
NotificationsUrls = _environmentService.NotificationsUrl;
SubmitCommand = new AsyncCommand(SubmitAsync, onException: ex => OnSubmitException(ex), allowsMultipleExecutions: false);
+ LoadFromFileCommand = new AsyncCommand(LoadEnvironmentsFromFile, onException: ex => OnSubmitException(ex), allowsMultipleExecutions: false);
+ ClearCommand = new Command(ClearAllUrls);
}
public ICommand SubmitCommand { get; }
+ public ICommand LoadFromFileCommand { get; }
+ public ICommand ClearCommand { get; }
public string BaseUrl { get; set; }
public string ApiUrl { get; set; }
public string IdentityUrl { get; set; }
@@ -87,5 +95,75 @@ namespace Bit.App.Pages
_logger.Value.Exception(ex);
Page.DisplayAlert(AppResources.AnErrorHasOccurred, AppResources.GenericErrorMessage, AppResources.Ok);
}
+
+ private async Task LoadEnvironmentsFromFile()
+ {
+ try
+ {
+ string jsonString;
+ var result = await FilePicker.PickAsync(new PickOptions
+ {
+ PickerTitle = "This a test to pick files"
+ });
+ if (result != null)
+ {
+ if (result.FileName.EndsWith("json", StringComparison.OrdinalIgnoreCase) ||
+ result.FileName.EndsWith("txt", StringComparison.OrdinalIgnoreCase))
+ {
+ var stream = await result.OpenReadAsync();
+ using (var reader = new System.IO.StreamReader(stream))
+ {
+ jsonString = reader.ReadToEnd();
+ }
+ var envUrls = JsonConvert.DeserializeObject(jsonString);
+ BaseUrl = envUrls.Base;
+ ApiUrl = envUrls.Api;
+ IdentityUrl = envUrls.Identity;
+ WebVaultUrl = envUrls.Vault;
+ IconsUrl = envUrls.Icons;
+ NotificationsUrls = envUrls.Notifications;
+ NotifyUrlsChanged();
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ HandleException(ex);
+ }
+ }
+
+ private void ClearAllUrls()
+ {
+ BaseUrl = string.Empty;
+ ApiUrl = string.Empty;
+ IdentityUrl = string.Empty;
+ WebVaultUrl = string.Empty;
+ IconsUrl = string.Empty;
+ NotificationsUrls = string.Empty;
+ NotifyUrlsChanged();
+ }
+
+ private void NotifyUrlsChanged() {
+ TriggerPropertyChanged(nameof(BaseUrl), new[]
+ {
+ nameof(ApiUrl),
+ nameof(IdentityUrl),
+ nameof(WebVaultUrl),
+ nameof(IconsUrl),
+ nameof(NotificationsUrls)
+ });
+ }
+ }
+
+ public class EnvironmentsData
+ {
+ public string Base { get; set; }
+ public string Admin { get; set; }
+ public string Api { get; set; }
+ public string Identity { get; set; }
+ public string Icons { get; set; }
+ public string Notifications { get; set; }
+ public string Sso { get; set; }
+ public string Vault { get; set; }
}
}
diff --git a/src/App/Resources/AppResources.Designer.cs b/src/App/Resources/AppResources.Designer.cs
index 51a6cfb8c..14f3dfee8 100644
--- a/src/App/Resources/AppResources.Designer.cs
+++ b/src/App/Resources/AppResources.Designer.cs
@@ -3541,6 +3541,15 @@ namespace Bit.App.Resources {
}
}
+ ///
+ /// Looks up a localized string similar to Load from file.
+ ///
+ public static string LoadFromFile {
+ get {
+ return ResourceManager.GetString("LoadFromFile", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Loading.
///
diff --git a/src/App/Resources/AppResources.resx b/src/App/Resources/AppResources.resx
index f4bae0727..1e2d8dff2 100644
--- a/src/App/Resources/AppResources.resx
+++ b/src/App/Resources/AppResources.resx
@@ -2637,4 +2637,7 @@ Do you want to switch to this account?
Unlocking may fail due to insufficient memory. Decrease your KDF memory settings to resolve
+
+ Load from file
+
diff --git a/src/Core/Models/Data/EnvironmentUrlData.cs b/src/Core/Models/Data/EnvironmentUrlData.cs
index ae57f804b..2d302006b 100644
--- a/src/Core/Models/Data/EnvironmentUrlData.cs
+++ b/src/Core/Models/Data/EnvironmentUrlData.cs
@@ -2,8 +2,19 @@
{
public class EnvironmentUrlData
{
- public static EnvironmentUrlData DefaultUS = new EnvironmentUrlData { Base = "https://vault.bitwarden.com" };
- public static EnvironmentUrlData DefaultEU = new EnvironmentUrlData { Base = "https://vault.bitwarden.eu" };
+ public static EnvironmentUrlData DefaultUS = new EnvironmentUrlData
+ {
+ Base = "https://vault.bitwarden.com",
+ Notifications = "https://notifications.bitwarden.com",
+ Icons = "https://icons.bitwarden.com",
+
+ };
+ public static EnvironmentUrlData DefaultEU = new EnvironmentUrlData
+ {
+ Base = "https://vault.bitwarden.eu",
+ Notifications = "https://notifications.bitwarden.eu",
+ Icons = "https://icons.bitwarden.eu",
+ };
public string Base { get; set; }
public string Api { get; set; }