1
0
Fork 0
mirror of https://github.com/bitwarden/android.git synced 2024-12-23 01:20:31 +03:00

Converted auth to identity server endpoints and utilize bearer2 access token

This commit is contained in:
Kyle Spearrin 2017-02-04 01:12:25 -05:00
parent 46bb8d2cb5
commit 4a4779fc63
17 changed files with 916 additions and 245 deletions

View file

@ -210,12 +210,13 @@ namespace Bit.Android
.RegisterType<ILocalizeService, LocalizeService>(new ContainerControlledLifetimeManager()) .RegisterType<ILocalizeService, LocalizeService>(new ContainerControlledLifetimeManager())
.RegisterType<ILogService, LogService>(new ContainerControlledLifetimeManager()) .RegisterType<ILogService, LogService>(new ContainerControlledLifetimeManager())
.RegisterType<IHttpService, HttpService>(new ContainerControlledLifetimeManager()) .RegisterType<IHttpService, HttpService>(new ContainerControlledLifetimeManager())
.RegisterType<ITokenService, TokenService>(new ContainerControlledLifetimeManager())
// Repositories // Repositories
.RegisterType<IFolderRepository, FolderRepository>(new ContainerControlledLifetimeManager()) .RegisterType<IFolderRepository, FolderRepository>(new ContainerControlledLifetimeManager())
.RegisterType<IFolderApiRepository, FolderApiRepository>(new ContainerControlledLifetimeManager()) .RegisterType<IFolderApiRepository, FolderApiRepository>(new ContainerControlledLifetimeManager())
.RegisterType<ILoginRepository, LoginRepository>(new ContainerControlledLifetimeManager()) .RegisterType<ILoginRepository, LoginRepository>(new ContainerControlledLifetimeManager())
.RegisterType<ILoginApiRepository, LoginApiRepository>(new ContainerControlledLifetimeManager()) .RegisterType<ILoginApiRepository, LoginApiRepository>(new ContainerControlledLifetimeManager())
.RegisterType<IAuthApiRepository, AuthApiRepository>(new ContainerControlledLifetimeManager()) .RegisterType<IConnectApiRepository, ConnectApiRepository>(new ContainerControlledLifetimeManager())
.RegisterType<IDeviceApiRepository, DeviceApiRepository>(new ContainerControlledLifetimeManager()) .RegisterType<IDeviceApiRepository, DeviceApiRepository>(new ContainerControlledLifetimeManager())
.RegisterType<IAccountsApiRepository, AccountsApiRepository>(new ContainerControlledLifetimeManager()) .RegisterType<IAccountsApiRepository, AccountsApiRepository>(new ContainerControlledLifetimeManager())
.RegisterType<ICipherApiRepository, CipherApiRepository>(new ContainerControlledLifetimeManager()) .RegisterType<ICipherApiRepository, CipherApiRepository>(new ContainerControlledLifetimeManager())

View file

@ -3,9 +3,8 @@ using Bit.App.Models.Api;
namespace Bit.App.Abstractions namespace Bit.App.Abstractions
{ {
public interface IAuthApiRepository public interface IConnectApiRepository
{ {
Task<ApiResult<TokenResponse>> PostTokenAsync(TokenRequest requestObj); Task<ApiResult<TokenResponse>> PostTokenAsync(TokenRequest requestObj);
Task<ApiResult<TokenResponse>> PostTokenTwoFactorAsync(TokenTwoFactorRequest requestObj);
} }
} }

View file

@ -1,13 +1,12 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using Bit.App.Models.Api; using Bit.App.Models.Api;
using System;
namespace Bit.App.Abstractions namespace Bit.App.Abstractions
{ {
public interface IAuthService public interface IAuthService
{ {
bool IsAuthenticated { get; } bool IsAuthenticated { get; }
bool IsAuthenticatedTwoFactor { get; }
string Token { get; set; }
string UserId { get; set; } string UserId { get; set; }
string PreviousUserId { get; } string PreviousUserId { get; }
bool UserIdChanged { get; } bool UserIdChanged { get; }
@ -16,6 +15,5 @@ namespace Bit.App.Abstractions
void LogOut(); void LogOut();
Task<ApiResult<TokenResponse>> TokenPostAsync(TokenRequest request); Task<ApiResult<TokenResponse>> TokenPostAsync(TokenRequest request);
Task<ApiResult<TokenResponse>> TokenTwoFactorPostAsync(TokenTwoFactorRequest request);
} }
} }

View file

@ -0,0 +1,19 @@
using System;
namespace Bit.App.Abstractions
{
public interface ITokenService
{
string Token { get; set; }
string RefreshToken { get; set; }
[Obsolete("Old auth scheme")]
string AuthBearer { get; set; }
DateTime TokenExpiration { get; }
bool TokenExpired { get; }
TimeSpan TokenTimeRemaining { get; }
bool TokenNeedseRefresh { get; }
string TokenUserId { get; }
string TokenEmail { get; }
string TokenName { get; }
}
}

View file

@ -37,6 +37,7 @@
<ItemGroup> <ItemGroup>
<Compile Include="Abstractions\Repositories\IAccountsApiRepository.cs" /> <Compile Include="Abstractions\Repositories\IAccountsApiRepository.cs" />
<Compile Include="Abstractions\Repositories\IDeviceApiRepository.cs" /> <Compile Include="Abstractions\Repositories\IDeviceApiRepository.cs" />
<Compile Include="Abstractions\Services\ITokenService.cs" />
<Compile Include="Abstractions\Services\IHttpService.cs" /> <Compile Include="Abstractions\Services\IHttpService.cs" />
<Compile Include="Abstractions\Services\IDeviceInfoService.cs" /> <Compile Include="Abstractions\Services\IDeviceInfoService.cs" />
<Compile Include="Abstractions\Services\IGoogleAnalyticsService.cs" /> <Compile Include="Abstractions\Services\IGoogleAnalyticsService.cs" />
@ -88,7 +89,6 @@
<Compile Include="Models\Api\Request\LoginRequest.cs" /> <Compile Include="Models\Api\Request\LoginRequest.cs" />
<Compile Include="Models\Api\Request\PasswordHintRequest.cs" /> <Compile Include="Models\Api\Request\PasswordHintRequest.cs" />
<Compile Include="Models\Api\Request\TokenRequest.cs" /> <Compile Include="Models\Api\Request\TokenRequest.cs" />
<Compile Include="Models\Api\Request\TokenTwoFactorRequest.cs" />
<Compile Include="Models\Api\Response\CipherHistoryResponse.cs" /> <Compile Include="Models\Api\Response\CipherHistoryResponse.cs" />
<Compile Include="Models\Api\Response\CipherResponse.cs" /> <Compile Include="Models\Api\Response\CipherResponse.cs" />
<Compile Include="Models\Api\Response\ErrorResponse.cs" /> <Compile Include="Models\Api\Response\ErrorResponse.cs" />
@ -140,12 +140,12 @@
<Compile Include="Abstractions\Repositories\ILoginRepository.cs" /> <Compile Include="Abstractions\Repositories\ILoginRepository.cs" />
<Compile Include="Repositories\ApiRepository.cs" /> <Compile Include="Repositories\ApiRepository.cs" />
<Compile Include="Repositories\AccountsApiRepository.cs" /> <Compile Include="Repositories\AccountsApiRepository.cs" />
<Compile Include="Repositories\ConnectApiRepository.cs" />
<Compile Include="Repositories\BaseApiRepository.cs" /> <Compile Include="Repositories\BaseApiRepository.cs" />
<Compile Include="Abstractions\Repositories\IApiRepository.cs" /> <Compile Include="Abstractions\Repositories\IApiRepository.cs" />
<Compile Include="Abstractions\Repositories\IFolderApiRepository.cs" /> <Compile Include="Abstractions\Repositories\IFolderApiRepository.cs" />
<Compile Include="Abstractions\Repositories\ILoginApiRepository.cs" /> <Compile Include="Abstractions\Repositories\ILoginApiRepository.cs" />
<Compile Include="Repositories\AuthApiRepository.cs" /> <Compile Include="Abstractions\Repositories\IConnectApiRepository.cs" />
<Compile Include="Abstractions\Repositories\IAuthApiRepository.cs" />
<Compile Include="Repositories\DeviceApiRepository.cs" /> <Compile Include="Repositories\DeviceApiRepository.cs" />
<Compile Include="Repositories\CipherApiRepository.cs" /> <Compile Include="Repositories\CipherApiRepository.cs" />
<Compile Include="Abstractions\Repositories\ICipherApiRepository.cs" /> <Compile Include="Abstractions\Repositories\ICipherApiRepository.cs" />
@ -180,6 +180,7 @@
<DesignTime>True</DesignTime> <DesignTime>True</DesignTime>
<DependentUpon>AppResources.zh-Hans.resx</DependentUpon> <DependentUpon>AppResources.zh-Hans.resx</DependentUpon>
</Compile> </Compile>
<Compile Include="Services\TokenService.cs" />
<Compile Include="Services\AppIdService.cs" /> <Compile Include="Services\AppIdService.cs" />
<Compile Include="Abstractions\Services\ILockService.cs" /> <Compile Include="Abstractions\Services\ILockService.cs" />
<Compile Include="Services\LockService.cs" /> <Compile Include="Services\LockService.cs" />

