mirror of
https://github.com/bitwarden/mobile
synced 2026-01-05 18:13:36 +00:00
initial commit
This commit is contained in:
88
src/App/Pages/LoginPage.cs
Normal file
88
src/App/Pages/LoginPage.cs
Normal file
@@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection.Emit;
|
||||
using System.Text;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Behaviors;
|
||||
using Bit.App.Models.Api;
|
||||
using Xamarin.Forms;
|
||||
using XLabs.Ioc;
|
||||
|
||||
namespace Bit.App.Views
|
||||
{
|
||||
public class LoginPage : ContentPage
|
||||
{
|
||||
public LoginPage()
|
||||
{
|
||||
var cryptoService = Resolver.Resolve<ICryptoService>();
|
||||
var authService = Resolver.Resolve<IAuthService>();
|
||||
|
||||
var emailEntry = new Entry
|
||||
{
|
||||
Keyboard = Keyboard.Email,
|
||||
Placeholder = "Email Address"
|
||||
};
|
||||
|
||||
emailEntry.Behaviors.Add(new RequiredValidationBehavior());
|
||||
emailEntry.Behaviors.Add(new EmailValidationBehavior());
|
||||
|
||||
var masterPasswordEntry = new Entry
|
||||
{
|
||||
IsPassword = true,
|
||||
Placeholder = "Master Password"
|
||||
};
|
||||
|
||||
masterPasswordEntry.Behaviors.Add(new RequiredValidationBehavior());
|
||||
|
||||
var loginButton = new Button
|
||||
{
|
||||
Text = "Log In",
|
||||
Command = new Command(async () =>
|
||||
{
|
||||
if(string.IsNullOrWhiteSpace(emailEntry.Text))
|
||||
{
|
||||
await DisplayAlert("An error has occurred", "The Email Address field is required.", "Ok");
|
||||
return;
|
||||
}
|
||||
|
||||
if(string.IsNullOrWhiteSpace(masterPasswordEntry.Text))
|
||||
{
|
||||
await DisplayAlert("An error has occurred", "The Master Password field is required.", "Ok");
|
||||
return;
|
||||
}
|
||||
|
||||
var key = cryptoService.MakeKeyFromPassword(masterPasswordEntry.Text, emailEntry.Text);
|
||||
|
||||
var request = new TokenRequest
|
||||
{
|
||||
Email = emailEntry.Text,
|
||||
MasterPasswordHash = cryptoService.HashPasswordBase64(key, masterPasswordEntry.Text)
|
||||
};
|
||||
|
||||
var response = await authService.TokenPostAsync(request);
|
||||
if(!response.Succeeded)
|
||||
{
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
cryptoService.Key = key;
|
||||
authService.Token = response.Result.Token;
|
||||
await Navigation.PushAsync(new VaultListPage());
|
||||
})
|
||||
};
|
||||
|
||||
var stackLayout = new StackLayout
|
||||
{
|
||||
Padding = new Thickness(10, 50, 10, 0)
|
||||
};
|
||||
stackLayout.Children.Add(emailEntry);
|
||||
stackLayout.Children.Add(masterPasswordEntry);
|
||||
stackLayout.Children.Add(loginButton);
|
||||
|
||||
Title = "Log In";
|
||||
Content = stackLayout;
|
||||
NavigationPage.SetHasNavigationBar(this, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
53
src/App/Pages/VaultAddFolderPage.cs
Normal file
53
src/App/Pages/VaultAddFolderPage.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection.Emit;
|
||||
using System.Text;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Models;
|
||||
using Xamarin.Forms;
|
||||
using XLabs.Ioc;
|
||||
|
||||
namespace Bit.App.Views
|
||||
{
|
||||
public class VaultAddFolderPage : ContentPage
|
||||
{
|
||||
public VaultAddFolderPage()
|
||||
{
|
||||
var cryptoService = Resolver.Resolve<ICryptoService>();
|
||||
var folderService = Resolver.Resolve<IFolderService>();
|
||||
|
||||
var nameEntry = new Entry();
|
||||
|
||||
var stackLayout = new StackLayout();
|
||||
stackLayout.Children.Add(new Label { Text = "Name" });
|
||||
stackLayout.Children.Add(nameEntry);
|
||||
|
||||
var scrollView = new ScrollView
|
||||
{
|
||||
Content = stackLayout,
|
||||
Orientation = ScrollOrientation.Vertical
|
||||
};
|
||||
|
||||
var saveToolBarItem = new ToolbarItem("Save", null, async () =>
|
||||
{
|
||||
if(string.IsNullOrWhiteSpace(nameEntry.Text))
|
||||
{
|
||||
await DisplayAlert("An error has occurred", "The Name field is required.", "Ok");
|
||||
return;
|
||||
}
|
||||
|
||||
var folder = new Folder
|
||||
{
|
||||
Name = new CipherString(nameEntry.Text)
|
||||
};
|
||||
await folderService.SaveAsync(folder);
|
||||
await Navigation.PopAsync();
|
||||
}, ToolbarItemOrder.Default, 0);
|
||||
|
||||
Title = "Add Folder";
|
||||
Content = scrollView;
|
||||
ToolbarItems.Add(saveToolBarItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
79
src/App/Pages/VaultAddSitePage.cs
Normal file
79
src/App/Pages/VaultAddSitePage.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection.Emit;
|
||||
using System.Text;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Models;
|
||||
using Xamarin.Forms;
|
||||
using XLabs.Ioc;
|
||||
|
||||
namespace Bit.App.Views
|
||||
{
|
||||
public class VaultAddSitePage : ContentPage
|
||||
{
|
||||
public VaultAddSitePage()
|
||||
{
|
||||
var cryptoService = Resolver.Resolve<ICryptoService>();
|
||||
var siteService = Resolver.Resolve<ISiteService>();
|
||||
|
||||
var uriEntry = new Entry { Keyboard = Keyboard.Url };
|
||||
var nameEntry = new Entry();
|
||||
var folderEntry = new Entry { };
|
||||
var usernameEntry = new Entry();
|
||||
var passwordEntry = new Entry { IsPassword = true };
|
||||
var notesEditor = new Editor();
|
||||
|
||||
var stackLayout = new StackLayout();
|
||||
stackLayout.Children.Add(new Label { Text = "URI" });
|
||||
stackLayout.Children.Add(uriEntry);
|
||||
stackLayout.Children.Add(new Label { Text = "Name" });
|
||||
stackLayout.Children.Add(nameEntry);
|
||||
stackLayout.Children.Add(new Label { Text = "Folder" });
|
||||
stackLayout.Children.Add(folderEntry);
|
||||
stackLayout.Children.Add(new Label { Text = "Username" });
|
||||
stackLayout.Children.Add(usernameEntry);
|
||||
stackLayout.Children.Add(new Label { Text = "Password" });
|
||||
stackLayout.Children.Add(passwordEntry);
|
||||
stackLayout.Children.Add(new Label { Text = "Notes" });
|
||||
stackLayout.Children.Add(notesEditor);
|
||||
|
||||
var scrollView = new ScrollView
|
||||
{
|
||||
Content = stackLayout,
|
||||
Orientation = ScrollOrientation.Vertical
|
||||
};
|
||||
|
||||
var saveToolBarItem = new ToolbarItem("Save", null, async () =>
|
||||
{
|
||||
if(string.IsNullOrWhiteSpace(uriEntry.Text))
|
||||
{
|
||||
await DisplayAlert("An error has occurred", "The Uri field is required.", "Ok");
|
||||
return;
|
||||
}
|
||||
|
||||
if(string.IsNullOrWhiteSpace(nameEntry.Text))
|
||||
{
|
||||
await DisplayAlert("An error has occurred", "The Name field is required.", "Ok");
|
||||
return;
|
||||
}
|
||||
|
||||
var site = new Site
|
||||
{
|
||||
Uri = uriEntry.Text.Encrypt(),
|
||||
Name = nameEntry.Text.Encrypt(),
|
||||
Username = usernameEntry.Text?.Encrypt(),
|
||||
Password = passwordEntry.Text?.Encrypt(),
|
||||
Notes = notesEditor.Text?.Encrypt()
|
||||
};
|
||||
|
||||
await siteService.SaveAsync(site);
|
||||
await Navigation.PopAsync();
|
||||
}, ToolbarItemOrder.Default, 0);
|
||||
|
||||
Title = "Add Site";
|
||||
Content = scrollView;
|
||||
ToolbarItems.Add(saveToolBarItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
19
src/App/Pages/VaultEditFolderPage.cs
Normal file
19
src/App/Pages/VaultEditFolderPage.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection.Emit;
|
||||
using System.Text;
|
||||
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Views
|
||||
{
|
||||
public class VaultEditFolderPage : ContentPage
|
||||
{
|
||||
public VaultEditFolderPage()
|
||||
{
|
||||
Title = "Edit Folder";
|
||||
Content = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
19
src/App/Pages/VaultEditSitePage.cs
Normal file
19
src/App/Pages/VaultEditSitePage.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection.Emit;
|
||||
using System.Text;
|
||||
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Views
|
||||
{
|
||||
public class VaultEditSitePage : ContentPage
|
||||
{
|
||||
public VaultEditSitePage()
|
||||
{
|
||||
Title = "Edit Site";
|
||||
Content = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
74
src/App/Pages/VaultListPage.cs
Normal file
74
src/App/Pages/VaultListPage.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Models.View;
|
||||
using Xamarin.Forms;
|
||||
using XLabs.Ioc;
|
||||
|
||||
namespace Bit.App.Views
|
||||
{
|
||||
public class VaultListPage : ContentPage
|
||||
{
|
||||
private readonly IFolderService _folderService;
|
||||
private readonly ISiteService _siteService;
|
||||
private ListView _listView;
|
||||
|
||||
public VaultListPage()
|
||||
{
|
||||
_folderService = Resolver.Resolve<IFolderService>();
|
||||
_siteService = Resolver.Resolve<ISiteService>();
|
||||
|
||||
var addSiteToolBarItem = new ToolbarItem("+", null, async () =>
|
||||
{
|
||||
var addSitePage = new VaultAddSitePage();
|
||||
await Navigation.PushAsync(addSitePage);
|
||||
}, ToolbarItemOrder.Default, 0);
|
||||
|
||||
ToolbarItems.Add(addSiteToolBarItem);
|
||||
|
||||
_listView = new ListView
|
||||
{
|
||||
IsGroupingEnabled = true,
|
||||
GroupDisplayBinding = new Binding("Name")
|
||||
};
|
||||
|
||||
_listView.ItemSelected += FolderSelected;
|
||||
_listView.ItemTemplate = new DataTemplate(() =>
|
||||
{
|
||||
var cell = new TextCell();
|
||||
cell.SetBinding<VaultView.Site>(TextCell.TextProperty, s => s.Name);
|
||||
cell.SetBinding<VaultView.Site>(TextCell.DetailProperty, s => s.Username);
|
||||
return cell;
|
||||
});
|
||||
|
||||
Title = "My Vault";
|
||||
Content = _listView;
|
||||
NavigationPage.SetHasBackButton(this, false);
|
||||
}
|
||||
|
||||
protected override void OnAppearing()
|
||||
{
|
||||
base.OnAppearing();
|
||||
|
||||
var folders = _folderService.GetAllAsync().GetAwaiter().GetResult();
|
||||
var sites = _siteService.GetAllAsync().GetAwaiter().GetResult();
|
||||
|
||||
var folderItems = folders.Select(f => new VaultView.Folder(f, sites.Where(s => s.FolderId == f.Id))).ToList();
|
||||
// add the sites with no folder
|
||||
folderItems.Add(new VaultView.Folder(sites.Where(s => !s.FolderId.HasValue)));
|
||||
_listView.ItemsSource = folderItems;
|
||||
}
|
||||
|
||||
void FolderSelected(object sender, SelectedItemChangedEventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SiteSelected(object sender, SelectedItemChangedEventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
23
src/App/Pages/VaultViewSitePage.cs
Normal file
23
src/App/Pages/VaultViewSitePage.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection.Emit;
|
||||
using System.Text;
|
||||
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Views
|
||||
{
|
||||
public class VaultViewSitePage : ContentPage
|
||||
{
|
||||
private int _siteId;
|
||||
|
||||
public VaultViewSitePage(int siteId)
|
||||
{
|
||||
_siteId = siteId;
|
||||
|
||||
Title = "View Site";
|
||||
Content = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user