View file

@ -1,9 +1,41 @@
namespace Bit.App.Models.Api using System.Collections.Generic;
namespace Bit.App.Models.Api
{ {
public class TokenRequest public class TokenRequest
{ {
public string Email { get; set; } public string Email { get; set; }
public string MasterPasswordHash { get; set; } public string MasterPasswordHash { get; set; }
public string Token { get; set; }
public int? Provider { get; set; }
public DeviceRequest Device { get; set; } public DeviceRequest Device { get; set; }
public IDictionary<string, string> ToIdentityTokenRequest()
{
var dict = new Dictionary<string, string>
{
{ "grant_type", "password" },
{ "username", Email },
{ "password", MasterPasswordHash },
{ "scope", "api offline_access" },
{ "client_id", "mobile" }
};
if(Device != null)
{
dict.Add("DeviceType", Device.Type.ToString());
dict.Add("DeviceIdentifier", Device.Identifier);
dict.Add("DeviceName", Device.Name);
dict.Add("DevicePushToken", Device.PushToken);
}
if(Token != null && Provider.HasValue)
{
dict.Add("TwoFactorToken", Token);
dict.Add("TwoFactorProvider", Provider.Value.ToString());
}
return dict;
}
} }
} }

View file

@ -1,9 +0,0 @@
namespace Bit.App.Models.Api
{
public class TokenTwoFactorRequest
{
public string Code { get; set; }
public string Provider { get; set; }
public DeviceRequest Device { get; set; }
}
}

View file

@ -1,8 +1,16 @@
namespace Bit.App.Models.Api using Newtonsoft.Json;
namespace Bit.App.Models.Api
{ {
public class TokenResponse public class TokenResponse
{ {
public string Token { get; set; } [JsonProperty("access_token")]
public ProfileResponse Profile { get; set; } public string AccessToken { get; set; }
[JsonProperty("expires_in")]
public long ExpiresIn { get; set; }
[JsonProperty("refresh_token")]
public string RefreshToken { get; set; }
[JsonProperty("token_type")]
public string TokenType { get; set; }
} }
} }

View file

@ -17,6 +17,7 @@ namespace Bit.App.Pages
{ {
private ICryptoService _cryptoService; private ICryptoService _cryptoService;
private IAuthService _authService; private IAuthService _authService;
private ITokenService _tokenService;
private IDeviceInfoService _deviceInfoService; private IDeviceInfoService _deviceInfoService;
private IAppIdService _appIdService; private IAppIdService _appIdService;
private IUserDialogs _userDialogs; private IUserDialogs _userDialogs;
@ -32,6 +33,7 @@ namespace Bit.App.Pages
_email = email; _email = email;
_cryptoService = Resolver.Resolve<ICryptoService>(); _cryptoService = Resolver.Resolve<ICryptoService>();
_authService = Resolver.Resolve<IAuthService>(); _authService = Resolver.Resolve<IAuthService>();
_tokenService = Resolver.Resolve<ITokenService>();
_deviceInfoService = Resolver.Resolve<IDeviceInfoService>(); _deviceInfoService = Resolver.Resolve<IDeviceInfoService>();
_appIdService = Resolver.Resolve<IAppIdService>(); _appIdService = Resolver.Resolve<IAppIdService>();
_userDialogs = Resolver.Resolve<IUserDialogs>(); _userDialogs = Resolver.Resolve<IUserDialogs>();
@ -196,9 +198,10 @@ namespace Bit.App.Pages
} }
_cryptoService.Key = key; _cryptoService.Key = key;
_authService.Token = response.Result.Token; _tokenService.Token = response.Result.AccessToken;
_authService.UserId = response.Result?.Profile?.Id; _tokenService.RefreshToken = response.Result.RefreshToken;
_authService.Email = response.Result?.Profile?.Email; _authService.UserId = _tokenService.TokenUserId;
_authService.Email = _tokenService.TokenEmail;
_settings.AddOrUpdateValue(Constants.LastLoginEmail, _authService.Email); _settings.AddOrUpdateValue(Constants.LastLoginEmail, _authService.Email);
_googleAnalyticsService.RefreshUserId(); _googleAnalyticsService.RefreshUserId();
_googleAnalyticsService.TrackAppEvent("LoggedIn"); _googleAnalyticsService.TrackAppEvent("LoggedIn");
@ -208,7 +211,7 @@ namespace Bit.App.Pages
_pushNotification.Register(); _pushNotification.Register();
} }
if(_authService.IsAuthenticatedTwoFactor) if(false) // TODO: 2FA
{ {
await Navigation.PushAsync(new LoginTwoFactorPage()); await Navigation.PushAsync(new LoginTwoFactorPage());
} }

View file

@ -15,6 +15,7 @@ namespace Bit.App.Pages
{ {
private ICryptoService _cryptoService; private ICryptoService _cryptoService;
private IAuthService _authService; private IAuthService _authService;
private ITokenService _tokenService;
private IDeviceInfoService _deviceInfoService; private IDeviceInfoService _deviceInfoService;
private IAppIdService _appIdService; private IAppIdService _appIdService;
private IUserDialogs _userDialogs; private IUserDialogs _userDialogs;
@ -25,6 +26,7 @@ namespace Bit.App.Pages
{ {
_cryptoService = Resolver.Resolve<ICryptoService>(); _cryptoService = Resolver.Resolve<ICryptoService>();
_authService = Resolver.Resolve<IAuthService>(); _authService = Resolver.Resolve<IAuthService>();
_tokenService = Resolver.Resolve<ITokenService>();
_deviceInfoService = Resolver.Resolve<IDeviceInfoService>(); _deviceInfoService = Resolver.Resolve<IDeviceInfoService>();
_appIdService = Resolver.Resolve<IAppIdService>(); _appIdService = Resolver.Resolve<IAppIdService>();
_userDialogs = Resolver.Resolve<IUserDialogs>(); _userDialogs = Resolver.Resolve<IUserDialogs>();
@ -134,15 +136,16 @@ namespace Bit.App.Pages
return; return;
} }
var request = new TokenTwoFactorRequest var request = new TokenRequest
{ {
Code = CodeCell.Entry.Text.Replace(" ", ""), // TODO: username and pass from previous page
Provider = "Authenticator", Token = CodeCell.Entry.Text.Replace(" ", ""),
Provider = 0,
Device = new DeviceRequest(_appIdService, _deviceInfoService) Device = new DeviceRequest(_appIdService, _deviceInfoService)
}; };
_userDialogs.ShowLoading(AppResources.ValidatingCode, MaskType.Black); _userDialogs.ShowLoading(AppResources.ValidatingCode, MaskType.Black);
var response = await _authService.TokenTwoFactorPostAsync(request); var response = await _authService.TokenPostAsync(request);
_userDialogs.HideLoading(); _userDialogs.HideLoading();
if(!response.Succeeded) if(!response.Succeeded)
{ {
@ -150,9 +153,10 @@ namespace Bit.App.Pages
return; return;
} }
_authService.Token = response.Result.Token; _tokenService.Token = response.Result.AccessToken;
_authService.UserId = response.Result.Profile.Id; _tokenService.RefreshToken = response.Result.RefreshToken;
_authService.Email = response.Result.Profile.Email; _authService.UserId = _tokenService.TokenUserId;
_authService.Email = _tokenService.TokenEmail;
var task = Task.Run(async () => await _syncService.FullSyncAsync()); var task = Task.Run(async () => await _syncService.FullSyncAsync());
Application.Current.MainPage = new MainPage(); Application.Current.MainPage = new MainPage();

View file

@ -9,15 +9,15 @@ using System.Net;
namespace Bit.App.Repositories namespace Bit.App.Repositories
{ {
public class AuthApiRepository : BaseApiRepository, IAuthApiRepository public class ConnectApiRepository : BaseApiRepository, IConnectApiRepository
{ {
public AuthApiRepository( public ConnectApiRepository(
IConnectivity connectivity, IConnectivity connectivity,
IHttpService httpService) IHttpService httpService)
: base(connectivity, httpService) : base(connectivity, httpService)
{ } { }
protected override string ApiRoute => "auth"; protected override string ApiRoute => "connect";
public virtual async Task<ApiResult<TokenResponse>> PostTokenAsync(TokenRequest requestObj) public virtual async Task<ApiResult<TokenResponse>> PostTokenAsync(TokenRequest requestObj)
{ {
@ -28,44 +28,11 @@ namespace Bit.App.Repositories
using(var client = HttpService.Client) using(var client = HttpService.Client)
{ {
var requestMessage = new TokenHttpRequestMessage(requestObj) var requestMessage = new HttpRequestMessage
{ {
Method = HttpMethod.Post, Method = HttpMethod.Post,
RequestUri = new Uri(client.BaseAddress, string.Concat(ApiRoute, "/token")), RequestUri = new Uri(client.BaseAddress, string.Concat(ApiRoute, "/token")),
}; Content = new FormUrlEncodedContent(requestObj.ToIdentityTokenRequest())
try
{
var response = await client.SendAsync(requestMessage).ConfigureAwait(false);
if(!response.IsSuccessStatusCode)
{
return await HandleErrorAsync<TokenResponse>(response).ConfigureAwait(false);
}
var responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
var responseObj = JsonConvert.DeserializeObject<TokenResponse>(responseContent);
return ApiResult<TokenResponse>.Success(responseObj, response.StatusCode);
}
catch(WebException e)
{
return HandledWebException<TokenResponse>();
}
}
}
public virtual async Task<ApiResult<TokenResponse>> PostTokenTwoFactorAsync(TokenTwoFactorRequest requestObj)
{
if(!Connectivity.IsConnected)
{
return HandledNotConnected<TokenResponse>();
}
using(var client = HttpService.Client)
{
var requestMessage = new TokenHttpRequestMessage(requestObj)
{
Method = HttpMethod.Post,
RequestUri = new Uri(client.BaseAddress, string.Concat(ApiRoute, "/token/two-factor")),
}; };
try try

View file

@ -9,18 +9,17 @@ namespace Bit.App.Services
{ {
public class AuthService : IAuthService public class AuthService : IAuthService
{ {
private const string TokenKey = "token";
private const string EmailKey = "email"; private const string EmailKey = "email";
private const string UserIdKey = "userId"; private const string UserIdKey = "userId";
private const string PreviousUserIdKey = "previousUserId"; private const string PreviousUserIdKey = "previousUserId";
private const string PinKey = "pin"; private const string PinKey = "pin";
private readonly ISecureStorageService _secureStorage; private readonly ISecureStorageService _secureStorage;
private readonly ITokenService _tokenService;
private readonly ISettings _settings; private readonly ISettings _settings;
private readonly ICryptoService _cryptoService; private readonly ICryptoService _cryptoService;
private readonly IAuthApiRepository _authApiRepository; private readonly IConnectApiRepository _connectApiRepository;
private string _token;
private string _email; private string _email;
private string _userId; private string _userId;
private string _previousUserId; private string _previousUserId;
@ -28,48 +27,16 @@ namespace Bit.App.Services
public AuthService( public AuthService(
ISecureStorageService secureStorage, ISecureStorageService secureStorage,
ITokenService tokenService,
ISettings settings, ISettings settings,
ICryptoService cryptoService, ICryptoService cryptoService,
IAuthApiRepository authApiRepository) IConnectApiRepository connectApiRepository)
{ {
_secureStorage = secureStorage; _secureStorage = secureStorage;
_tokenService = tokenService;
_settings = settings; _settings = settings;
_cryptoService = cryptoService; _cryptoService = cryptoService;
_authApiRepository = authApiRepository; _connectApiRepository = connectApiRepository;
}
public string Token
{
get
{
if(_token != null)
{
return _token;
}
var tokenBytes = _secureStorage.Retrieve(TokenKey);
if(tokenBytes == null)
{
return null;
}
_token = Encoding.UTF8.GetString(tokenBytes, 0, tokenBytes.Length);
return _token;
}
set
{
if(value != null)
{
var tokenBytes = Encoding.UTF8.GetBytes(value);
_secureStorage.Store(TokenKey, tokenBytes);
}
else
{
_secureStorage.Delete(TokenKey);
}
_token = value;
}
} }
public string UserId public string UserId
@ -170,14 +137,8 @@ namespace Bit.App.Services
{ {
get get
{ {
return _cryptoService.Key != null && !string.IsNullOrWhiteSpace(Token) && !string.IsNullOrWhiteSpace(UserId); return _cryptoService.Key != null && !string.IsNullOrWhiteSpace(_tokenService.Token) &&
} !string.IsNullOrWhiteSpace(UserId);
}
public bool IsAuthenticatedTwoFactor
{
get
{
return _cryptoService.Key != null && !string.IsNullOrWhiteSpace(Token) && string.IsNullOrWhiteSpace(UserId);
} }
} }
@ -217,7 +178,9 @@ namespace Bit.App.Services
public void LogOut() public void LogOut()
{ {
Token = null; _tokenService.Token = null;
_tokenService.RefreshToken = null;
_tokenService.AuthBearer = null;
UserId = null; UserId = null;
Email = null; Email = null;
_cryptoService.Key = null; _cryptoService.Key = null;
@ -227,13 +190,7 @@ namespace Bit.App.Services
public async Task<ApiResult<TokenResponse>> TokenPostAsync(TokenRequest request) public async Task<ApiResult<TokenResponse>> TokenPostAsync(TokenRequest request)
{ {
// TODO: move more logic in here // TODO: move more logic in here
return await _authApiRepository.PostTokenAsync(request); return await _connectApiRepository.PostTokenAsync(request);
}
public async Task<ApiResult<TokenResponse>> TokenTwoFactorPostAsync(TokenTwoFactorRequest request)
{
// TODO: move more logic in here
return await _authApiRepository.PostTokenTwoFactorAsync(request);
} }
} }
} }

View file

@ -0,0 +1,210 @@
using System;
using Bit.App.Abstractions;
using System.Text;
using Newtonsoft.Json;
namespace Bit.App.Services
{
public class TokenService : ITokenService
{
private const string TokenKey = "accessToken";
private const string RefreshTokenKey = "refreshToken";
private const string AuthBearerKey = "token";
private readonly ISecureStorageService _secureStorage;
private string _token;
private dynamic _decodedToken;
private string _refreshToken;
private string _authBearer;
private static readonly DateTime _epoc = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public TokenService(ISecureStorageService secureStorage)
{
_secureStorage = secureStorage;
}
public string Token
{
get
{
if(_token != null)
{
return _token;
}
var tokenBytes = _secureStorage.Retrieve(TokenKey);
if(tokenBytes == null)
{
return null;
}
_token = Encoding.UTF8.GetString(tokenBytes, 0, tokenBytes.Length);
return _token;
}
set
{
if(value != null)
{
var tokenBytes = Encoding.UTF8.GetBytes(value);
_secureStorage.Store(TokenKey, tokenBytes);
}
else
{
_secureStorage.Delete(TokenKey);
RefreshToken = null;
AuthBearer = null;
}
_decodedToken = null;
_token = value;
}
}
public DateTime TokenExpiration
{
get
{
var decoded = DecodeToken();
long exp = 0;
if(decoded?.exp != null || !long.TryParse(decoded.exp, out exp))
{
throw new InvalidOperationException("No exp in token.");
}
return _epoc.AddSeconds(Convert.ToDouble(exp));
}
}
public bool TokenExpired => DateTime.UtcNow < TokenExpiration;
public TimeSpan TokenTimeRemaining => TokenExpiration - DateTime.UtcNow;
public bool TokenNeedseRefresh => TokenTimeRemaining.TotalMinutes < 5;
public string TokenUserId => DecodeToken()?.sub;
public string TokenEmail => DecodeToken()?.email;
public string TokenName => DecodeToken()?.name;
public string RefreshToken
{
get
{
if(_refreshToken != null)
{
return _refreshToken;
}
var tokenBytes = _secureStorage.Retrieve(RefreshTokenKey);
if(tokenBytes == null)
{
return null;
}
_refreshToken = Encoding.UTF8.GetString(tokenBytes, 0, tokenBytes.Length);
return _refreshToken;
}
set
{
if(value != null)
{
var tokenBytes = Encoding.UTF8.GetBytes(value);
_secureStorage.Store(RefreshTokenKey, tokenBytes);
}
else
{
_secureStorage.Delete(RefreshTokenKey);
}
_refreshToken = value;
}
}
public string AuthBearer
{
get
{
if(_authBearer != null)
{
return _authBearer;
}
var tokenBytes = _secureStorage.Retrieve(AuthBearerKey);
if(tokenBytes == null)
{
return null;
}
_authBearer = Encoding.UTF8.GetString(tokenBytes, 0, tokenBytes.Length);
return _authBearer;
}
set
{
if(value != null)
{
var tokenBytes = Encoding.UTF8.GetBytes(value);
_secureStorage.Store(AuthBearerKey, tokenBytes);
}
else
{
_secureStorage.Delete(AuthBearerKey);
}
_authBearer = value;
}
}
public dynamic DecodeToken()
{
if(_decodedToken != null)
{
return _decodedToken;
}
if(Token == null)
{
throw new InvalidOperationException($"{nameof(Token)} not found.");
}
var parts = Token.Split('.');
if(parts.Length != 3)
{
throw new InvalidOperationException($"{nameof(Token)} must have 3 parts");
}
var decodedBytes = Base64UrlDecode(parts[1]);
if(decodedBytes == null || decodedBytes.Length < 1)
{
throw new InvalidOperationException($"{nameof(Token)} must have 3 parts");
}
_decodedToken = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(decodedBytes, 0, decodedBytes.Length));
return _decodedToken;
}
private static byte[] Base64UrlDecode(string input)
{
var output = input;
// 62nd char of encoding
output = output.Replace('-', '+');
// 63rd char of encoding
output = output.Replace('_', '/');
// Pad with trailing '='s
switch(output.Length % 4)
{
case 0:
// No pad chars in this case
break;
case 2:
// Two pad chars
output += "=="; break;
case 3:
// One pad char
output += "="; break;
default:
throw new InvalidOperationException("Illegal base64url string!");
}
// Standard base64 decoder
return Convert.FromBase64String(output);
}
}
}

View file

@ -10,11 +10,11 @@ namespace Bit.App
{ {
public TokenHttpRequestMessage() public TokenHttpRequestMessage()
{ {
var authService = Resolver.Resolve<IAuthService>(); var tokenService = Resolver.Resolve<ITokenService>();
var appIdService = Resolver.Resolve<IAppIdService>(); var appIdService = Resolver.Resolve<IAppIdService>();
if(!string.IsNullOrWhiteSpace(authService.Token)) if(!string.IsNullOrWhiteSpace(tokenService.Token))
{ {
Headers.Add("Authorization", $"Bearer {authService.Token}"); Headers.Add("Authorization", $"Bearer2 {tokenService.Token}");
} }
if(!string.IsNullOrWhiteSpace(appIdService.AppId)) if(!string.IsNullOrWhiteSpace(appIdService.AppId))
{ {

View file

@ -280,12 +280,13 @@ namespace Bit.iOS.Extension
.RegisterType<ILocalizeService, LocalizeService>(new ContainerControlledLifetimeManager()) .RegisterType<ILocalizeService, LocalizeService>(new ContainerControlledLifetimeManager())
.RegisterType<ILogService, LogService>(new ContainerControlledLifetimeManager()) .RegisterType<ILogService, LogService>(new ContainerControlledLifetimeManager())
.RegisterType<IHttpService, HttpService>(new ContainerControlledLifetimeManager()) .RegisterType<IHttpService, HttpService>(new ContainerControlledLifetimeManager())
.RegisterType<ITokenService, TokenService>(new ContainerControlledLifetimeManager())
// Repositories // Repositories
.RegisterType<IFolderRepository, FolderRepository>(new ContainerControlledLifetimeManager()) .RegisterType<IFolderRepository, FolderRepository>(new ContainerControlledLifetimeManager())
.RegisterType<IFolderApiRepository, FolderApiRepository>(new ContainerControlledLifetimeManager()) .RegisterType<IFolderApiRepository, FolderApiRepository>(new ContainerControlledLifetimeManager())
.RegisterType<ILoginRepository, LoginRepository>(new ContainerControlledLifetimeManager()) .RegisterType<ILoginRepository, LoginRepository>(new ContainerControlledLifetimeManager())
.RegisterType<ILoginApiRepository, LoginApiRepository>(new ContainerControlledLifetimeManager()) .RegisterType<ILoginApiRepository, LoginApiRepository>(new ContainerControlledLifetimeManager())
.RegisterType<IAuthApiRepository, AuthApiRepository>(new ContainerControlledLifetimeManager()) .RegisterType<IConnectApiRepository, ConnectApiRepository>(new ContainerControlledLifetimeManager())
// Other // Other
.RegisterInstance(CrossConnectivity.Current, new ContainerControlledLifetimeManager()) .RegisterInstance(CrossConnectivity.Current, new ContainerControlledLifetimeManager())
.RegisterInstance(CrossFingerprint.Current, new ContainerControlledLifetimeManager()); .RegisterInstance(CrossFingerprint.Current, new ContainerControlledLifetimeManager());

View file

@ -264,13 +264,14 @@ namespace Bit.iOS
.RegisterType<ILocalizeService, LocalizeService>(new ContainerControlledLifetimeManager()) .RegisterType<ILocalizeService, LocalizeService>(new ContainerControlledLifetimeManager())
.RegisterType<ILogService, LogService>(new ContainerControlledLifetimeManager()) .RegisterType<ILogService, LogService>(new ContainerControlledLifetimeManager())
.RegisterType<IHttpService, HttpService>(new ContainerControlledLifetimeManager()) .RegisterType<IHttpService, HttpService>(new ContainerControlledLifetimeManager())
.RegisterType<ITokenService, TokenService>(new ContainerControlledLifetimeManager())
// Repositories // Repositories
// Repositories // Repositories
.RegisterType<IFolderRepository, FolderRepository>(new ContainerControlledLifetimeManager()) .RegisterType<IFolderRepository, FolderRepository>(new ContainerControlledLifetimeManager())
.RegisterType<IFolderApiRepository, FolderApiRepository>(new ContainerControlledLifetimeManager()) .RegisterType<IFolderApiRepository, FolderApiRepository>(new ContainerControlledLifetimeManager())
.RegisterType<ILoginRepository, LoginRepository>(new ContainerControlledLifetimeManager()) .RegisterType<ILoginRepository, LoginRepository>(new ContainerControlledLifetimeManager())
.RegisterType<ILoginApiRepository, LoginApiRepository>(new ContainerControlledLifetimeManager()) .RegisterType<ILoginApiRepository, LoginApiRepository>(new ContainerControlledLifetimeManager())
.RegisterType<IAuthApiRepository, AuthApiRepository>(new ContainerControlledLifetimeManager()) .RegisterType<IConnectApiRepository, ConnectApiRepository>(new ContainerControlledLifetimeManager())
.RegisterType<IDeviceApiRepository, DeviceApiRepository>(new ContainerControlledLifetimeManager()) .RegisterType<IDeviceApiRepository, DeviceApiRepository>(new ContainerControlledLifetimeManager())
.RegisterType<IAccountsApiRepository, AccountsApiRepository>(new ContainerControlledLifetimeManager()) .RegisterType<IAccountsApiRepository, AccountsApiRepository>(new ContainerControlledLifetimeManager())
.RegisterType<ICipherApiRepository, CipherApiRepository>(new ContainerControlledLifetimeManager()) .RegisterType<ICipherApiRepository, CipherApiRepository>(new ContainerControlledLifetimeManager())

View file

@ -222,6 +222,42 @@ namespace Bit.Android.Test
// aapt resource value: 0x7f0100b4 // aapt resource value: 0x7f0100b4
public const int activityChooserViewStyle = 2130772148; public const int activityChooserViewStyle = 2130772148;
// aapt resource value: 0x7f01012b
public const int ahBarColor = 2130772267;
// aapt resource value: 0x7f010133
public const int ahBarLength = 2130772275;
// aapt resource value: 0x7f010132
public const int ahBarWidth = 2130772274;
// aapt resource value: 0x7f010130
public const int ahCircleColor = 2130772272;
// aapt resource value: 0x7f01012f
public const int ahDelayMillis = 2130772271;
// aapt resource value: 0x7f010131
public const int ahRadius = 2130772273;
// aapt resource value: 0x7f01012c
public const int ahRimColor = 2130772268;
// aapt resource value: 0x7f01012d
public const int ahRimWidth = 2130772269;
// aapt resource value: 0x7f01012e
public const int ahSpinSpeed = 2130772270;
// aapt resource value: 0x7f010128
public const int ahText = 2130772264;
// aapt resource value: 0x7f010129
public const int ahTextColor = 2130772265;
// aapt resource value: 0x7f01012a
public const int ahTextSize = 2130772266;
// aapt resource value: 0x7f0100d7 // aapt resource value: 0x7f0100d7
public const int alertDialogButtonGroupStyle = 2130772183; public const int alertDialogButtonGroupStyle = 2130772183;
@ -1058,32 +1094,32 @@ namespace Bit.Android.Test
public partial class Color public partial class Color
{ {
// aapt resource value: 0x7f0c0048 // aapt resource value: 0x7f0c0052
public const int abc_background_cache_hint_selector_material_dark = 2131492936; public const int abc_background_cache_hint_selector_material_dark = 2131492946;
// aapt resource value: 0x7f0c0049 // aapt resource value: 0x7f0c0053
public const int abc_background_cache_hint_selector_material_light = 2131492937; public const int abc_background_cache_hint_selector_material_light = 2131492947;
// aapt resource value: 0x7f0c004a // aapt resource value: 0x7f0c0054
public const int abc_color_highlight_material = 2131492938; public const int abc_color_highlight_material = 2131492948;
// aapt resource value: 0x7f0c000e // aapt resource value: 0x7f0c000e
public const int abc_input_method_navigation_guard = 2131492878; public const int abc_input_method_navigation_guard = 2131492878;
// aapt resource value: 0x7f0c004b // aapt resource value: 0x7f0c0055
public const int abc_primary_text_disable_only_material_dark = 2131492939; public const int abc_primary_text_disable_only_material_dark = 2131492949;
// aapt resource value: 0x7f0c004c // aapt resource value: 0x7f0c0056
public const int abc_primary_text_disable_only_material_light = 2131492940; public const int abc_primary_text_disable_only_material_light = 2131492950;
// aapt resource value: 0x7f0c004d // aapt resource value: 0x7f0c0057
public const int abc_primary_text_material_dark = 2131492941; public const int abc_primary_text_material_dark = 2131492951;
// aapt resource value: 0x7f0c004e // aapt resource value: 0x7f0c0058
public const int abc_primary_text_material_light = 2131492942; public const int abc_primary_text_material_light = 2131492952;
// aapt resource value: 0x7f0c004f // aapt resource value: 0x7f0c0059
public const int abc_search_url_text = 2131492943; public const int abc_search_url_text = 2131492953;
// aapt resource value: 0x7f0c000f // aapt resource value: 0x7f0c000f
public const int abc_search_url_text_normal = 2131492879; public const int abc_search_url_text_normal = 2131492879;
@ -1094,11 +1130,11 @@ namespace Bit.Android.Test
// aapt resource value: 0x7f0c0011 // aapt resource value: 0x7f0c0011
public const int abc_search_url_text_selected = 2131492881; public const int abc_search_url_text_selected = 2131492881;
// aapt resource value: 0x7f0c0050 // aapt resource value: 0x7f0c005a
public const int abc_secondary_text_material_dark = 2131492944; public const int abc_secondary_text_material_dark = 2131492954;
// aapt resource value: 0x7f0c0051 // aapt resource value: 0x7f0c005b
public const int abc_secondary_text_material_light = 2131492945; public const int abc_secondary_text_material_light = 2131492955;
// aapt resource value: 0x7f0c0012 // aapt resource value: 0x7f0c0012
public const int accent_material_dark = 2131492882; public const int accent_material_dark = 2131492882;
@ -1214,6 +1250,36 @@ namespace Bit.Android.Test
// aapt resource value: 0x7f0c0029 // aapt resource value: 0x7f0c0029
public const int hint_foreground_material_light = 2131492905; public const int hint_foreground_material_light = 2131492905;
// aapt resource value: 0x7f0c0048
public const int hockeyapp_background_header = 2131492936;
// aapt resource value: 0x7f0c0049
public const int hockeyapp_background_light = 2131492937;
// aapt resource value: 0x7f0c004a
public const int hockeyapp_background_white = 2131492938;
// aapt resource value: 0x7f0c004b
public const int hockeyapp_button_background = 2131492939;
// aapt resource value: 0x7f0c004c
public const int hockeyapp_button_background_pressed = 2131492940;
// aapt resource value: 0x7f0c004d
public const int hockeyapp_button_background_selected = 2131492941;
// aapt resource value: 0x7f0c004e
public const int hockeyapp_text_black = 2131492942;
// aapt resource value: 0x7f0c004f
public const int hockeyapp_text_light = 2131492943;
// aapt resource value: 0x7f0c0050
public const int hockeyapp_text_normal = 2131492944;
// aapt resource value: 0x7f0c0051
public const int hockeyapp_text_white = 2131492945;
// aapt resource value: 0x7f0c002a // aapt resource value: 0x7f0c002a
public const int material_blue_grey_800 = 2131492906; public const int material_blue_grey_800 = 2131492906;
@ -1298,11 +1364,11 @@ namespace Bit.Android.Test
// aapt resource value: 0x7f0c0045 // aapt resource value: 0x7f0c0045
public const int switch_thumb_disabled_material_light = 2131492933; public const int switch_thumb_disabled_material_light = 2131492933;
// aapt resource value: 0x7f0c0052 // aapt resource value: 0x7f0c005c
public const int switch_thumb_material_dark = 2131492946; public const int switch_thumb_material_dark = 2131492956;
// aapt resource value: 0x7f0c0053 // aapt resource value: 0x7f0c005d
public const int switch_thumb_material_light = 2131492947; public const int switch_thumb_material_light = 2131492957;
// aapt resource value: 0x7f0c0046 // aapt resource value: 0x7f0c0046
public const int switch_thumb_normal_material_dark = 2131492934; public const int switch_thumb_normal_material_dark = 2131492934;
@ -1901,10 +1967,25 @@ namespace Bit.Android.Test
public const int fingerprint_white = 2130837581; public const int fingerprint_white = 2130837581;
// aapt resource value: 0x7f02004e // aapt resource value: 0x7f02004e
public const int icon = 2130837582; public const int hockeyapp_btn_background = 2130837582;
// aapt resource value: 0x7f02004f // aapt resource value: 0x7f02004f
public const int notification_template_icon_bg = 2130837583; public const int ic_errorstatus = 2130837583;
// aapt resource value: 0x7f020050
public const int ic_successstatus = 2130837584;
// aapt resource value: 0x7f020051
public const int icon = 2130837585;
// aapt resource value: 0x7f020054
public const int notification_template_icon_bg = 2130837588;
// aapt resource value: 0x7f020052
public const int roundedbg = 2130837586;
// aapt resource value: 0x7f020053
public const int roundedbgdark = 2130837587;
static Drawable() static Drawable()
{ {
@ -1919,62 +2000,62 @@ namespace Bit.Android.Test
public partial class Id public partial class Id
{ {
// aapt resource value: 0x7f080084 // aapt resource value: 0x7f0800a4
public const int OptionHostName = 2131230852; public const int OptionHostName = 2131230884;
// aapt resource value: 0x7f080085 // aapt resource value: 0x7f0800a5
public const int OptionPort = 2131230853; public const int OptionPort = 2131230885;
// aapt resource value: 0x7f080083 // aapt resource value: 0x7f0800a3
public const int OptionRemoteServer = 2131230851; public const int OptionRemoteServer = 2131230883;
// aapt resource value: 0x7f080093 // aapt resource value: 0x7f0800b3
public const int OptionsButton = 2131230867; public const int OptionsButton = 2131230899;
// aapt resource value: 0x7f08008e // aapt resource value: 0x7f0800ae
public const int ResultFullName = 2131230862; public const int ResultFullName = 2131230894;
// aapt resource value: 0x7f080090 // aapt resource value: 0x7f0800b0
public const int ResultMessage = 2131230864; public const int ResultMessage = 2131230896;
// aapt resource value: 0x7f08008f // aapt resource value: 0x7f0800af
public const int ResultResultState = 2131230863; public const int ResultResultState = 2131230895;
// aapt resource value: 0x7f08008d // aapt resource value: 0x7f0800ad
public const int ResultRunSingleMethodTest = 2131230861; public const int ResultRunSingleMethodTest = 2131230893;
// aapt resource value: 0x7f080091 // aapt resource value: 0x7f0800b1
public const int ResultStackTrace = 2131230865; public const int ResultStackTrace = 2131230897;
// aapt resource value: 0x7f080089 // aapt resource value: 0x7f0800a9
public const int ResultsFailed = 2131230857; public const int ResultsFailed = 2131230889;
// aapt resource value: 0x7f080086 // aapt resource value: 0x7f0800a6
public const int ResultsId = 2131230854; public const int ResultsId = 2131230886;
// aapt resource value: 0x7f08008a // aapt resource value: 0x7f0800aa
public const int ResultsIgnored = 2131230858; public const int ResultsIgnored = 2131230890;
// aapt resource value: 0x7f08008b // aapt resource value: 0x7f0800ab
public const int ResultsInconclusive = 2131230859; public const int ResultsInconclusive = 2131230891;
// aapt resource value: 0x7f08008c // aapt resource value: 0x7f0800ac
public const int ResultsMessage = 2131230860; public const int ResultsMessage = 2131230892;
// aapt resource value: 0x7f080088 // aapt resource value: 0x7f0800a8
public const int ResultsPassed = 2131230856; public const int ResultsPassed = 2131230888;
// aapt resource value: 0x7f080087 // aapt resource value: 0x7f0800a7
public const int ResultsResult = 2131230855; public const int ResultsResult = 2131230887;
// aapt resource value: 0x7f080092 // aapt resource value: 0x7f0800b2
public const int RunTestsButton = 2131230866; public const int RunTestsButton = 2131230898;
// aapt resource value: 0x7f080094 // aapt resource value: 0x7f0800b4
public const int TestSuiteListView = 2131230868; public const int TestSuiteListView = 2131230900;
// aapt resource value: 0x7f080076 // aapt resource value: 0x7f080096
public const int action0 = 2131230838; public const int action0 = 2131230870;
// aapt resource value: 0x7f08005c // aapt resource value: 0x7f08005c
public const int action_bar = 2131230812; public const int action_bar = 2131230812;
@ -2000,8 +2081,8 @@ namespace Bit.Android.Test
// aapt resource value: 0x7f08005d // aapt resource value: 0x7f08005d
public const int action_context_bar = 2131230813; public const int action_context_bar = 2131230813;
// aapt resource value: 0x7f08007a // aapt resource value: 0x7f08009a
public const int action_divider = 2131230842; public const int action_divider = 2131230874;
// aapt resource value: 0x7f080004 // aapt resource value: 0x7f080004
public const int action_menu_divider = 2131230724; public const int action_menu_divider = 2131230724;
@ -2042,8 +2123,26 @@ namespace Bit.Android.Test
// aapt resource value: 0x7f080046 // aapt resource value: 0x7f080046
public const int buttonPanel = 2131230790; public const int buttonPanel = 2131230790;
// aapt resource value: 0x7f080077 // aapt resource value: 0x7f080083
public const int cancel_action = 2131230839; public const int button_add_response = 2131230851;
// aapt resource value: 0x7f08007e
public const int button_attachment = 2131230846;
// aapt resource value: 0x7f080088
public const int button_login = 2131230856;
// aapt resource value: 0x7f080084
public const int button_refresh = 2131230852;
// aapt resource value: 0x7f08007f
public const int button_send = 2131230847;
// aapt resource value: 0x7f08008c
public const int button_update = 2131230860;
// aapt resource value: 0x7f080097
public const int cancel_action = 2131230871;
// aapt resource value: 0x7f080016 // aapt resource value: 0x7f080016
public const int center = 2131230742; public const int center = 2131230742;
@ -2057,8 +2156,8 @@ namespace Bit.Android.Test
// aapt resource value: 0x7f080054 // aapt resource value: 0x7f080054
public const int checkbox = 2131230804; public const int checkbox = 2131230804;
// aapt resource value: 0x7f08007d // aapt resource value: 0x7f08009d
public const int chronometer = 2131230845; public const int chronometer = 2131230877;
// aapt resource value: 0x7f08001f // aapt resource value: 0x7f08001f
public const int clip_horizontal = 2131230751; public const int clip_horizontal = 2131230751;
@ -2108,8 +2207,8 @@ namespace Bit.Android.Test
// aapt resource value: 0x7f080019 // aapt resource value: 0x7f080019
public const int end = 2131230745; public const int end = 2131230745;
// aapt resource value: 0x7f080082 // aapt resource value: 0x7f0800a2
public const int end_padder = 2131230850; public const int end_padder = 2131230882;
// aapt resource value: 0x7f08000e // aapt resource value: 0x7f08000e
public const int enterAlways = 2131230734; public const int enterAlways = 2131230734;
@ -2159,29 +2258,80 @@ namespace Bit.Android.Test
// aapt resource value: 0x7f080041 // aapt resource value: 0x7f080041
public const int image = 2131230785; public const int image = 2131230785;
// aapt resource value: 0x7f080081 // aapt resource value: 0x7f0800a1
public const int info = 2131230849; public const int info = 2131230881;
// aapt resource value: 0x7f08007a
public const int input_email = 2131230842;
// aapt resource value: 0x7f08007c
public const int input_message = 2131230844;
// aapt resource value: 0x7f080079
public const int input_name = 2131230841;
// aapt resource value: 0x7f080087
public const int input_password = 2131230855;
// aapt resource value: 0x7f08007b
public const int input_subject = 2131230843;
// aapt resource value: 0x7f080000 // aapt resource value: 0x7f080000
public const int item_touch_helper_previous_elevation = 2131230720; public const int item_touch_helper_previous_elevation = 2131230720;
// aapt resource value: 0x7f08008e
public const int label_author = 2131230862;
// aapt resource value: 0x7f08008f
public const int label_date = 2131230863;
// aapt resource value: 0x7f080081
public const int label_last_updated = 2131230849;
// aapt resource value: 0x7f080076
public const int label_message = 2131230838;
// aapt resource value: 0x7f080090
public const int label_text = 2131230864;
// aapt resource value: 0x7f08008a
public const int label_title = 2131230858;
// aapt resource value: 0x7f08008b
public const int label_version = 2131230859;
// aapt resource value: 0x7f08001b // aapt resource value: 0x7f08001b
public const int left = 2131230747; public const int left = 2131230747;
// aapt resource value: 0x7f08007b // aapt resource value: 0x7f08009b
public const int line1 = 2131230843; public const int line1 = 2131230875;
// aapt resource value: 0x7f08007f // aapt resource value: 0x7f08009f
public const int line3 = 2131230847; public const int line3 = 2131230879;
// aapt resource value: 0x7f080027 // aapt resource value: 0x7f080027
public const int listMode = 2131230759; public const int listMode = 2131230759;
// aapt resource value: 0x7f080091
public const int list_attachments = 2131230865;
// aapt resource value: 0x7f080085
public const int list_feedback_messages = 2131230853;
// aapt resource value: 0x7f080043 // aapt resource value: 0x7f080043
public const int list_item = 2131230787; public const int list_item = 2131230787;
// aapt resource value: 0x7f080079 // aapt resource value: 0x7f080094
public const int media_actions = 2131230841; public const int loadingImage = 2131230868;
// aapt resource value: 0x7f080092
public const int loadingProgressBar = 2131230866;
// aapt resource value: 0x7f080095
public const int loadingProgressWheel = 2131230869;
// aapt resource value: 0x7f080099
public const int media_actions = 2131230873;
// aapt resource value: 0x7f080036 // aapt resource value: 0x7f080036
public const int middle = 2131230774; public const int middle = 2131230774;
@ -2315,8 +2465,8 @@ namespace Bit.Android.Test
// aapt resource value: 0x7f08001d // aapt resource value: 0x7f08001d
public const int start = 2131230749; public const int start = 2131230749;
// aapt resource value: 0x7f080078 // aapt resource value: 0x7f080098
public const int status_bar_latest_event_content = 2131230840; public const int status_bar_latest_event_content = 2131230872;
// aapt resource value: 0x7f080067 // aapt resource value: 0x7f080067
public const int submit_area = 2131230823; public const int submit_area = 2131230823;
@ -2324,17 +2474,23 @@ namespace Bit.Android.Test
// aapt resource value: 0x7f080028 // aapt resource value: 0x7f080028
public const int tabMode = 2131230760; public const int tabMode = 2131230760;
// aapt resource value: 0x7f080080 // aapt resource value: 0x7f0800a0
public const int text = 2131230848; public const int text = 2131230880;
// aapt resource value: 0x7f08007e // aapt resource value: 0x7f08009e
public const int text2 = 2131230846; public const int text2 = 2131230878;
// aapt resource value: 0x7f08004f // aapt resource value: 0x7f08004f
public const int textSpacerNoButtons = 2131230799; public const int textSpacerNoButtons = 2131230799;
// aapt resource value: 0x7f08007c // aapt resource value: 0x7f080093
public const int time = 2131230844; public const int textViewStatus = 2131230867;
// aapt resource value: 0x7f080086
public const int text_headline = 2131230854;
// aapt resource value: 0x7f08009c
public const int time = 2131230876;
// aapt resource value: 0x7f080045 // aapt resource value: 0x7f080045
public const int title = 2131230789; public const int title = 2131230789;
@ -2357,15 +2513,36 @@ namespace Bit.Android.Test
// aapt resource value: 0x7f08002e // aapt resource value: 0x7f08002e
public const int useLogo = 2131230766; public const int useLogo = 2131230766;
// aapt resource value: 0x7f080089
public const int view_header = 2131230857;
// aapt resource value: 0x7f080001 // aapt resource value: 0x7f080001
public const int view_offset_helper = 2131230721; public const int view_offset_helper = 2131230721;
// aapt resource value: 0x7f08008d
public const int web_update_details = 2131230861;
// aapt resource value: 0x7f08003b // aapt resource value: 0x7f08003b
public const int withText = 2131230779; public const int withText = 2131230779;
// aapt resource value: 0x7f08002f // aapt resource value: 0x7f08002f
public const int wrap_content = 2131230767; public const int wrap_content = 2131230767;
// aapt resource value: 0x7f08007d
public const int wrapper_attachments = 2131230845;
// aapt resource value: 0x7f080078
public const int wrapper_feedback = 2131230840;
// aapt resource value: 0x7f080077
public const int wrapper_feedback_scroll = 2131230839;
// aapt resource value: 0x7f080080
public const int wrapper_messages = 2131230848;
// aapt resource value: 0x7f080082
public const int wrapper_messages_buttons = 2131230850;
static Id() static Id()
{ {
global::Android.Runtime.ResourceIdManager.UpdateIdValues(); global::Android.Runtime.ResourceIdManager.UpdateIdValues();
@ -2531,52 +2708,79 @@ namespace Bit.Android.Test
public const int FingerprintDialog = 2130903077; public const int FingerprintDialog = 2130903077;
// aapt resource value: 0x7f030026 // aapt resource value: 0x7f030026
public const int notification_media_action = 2130903078; public const int hockeyapp_activity_expiry_info = 2130903078;
// aapt resource value: 0x7f030027 // aapt resource value: 0x7f030027
public const int notification_media_cancel_action = 2130903079; public const int hockeyapp_activity_feedback = 2130903079;
// aapt resource value: 0x7f030028 // aapt resource value: 0x7f030028
public const int notification_template_big_media = 2130903080; public const int hockeyapp_activity_login = 2130903080;
// aapt resource value: 0x7f030029 // aapt resource value: 0x7f030029
public const int notification_template_big_media_narrow = 2130903081; public const int hockeyapp_activity_update = 2130903081;
// aapt resource value: 0x7f03002a // aapt resource value: 0x7f03002a
public const int notification_template_lines = 2130903082; public const int hockeyapp_fragment_update = 2130903082;
// aapt resource value: 0x7f03002b // aapt resource value: 0x7f03002b
public const int notification_template_media = 2130903083; public const int hockeyapp_view_feedback_message = 2130903083;
// aapt resource value: 0x7f03002c // aapt resource value: 0x7f03002c
public const int notification_template_part_chronometer = 2130903084; public const int loading = 2130903084;
// aapt resource value: 0x7f03002d // aapt resource value: 0x7f03002d
public const int notification_template_part_time = 2130903085; public const int loadingimage = 2130903085;
// aapt resource value: 0x7f03002e // aapt resource value: 0x7f03002e
public const int options = 2130903086; public const int loadingprogress = 2130903086;
// aapt resource value: 0x7f03002f // aapt resource value: 0x7f03002f
public const int results = 2130903087; public const int notification_media_action = 2130903087;
// aapt resource value: 0x7f030030 // aapt resource value: 0x7f030030
public const int select_dialog_item_material = 2130903088; public const int notification_media_cancel_action = 2130903088;
// aapt resource value: 0x7f030031 // aapt resource value: 0x7f030031
public const int select_dialog_multichoice_material = 2130903089; public const int notification_template_big_media = 2130903089;
// aapt resource value: 0x7f030032 // aapt resource value: 0x7f030032
public const int select_dialog_singlechoice_material = 2130903090; public const int notification_template_big_media_narrow = 2130903090;
// aapt resource value: 0x7f030033 // aapt resource value: 0x7f030033
public const int support_simple_spinner_dropdown_item = 2130903091; public const int notification_template_lines = 2130903091;
// aapt resource value: 0x7f030034 // aapt resource value: 0x7f030034
public const int test_result = 2130903092; public const int notification_template_media = 2130903092;
// aapt resource value: 0x7f030035 // aapt resource value: 0x7f030035
public const int test_suite = 2130903093; public const int notification_template_part_chronometer = 2130903093;
// aapt resource value: 0x7f030036
public const int notification_template_part_time = 2130903094;
// aapt resource value: 0x7f030037
public const int options = 2130903095;
// aapt resource value: 0x7f030038
public const int results = 2130903096;
// aapt resource value: 0x7f030039
public const int select_dialog_item_material = 2130903097;
// aapt resource value: 0x7f03003a
public const int select_dialog_multichoice_material = 2130903098;
// aapt resource value: 0x7f03003b
public const int select_dialog_singlechoice_material = 2130903099;
// aapt resource value: 0x7f03003c
public const int support_simple_spinner_dropdown_item = 2130903100;
// aapt resource value: 0x7f03003d
public const int test_result = 2130903101;
// aapt resource value: 0x7f03003e
public const int test_suite = 2130903102;
static Layout() static Layout()
{ {
@ -2607,11 +2811,11 @@ namespace Bit.Android.Test
public partial class String public partial class String
{ {
// aapt resource value: 0x7f09001b // aapt resource value: 0x7f090063
public const int ApplicationName = 2131296283; public const int ApplicationName = 2131296355;
// aapt resource value: 0x7f09001a // aapt resource value: 0x7f090062
public const int Hello = 2131296282; public const int Hello = 2131296354;
// aapt resource value: 0x7f090006 // aapt resource value: 0x7f090006
public const int abc_action_bar_home_description = 2131296262; public const int abc_action_bar_home_description = 2131296262;
@ -2688,6 +2892,222 @@ namespace Bit.Android.Test
// aapt resource value: 0x7f090002 // aapt resource value: 0x7f090002
public const int common_google_play_services_unknown_issue = 2131296258; public const int common_google_play_services_unknown_issue = 2131296258;
// aapt resource value: 0x7f09001b
public const int hockeyapp_crash_dialog_app_name_fallback = 2131296283;
// aapt resource value: 0x7f09001c
public const int hockeyapp_crash_dialog_message = 2131296284;
// aapt resource value: 0x7f09001d
public const int hockeyapp_crash_dialog_negative_button = 2131296285;
// aapt resource value: 0x7f09001e
public const int hockeyapp_crash_dialog_neutral_button = 2131296286;
// aapt resource value: 0x7f09001f
public const int hockeyapp_crash_dialog_positive_button = 2131296287;
// aapt resource value: 0x7f090020
public const int hockeyapp_crash_dialog_title = 2131296288;
// aapt resource value: 0x7f090021
public const int hockeyapp_dialog_error_message = 2131296289;
// aapt resource value: 0x7f090022
public const int hockeyapp_dialog_error_title = 2131296290;
// aapt resource value: 0x7f090023
public const int hockeyapp_dialog_negative_button = 2131296291;
// aapt resource value: 0x7f090024
public const int hockeyapp_dialog_positive_button = 2131296292;
// aapt resource value: 0x7f090025
public const int hockeyapp_download_failed_dialog_message = 2131296293;
// aapt resource value: 0x7f090026
public const int hockeyapp_download_failed_dialog_negative_button = 2131296294;
// aapt resource value: 0x7f090027
public const int hockeyapp_download_failed_dialog_positive_button = 2131296295;
// aapt resource value: 0x7f090028
public const int hockeyapp_download_failed_dialog_title = 2131296296;
// aapt resource value: 0x7f090029
public const int hockeyapp_error_no_network_message = 2131296297;
// aapt resource value: 0x7f09002a
public const int hockeyapp_expiry_info_text = 2131296298;
// aapt resource value: 0x7f09002b
public const int hockeyapp_expiry_info_title = 2131296299;
// aapt resource value: 0x7f09002c
public const int hockeyapp_feedback_attach_file = 2131296300;
// aapt resource value: 0x7f09002d
public const int hockeyapp_feedback_attach_picture = 2131296301;
// aapt resource value: 0x7f09002e
public const int hockeyapp_feedback_attachment_button_text = 2131296302;
// aapt resource value: 0x7f09002f
public const int hockeyapp_feedback_attachment_error = 2131296303;
// aapt resource value: 0x7f090030
public const int hockeyapp_feedback_attachment_loading = 2131296304;
// aapt resource value: 0x7f090031
public const int hockeyapp_feedback_email_hint = 2131296305;
// aapt resource value: 0x7f090032
public const int hockeyapp_feedback_failed_text = 2131296306;
// aapt resource value: 0x7f090033
public const int hockeyapp_feedback_failed_title = 2131296307;
// aapt resource value: 0x7f090034
public const int hockeyapp_feedback_fetching_feedback_text = 2131296308;
// aapt resource value: 0x7f090035
public const int hockeyapp_feedback_generic_error = 2131296309;
// aapt resource value: 0x7f090036
public const int hockeyapp_feedback_last_updated_text = 2131296310;
// aapt resource value: 0x7f090037
public const int hockeyapp_feedback_max_attachments_allowed = 2131296311;
// aapt resource value: 0x7f090038
public const int hockeyapp_feedback_message_hint = 2131296312;
// aapt resource value: 0x7f090039
public const int hockeyapp_feedback_name_hint = 2131296313;
// aapt resource value: 0x7f09003a
public const int hockeyapp_feedback_refresh_button_text = 2131296314;
// aapt resource value: 0x7f09003b
public const int hockeyapp_feedback_response_button_text = 2131296315;
// aapt resource value: 0x7f09003c
public const int hockeyapp_feedback_select_file = 2131296316;
// aapt resource value: 0x7f09003d
public const int hockeyapp_feedback_select_picture = 2131296317;
// aapt resource value: 0x7f09003e
public const int hockeyapp_feedback_send_button_text = 2131296318;
// aapt resource value: 0x7f09003f
public const int hockeyapp_feedback_send_generic_error = 2131296319;
// aapt resource value: 0x7f090040
public const int hockeyapp_feedback_send_network_error = 2131296320;
// aapt resource value: 0x7f090041
public const int hockeyapp_feedback_sending_feedback_text = 2131296321;
// aapt resource value: 0x7f090042
public const int hockeyapp_feedback_subject_hint = 2131296322;
// aapt resource value: 0x7f090043
public const int hockeyapp_feedback_title = 2131296323;
// aapt resource value: 0x7f090044
public const int hockeyapp_feedback_validate_email_empty = 2131296324;
// aapt resource value: 0x7f090045
public const int hockeyapp_feedback_validate_email_error = 2131296325;
// aapt resource value: 0x7f090046
public const int hockeyapp_feedback_validate_name_error = 2131296326;
// aapt resource value: 0x7f090047
public const int hockeyapp_feedback_validate_subject_error = 2131296327;
// aapt resource value: 0x7f090048
public const int hockeyapp_feedback_validate_text_error = 2131296328;
// aapt resource value: 0x7f090049
public const int hockeyapp_login_email_hint = 2131296329;
// aapt resource value: 0x7f09004a
public const int hockeyapp_login_headline_text = 2131296330;
// aapt resource value: 0x7f09004b
public const int hockeyapp_login_headline_text_email_only = 2131296331;
// aapt resource value: 0x7f09004c
public const int hockeyapp_login_login_button_text = 2131296332;
// aapt resource value: 0x7f09004d
public const int hockeyapp_login_missing_credentials_toast = 2131296333;
// aapt resource value: 0x7f09004e
public const int hockeyapp_login_password_hint = 2131296334;
// aapt resource value: 0x7f09004f
public const int hockeyapp_paint_dialog_message = 2131296335;
// aapt resource value: 0x7f090050
public const int hockeyapp_paint_dialog_negative_button = 2131296336;
// aapt resource value: 0x7f090051
public const int hockeyapp_paint_dialog_neutral_button = 2131296337;
// aapt resource value: 0x7f090052
public const int hockeyapp_paint_dialog_positive_button = 2131296338;
// aapt resource value: 0x7f090053
public const int hockeyapp_paint_indicator_toast = 2131296339;
// aapt resource value: 0x7f090054
public const int hockeyapp_paint_menu_clear = 2131296340;
// aapt resource value: 0x7f090055
public const int hockeyapp_paint_menu_save = 2131296341;
// aapt resource value: 0x7f090056
public const int hockeyapp_paint_menu_undo = 2131296342;
// aapt resource value: 0x7f090057
public const int hockeyapp_permission_dialog_negative_button = 2131296343;
// aapt resource value: 0x7f090058
public const int hockeyapp_permission_dialog_positive_button = 2131296344;
// aapt resource value: 0x7f090059
public const int hockeyapp_permission_update_message = 2131296345;
// aapt resource value: 0x7f09005a
public const int hockeyapp_permission_update_title = 2131296346;
// aapt resource value: 0x7f09005b
public const int hockeyapp_update_button = 2131296347;
// aapt resource value: 0x7f09005c
public const int hockeyapp_update_dialog_message = 2131296348;
// aapt resource value: 0x7f09005d
public const int hockeyapp_update_dialog_negative_button = 2131296349;
// aapt resource value: 0x7f09005e
public const int hockeyapp_update_dialog_positive_button = 2131296350;
// aapt resource value: 0x7f09005f
public const int hockeyapp_update_dialog_title = 2131296351;
// aapt resource value: 0x7f090060
public const int hockeyapp_update_mandatory_toast = 2131296352;
// aapt resource value: 0x7f090061
public const int hockeyapp_update_version_details_label = 2131296353;
// aapt resource value: 0x7f09001a
public const int library_name = 2131296282;
// aapt resource value: 0x7f090019 // aapt resource value: 0x7f090019
public const int status_bar_notification_info_overflow = 2131296281; public const int status_bar_notification_info_overflow = 2131296281;
@ -3151,14 +3571,14 @@ namespace Bit.Android.Test
// aapt resource value: 0x7f0b0006 // aapt resource value: 0x7f0b0006
public const int Base_Widget_Design_TabLayout = 2131427334; public const int Base_Widget_Design_TabLayout = 2131427334;
// aapt resource value: 0x7f0b015c // aapt resource value: 0x7f0b015f
public const int BitwardenTheme = 2131427676; public const int BitwardenTheme = 2131427679;
// aapt resource value: 0x7f0b015d // aapt resource value: 0x7f0b0160
public const int BitwardenTheme_Base = 2131427677; public const int BitwardenTheme_Base = 2131427680;
// aapt resource value: 0x7f0b015b // aapt resource value: 0x7f0b015e
public const int BitwardenTheme_Splash = 2131427675; public const int BitwardenTheme_Splash = 2131427678;
// aapt resource value: 0x7f0b0000 // aapt resource value: 0x7f0b0000
public const int CardView = 2131427328; public const int CardView = 2131427328;
@ -3169,6 +3589,15 @@ namespace Bit.Android.Test
// aapt resource value: 0x7f0b0003 // aapt resource value: 0x7f0b0003
public const int CardView_Light = 2131427331; public const int CardView_Light = 2131427331;
// aapt resource value: 0x7f0b015b
public const int HockeyApp_ButtonStyle = 2131427675;
// aapt resource value: 0x7f0b015c
public const int HockeyApp_EditTextStyle = 2131427676;
// aapt resource value: 0x7f0b015d
public const int HockeyApp_SingleLineInputStyle = 2131427677;
// aapt resource value: 0x7f0b0034 // aapt resource value: 0x7f0b0034
public const int Platform_AppCompat = 2131427380; public const int Platform_AppCompat = 2131427380;
@ -5011,6 +5440,56 @@ namespace Bit.Android.Test
// aapt resource value: 0 // aapt resource value: 0
public const int PopupWindowBackgroundState_state_above_anchor = 0; public const int PopupWindowBackgroundState_state_above_anchor = 0;
public static int[] ProgressWheel = new int[] {
2130772264,
2130772265,
2130772266,
2130772267,
2130772268,
2130772269,
2130772270,
2130772271,
2130772272,
2130772273,
2130772274,
2130772275};
// aapt resource value: 3
public const int ProgressWheel_ahBarColor = 3;
// aapt resource value: 11
public const int ProgressWheel_ahBarLength = 11;
// aapt resource value: 10
public const int ProgressWheel_ahBarWidth = 10;
// aapt resource value: 8
public const int ProgressWheel_ahCircleColor = 8;
// aapt resource value: 7
public const int ProgressWheel_ahDelayMillis = 7;
// aapt resource value: 9
public const int ProgressWheel_ahRadius = 9;
// aapt resource value: 4
public const int ProgressWheel_ahRimColor = 4;
// aapt resource value: 5
public const int ProgressWheel_ahRimWidth = 5;
// aapt resource value: 6
public const int ProgressWheel_ahSpinSpeed = 6;
// aapt resource value: 0
public const int ProgressWheel_ahText = 0;
// aapt resource value: 1
public const int ProgressWheel_ahTextColor = 1;
// aapt resource value: 2
public const int ProgressWheel_ahTextSize = 2;
public static int[] RecyclerView = new int[] { public static int[] RecyclerView = new int[] {
16842948, 16842948,
2130771968, 2130771968,