mirror of
https://github.com/bitwarden/mobile
synced 2025-12-10 13:23:39 +00:00
set org keys on login and decrypt org ciphers
This commit is contained in:
@@ -8,6 +8,7 @@ namespace Bit.App.Abstractions
|
|||||||
{
|
{
|
||||||
Task<ApiResult> PostRegisterAsync(RegisterRequest requestObj);
|
Task<ApiResult> PostRegisterAsync(RegisterRequest requestObj);
|
||||||
Task<ApiResult> PostPasswordHintAsync(PasswordHintRequest requestObj);
|
Task<ApiResult> PostPasswordHintAsync(PasswordHintRequest requestObj);
|
||||||
Task<ApiResult<DateTime?>> GetAccountRevisionDate();
|
Task<ApiResult<DateTime?>> GetAccountRevisionDateAsync();
|
||||||
|
Task<ApiResult<ProfileResponse>> GetProfileAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,14 +10,16 @@ namespace Bit.App.Abstractions
|
|||||||
CryptoKey PreviousKey { get; }
|
CryptoKey PreviousKey { get; }
|
||||||
bool KeyChanged { get; }
|
bool KeyChanged { get; }
|
||||||
byte[] PrivateKey { get; }
|
byte[] PrivateKey { get; }
|
||||||
IDictionary<Guid, CryptoKey> OrgKeys { get; set; }
|
IDictionary<string, CryptoKey> OrgKeys { get; set; }
|
||||||
|
|
||||||
void SetPrivateKey(CipherString privateKeyEnc, CryptoKey key);
|
void SetPrivateKey(CipherString privateKeyEnc, CryptoKey key);
|
||||||
CryptoKey GetOrgKey(Guid orgId);
|
CryptoKey GetOrgKey(string orgId);
|
||||||
void ClearOrgKey(Guid orgId);
|
void ClearOrgKey(string orgId);
|
||||||
void ClearKeys();
|
void ClearKeys();
|
||||||
CryptoKey AddOrgKey(Guid orgId, CipherString encOrgKey, byte[] privateKey);
|
CryptoKey AddOrgKey(string orgId, CipherString encOrgKey, byte[] privateKey);
|
||||||
string Decrypt(CipherString encyptedValue, CryptoKey key = null);
|
string Decrypt(CipherString encyptedValue, CryptoKey key = null);
|
||||||
|
byte[] DecryptToBytes(CipherString encyptedValue, CryptoKey key = null);
|
||||||
|
byte[] RsaDecryptToBytes(CipherString encyptedValue, byte[] privateKey);
|
||||||
CipherString Encrypt(string plaintextValue, CryptoKey key = null);
|
CipherString Encrypt(string plaintextValue, CryptoKey key = null);
|
||||||
CryptoKey MakeKeyFromPassword(string password, string salt);
|
CryptoKey MakeKeyFromPassword(string password, string salt);
|
||||||
string MakeKeyFromPasswordBase64(string password, string salt);
|
string MakeKeyFromPasswordBase64(string password, string salt);
|
||||||
|
|||||||
@@ -81,8 +81,10 @@
|
|||||||
<Compile Include="Controls\PinControl.cs" />
|
<Compile Include="Controls\PinControl.cs" />
|
||||||
<Compile Include="Controls\VaultListViewCell.cs" />
|
<Compile Include="Controls\VaultListViewCell.cs" />
|
||||||
<Compile Include="Enums\EncryptionType.cs" />
|
<Compile Include="Enums\EncryptionType.cs" />
|
||||||
|
<Compile Include="Enums\OrganizationUserType.cs" />
|
||||||
<Compile Include="Enums\LockType.cs" />
|
<Compile Include="Enums\LockType.cs" />
|
||||||
<Compile Include="Enums\CipherType.cs" />
|
<Compile Include="Enums\CipherType.cs" />
|
||||||
|
<Compile Include="Enums\OrganizationUserStatusType.cs" />
|
||||||
<Compile Include="Enums\PushType.cs" />
|
<Compile Include="Enums\PushType.cs" />
|
||||||
<Compile Include="Enums\ReturnType.cs" />
|
<Compile Include="Enums\ReturnType.cs" />
|
||||||
<Compile Include="Abstractions\Services\ILocalizeService.cs" />
|
<Compile Include="Abstractions\Services\ILocalizeService.cs" />
|
||||||
@@ -104,6 +106,7 @@
|
|||||||
<Compile Include="Models\Api\Response\ListResponse.cs" />
|
<Compile Include="Models\Api\Response\ListResponse.cs" />
|
||||||
<Compile Include="Models\Api\Response\DeviceResponse.cs" />
|
<Compile Include="Models\Api\Response\DeviceResponse.cs" />
|
||||||
<Compile Include="Models\Api\Response\LoginResponse.cs" />
|
<Compile Include="Models\Api\Response\LoginResponse.cs" />
|
||||||
|
<Compile Include="Models\Api\Response\ProfileOrganizationResponse.cs" />
|
||||||
<Compile Include="Models\Api\Response\TokenResponse.cs" />
|
<Compile Include="Models\Api\Response\TokenResponse.cs" />
|
||||||
<Compile Include="Models\Api\Response\ProfileResponse.cs" />
|
<Compile Include="Models\Api\Response\ProfileResponse.cs" />
|
||||||
<Compile Include="Models\Api\LoginDataModel.cs" />
|
<Compile Include="Models\Api\LoginDataModel.cs" />
|
||||||
|
|||||||
9
src/App/Enums/OrganizationUserStatusType.cs
Normal file
9
src/App/Enums/OrganizationUserStatusType.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
namespace Bit.App.Enums
|
||||||
|
{
|
||||||
|
public enum OrganizationUserStatusType : byte
|
||||||
|
{
|
||||||
|
Invited = 0,
|
||||||
|
Accepted = 1,
|
||||||
|
Confirmed = 2
|
||||||
|
}
|
||||||
|
}
|
||||||
9
src/App/Enums/OrganizationUserType.cs
Normal file
9
src/App/Enums/OrganizationUserType.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
namespace Bit.App.Enums
|
||||||
|
{
|
||||||
|
public enum OrganizationUserType : byte
|
||||||
|
{
|
||||||
|
Owner = 0,
|
||||||
|
Admin = 1,
|
||||||
|
User = 2
|
||||||
|
}
|
||||||
|
}
|
||||||
14
src/App/Models/Api/Response/ProfileOrganizationResponse.cs
Normal file
14
src/App/Models/Api/Response/ProfileOrganizationResponse.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
using Bit.App.Enums;
|
||||||
|
|
||||||
|
namespace Bit.App.Models.Api
|
||||||
|
{
|
||||||
|
public class ProfileOrganizationResponseModel
|
||||||
|
{
|
||||||
|
public string Id { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string Key { get; set; }
|
||||||
|
public OrganizationUserStatusType Status { get; set; }
|
||||||
|
public OrganizationUserType Type { get; set; }
|
||||||
|
public bool Enabled { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
namespace Bit.App.Models.Api
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Bit.App.Models.Api
|
||||||
{
|
{
|
||||||
public class ProfileResponse
|
public class ProfileResponse
|
||||||
{
|
{
|
||||||
@@ -8,5 +10,6 @@
|
|||||||
public string MasterPasswordHint { get; set; }
|
public string MasterPasswordHint { get; set; }
|
||||||
public string Culture { get; set; }
|
public string Culture { get; set; }
|
||||||
public bool TwoFactorEnabled { get; set; }
|
public bool TwoFactorEnabled { get; set; }
|
||||||
|
public IEnumerable<ProfileOrganizationResponseModel> Organizations { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -102,12 +102,19 @@ namespace Bit.App.Models
|
|||||||
public byte[] CipherTextBytes => Convert.FromBase64String(CipherText);
|
public byte[] CipherTextBytes => Convert.FromBase64String(CipherText);
|
||||||
public byte[] MacBytes => Mac == null ? null : Convert.FromBase64String(Mac);
|
public byte[] MacBytes => Mac == null ? null : Convert.FromBase64String(Mac);
|
||||||
|
|
||||||
public string Decrypt()
|
public string Decrypt(string orgId = null)
|
||||||
{
|
{
|
||||||
if(_decryptedValue == null)
|
if(_decryptedValue == null)
|
||||||
{
|
{
|
||||||
var cryptoService = Resolver.Resolve<ICryptoService>();
|
var cryptoService = Resolver.Resolve<ICryptoService>();
|
||||||
_decryptedValue = cryptoService.Decrypt(this);
|
if(!string.IsNullOrWhiteSpace(orgId))
|
||||||
|
{
|
||||||
|
_decryptedValue = cryptoService.Decrypt(this, cryptoService.GetOrgKey(orgId));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_decryptedValue = cryptoService.Decrypt(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return _decryptedValue;
|
return _decryptedValue;
|
||||||
|
|||||||
@@ -12,10 +12,10 @@ namespace Bit.App.Models.Page
|
|||||||
{
|
{
|
||||||
Id = login.Id;
|
Id = login.Id;
|
||||||
FolderId = login.FolderId;
|
FolderId = login.FolderId;
|
||||||
Name = login.Name?.Decrypt();
|
Name = login.Name?.Decrypt(login.OrganizationId);
|
||||||
Username = login.Username?.Decrypt() ?? " ";
|
Username = login.Username?.Decrypt(login.OrganizationId) ?? " ";
|
||||||
Password = new Lazy<string>(() => login.Password?.Decrypt());
|
Password = new Lazy<string>(() => login.Password?.Decrypt(login.OrganizationId));
|
||||||
Uri = new Lazy<string>(() => login.Uri?.Decrypt());
|
Uri = new Lazy<string>(() => login.Uri?.Decrypt(login.OrganizationId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
|
|||||||
@@ -171,11 +171,11 @@ namespace Bit.App.Models.Page
|
|||||||
|
|
||||||
public void Update(Login login)
|
public void Update(Login login)
|
||||||
{
|
{
|
||||||
Name = login.Name?.Decrypt();
|
Name = login.Name?.Decrypt(login.OrganizationId);
|
||||||
Username = login.Username?.Decrypt();
|
Username = login.Username?.Decrypt(login.OrganizationId);
|
||||||
Password = login.Password?.Decrypt();
|
Password = login.Password?.Decrypt(login.OrganizationId);
|
||||||
Uri = login.Uri?.Decrypt();
|
Uri = login.Uri?.Decrypt(login.OrganizationId);
|
||||||
Notes = login.Notes?.Decrypt();
|
Notes = login.Notes?.Decrypt(login.OrganizationId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,25 +51,25 @@ namespace Bit.App.Pages
|
|||||||
}
|
}
|
||||||
|
|
||||||
NotesCell = new FormEditorCell(height: 90);
|
NotesCell = new FormEditorCell(height: 90);
|
||||||
NotesCell.Editor.Text = login.Notes?.Decrypt();
|
NotesCell.Editor.Text = login.Notes?.Decrypt(login.OrganizationId);
|
||||||
|
|
||||||
PasswordCell = new FormEntryCell(AppResources.Password, isPassword: true, nextElement: NotesCell.Editor,
|
PasswordCell = new FormEntryCell(AppResources.Password, isPassword: true, nextElement: NotesCell.Editor,
|
||||||
useButton: true);
|
useButton: true);
|
||||||
PasswordCell.Entry.Text = login.Password?.Decrypt();
|
PasswordCell.Entry.Text = login.Password?.Decrypt(login.OrganizationId);
|
||||||
PasswordCell.Button.Image = "eye";
|
PasswordCell.Button.Image = "eye";
|
||||||
PasswordCell.Entry.DisableAutocapitalize = true;
|
PasswordCell.Entry.DisableAutocapitalize = true;
|
||||||
PasswordCell.Entry.Autocorrect = false;
|
PasswordCell.Entry.Autocorrect = false;
|
||||||
PasswordCell.Entry.FontFamily = Device.OnPlatform(iOS: "Courier", Android: "monospace", WinPhone: "Courier");
|
PasswordCell.Entry.FontFamily = Device.OnPlatform(iOS: "Courier", Android: "monospace", WinPhone: "Courier");
|
||||||
|
|
||||||
UsernameCell = new FormEntryCell(AppResources.Username, nextElement: PasswordCell.Entry);
|
UsernameCell = new FormEntryCell(AppResources.Username, nextElement: PasswordCell.Entry);
|
||||||
UsernameCell.Entry.Text = login.Username?.Decrypt();
|
UsernameCell.Entry.Text = login.Username?.Decrypt(login.OrganizationId);
|
||||||
UsernameCell.Entry.DisableAutocapitalize = true;
|
UsernameCell.Entry.DisableAutocapitalize = true;
|
||||||
UsernameCell.Entry.Autocorrect = false;
|
UsernameCell.Entry.Autocorrect = false;
|
||||||
|
|
||||||
UriCell = new FormEntryCell(AppResources.URI, Keyboard.Url, nextElement: UsernameCell.Entry);
|
UriCell = new FormEntryCell(AppResources.URI, Keyboard.Url, nextElement: UsernameCell.Entry);
|
||||||
UriCell.Entry.Text = login.Uri?.Decrypt();
|
UriCell.Entry.Text = login.Uri?.Decrypt(login.OrganizationId);
|
||||||
NameCell = new FormEntryCell(AppResources.Name, nextElement: UriCell.Entry);
|
NameCell = new FormEntryCell(AppResources.Name, nextElement: UriCell.Entry);
|
||||||
NameCell.Entry.Text = login.Name?.Decrypt();
|
NameCell.Entry.Text = login.Name?.Decrypt(login.OrganizationId);
|
||||||
|
|
||||||
GenerateCell = new ExtendedTextCell
|
GenerateCell = new ExtendedTextCell
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using System.Threading.Tasks;
|
|||||||
using Bit.App.Abstractions;
|
using Bit.App.Abstractions;
|
||||||
using Bit.App.Models.Api;
|
using Bit.App.Models.Api;
|
||||||
using Plugin.Connectivity.Abstractions;
|
using Plugin.Connectivity.Abstractions;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Bit.App.Repositories
|
namespace Bit.App.Repositories
|
||||||
{
|
{
|
||||||
@@ -84,7 +85,7 @@ namespace Bit.App.Repositories
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<ApiResult<DateTime?>> GetAccountRevisionDate()
|
public virtual async Task<ApiResult<DateTime?>> GetAccountRevisionDateAsync()
|
||||||
{
|
{
|
||||||
if(!Connectivity.IsConnected)
|
if(!Connectivity.IsConnected)
|
||||||
{
|
{
|
||||||
@@ -132,5 +133,45 @@ namespace Bit.App.Repositories
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual async Task<ApiResult<ProfileResponse>> GetProfileAsync()
|
||||||
|
{
|
||||||
|
if(!Connectivity.IsConnected)
|
||||||
|
{
|
||||||
|
return HandledNotConnected<ProfileResponse>();
|
||||||
|
}
|
||||||
|
|
||||||
|
var tokenStateResponse = await HandleTokenStateAsync<ProfileResponse>();
|
||||||
|
if(!tokenStateResponse.Succeeded)
|
||||||
|
{
|
||||||
|
return tokenStateResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
using(var client = HttpService.Client)
|
||||||
|
{
|
||||||
|
var requestMessage = new TokenHttpRequestMessage()
|
||||||
|
{
|
||||||
|
Method = HttpMethod.Get,
|
||||||
|
RequestUri = new Uri(client.BaseAddress, string.Concat(ApiRoute, "/profile")),
|
||||||
|
};
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var response = await client.SendAsync(requestMessage).ConfigureAwait(false);
|
||||||
|
if(!response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
return await HandleErrorAsync<ProfileResponse>(response).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
var responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||||
|
var responseObj = JsonConvert.DeserializeObject<ProfileResponse>(responseContent);
|
||||||
|
return ApiResult<ProfileResponse>.Success(responseObj, response.StatusCode);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return HandledWebException<ProfileResponse>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ using Bit.App.Models.Api;
|
|||||||
using Plugin.Settings.Abstractions;
|
using Plugin.Settings.Abstractions;
|
||||||
using Bit.App.Models;
|
using Bit.App.Models;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
namespace Bit.App.Services
|
namespace Bit.App.Services
|
||||||
{
|
{
|
||||||
@@ -21,6 +23,7 @@ namespace Bit.App.Services
|
|||||||
private readonly ISettings _settings;
|
private readonly ISettings _settings;
|
||||||
private readonly ICryptoService _cryptoService;
|
private readonly ICryptoService _cryptoService;
|
||||||
private readonly IConnectApiRepository _connectApiRepository;
|
private readonly IConnectApiRepository _connectApiRepository;
|
||||||
|
private readonly IAccountsApiRepository _accountsApiRepository;
|
||||||
private readonly IAppIdService _appIdService;
|
private readonly IAppIdService _appIdService;
|
||||||
private readonly IDeviceInfoService _deviceInfoService;
|
private readonly IDeviceInfoService _deviceInfoService;
|
||||||
|
|
||||||
@@ -35,6 +38,7 @@ namespace Bit.App.Services
|
|||||||
ISettings settings,
|
ISettings settings,
|
||||||
ICryptoService cryptoService,
|
ICryptoService cryptoService,
|
||||||
IConnectApiRepository connectApiRepository,
|
IConnectApiRepository connectApiRepository,
|
||||||
|
IAccountsApiRepository accountsApiRepository,
|
||||||
IAppIdService appIdService,
|
IAppIdService appIdService,
|
||||||
IDeviceInfoService deviceInfoService)
|
IDeviceInfoService deviceInfoService)
|
||||||
{
|
{
|
||||||
@@ -43,6 +47,7 @@ namespace Bit.App.Services
|
|||||||
_settings = settings;
|
_settings = settings;
|
||||||
_cryptoService = cryptoService;
|
_cryptoService = cryptoService;
|
||||||
_connectApiRepository = connectApiRepository;
|
_connectApiRepository = connectApiRepository;
|
||||||
|
_accountsApiRepository = accountsApiRepository;
|
||||||
_appIdService = appIdService;
|
_appIdService = appIdService;
|
||||||
_deviceInfoService = deviceInfoService;
|
_deviceInfoService = deviceInfoService;
|
||||||
}
|
}
|
||||||
@@ -230,7 +235,7 @@ namespace Bit.App.Services
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessLoginSuccess(key, response.Result);
|
await ProcessLoginSuccessAsync(key, response.Result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -257,11 +262,11 @@ namespace Bit.App.Services
|
|||||||
}
|
}
|
||||||
|
|
||||||
result.Success = true;
|
result.Success = true;
|
||||||
ProcessLoginSuccess(key, response.Result);
|
await ProcessLoginSuccessAsync(key, response.Result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ProcessLoginSuccess(CryptoKey key, TokenResponse response)
|
private async Task ProcessLoginSuccessAsync(CryptoKey key, TokenResponse response)
|
||||||
{
|
{
|
||||||
if(response.PrivateKey != null)
|
if(response.PrivateKey != null)
|
||||||
{
|
{
|
||||||
@@ -274,6 +279,30 @@ namespace Bit.App.Services
|
|||||||
UserId = _tokenService.TokenUserId;
|
UserId = _tokenService.TokenUserId;
|
||||||
Email = _tokenService.TokenEmail;
|
Email = _tokenService.TokenEmail;
|
||||||
_settings.AddOrUpdateValue(Constants.LastLoginEmail, Email);
|
_settings.AddOrUpdateValue(Constants.LastLoginEmail, Email);
|
||||||
|
|
||||||
|
if(response.PrivateKey != null)
|
||||||
|
{
|
||||||
|
var profile = await _accountsApiRepository.GetProfileAsync();
|
||||||
|
var orgKeysDict = new Dictionary<string, CryptoKey>();
|
||||||
|
|
||||||
|
if(profile.Succeeded && (profile.Result.Organizations?.Any() ?? false))
|
||||||
|
{
|
||||||
|
foreach(var org in profile.Result.Organizations)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var decBytes = _cryptoService.RsaDecryptToBytes(new CipherString(org.Key), null);
|
||||||
|
orgKeysDict.Add(org.Id, new CryptoKey(decBytes));
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Debug.WriteLine($"Cannot set org key {org.Id}. Decryption failed.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_cryptoService.OrgKeys = orgKeysDict;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ namespace Bit.App.Services
|
|||||||
private CryptoKey _key;
|
private CryptoKey _key;
|
||||||
private CryptoKey _legacyEtmKey;
|
private CryptoKey _legacyEtmKey;
|
||||||
private CryptoKey _previousKey;
|
private CryptoKey _previousKey;
|
||||||
private IDictionary<Guid, CryptoKey> _orgKeys;
|
private IDictionary<string, CryptoKey> _orgKeys;
|
||||||
private byte[] _privateKey;
|
private byte[] _privateKey;
|
||||||
|
|
||||||
public CryptoService(
|
public CryptoService(
|
||||||
@@ -127,7 +127,7 @@ namespace Bit.App.Services
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IDictionary<Guid, CryptoKey> OrgKeys
|
public IDictionary<string, CryptoKey> OrgKeys
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@@ -139,8 +139,8 @@ namespace Bit.App.Services
|
|||||||
var orgKeysDictJson = Encoding.UTF8.GetString(orgKeysDictBytes, 0, orgKeysDictBytes.Length);
|
var orgKeysDictJson = Encoding.UTF8.GetString(orgKeysDictBytes, 0, orgKeysDictBytes.Length);
|
||||||
if(!string.IsNullOrWhiteSpace(orgKeysDictJson))
|
if(!string.IsNullOrWhiteSpace(orgKeysDictJson))
|
||||||
{
|
{
|
||||||
_orgKeys = new Dictionary<Guid, CryptoKey>();
|
_orgKeys = new Dictionary<string, CryptoKey>();
|
||||||
var orgKeysDict = JsonConvert.DeserializeObject<IDictionary<Guid, byte[]>>(orgKeysDictJson);
|
var orgKeysDict = JsonConvert.DeserializeObject<IDictionary<string, byte[]>>(orgKeysDictJson);
|
||||||
foreach(var item in orgKeysDict)
|
foreach(var item in orgKeysDict)
|
||||||
{
|
{
|
||||||
_orgKeys.Add(item.Key, new CryptoKey(item.Value));
|
_orgKeys.Add(item.Key, new CryptoKey(item.Value));
|
||||||
@@ -155,7 +155,7 @@ namespace Bit.App.Services
|
|||||||
{
|
{
|
||||||
if(value != null && value.Any())
|
if(value != null && value.Any())
|
||||||
{
|
{
|
||||||
var dict = new Dictionary<Guid, byte[]>();
|
var dict = new Dictionary<string, byte[]>();
|
||||||
foreach(var item in value)
|
foreach(var item in value)
|
||||||
{
|
{
|
||||||
dict.Add(item.Key, item.Value.Key);
|
dict.Add(item.Key, item.Value.Key);
|
||||||
@@ -180,7 +180,7 @@ namespace Bit.App.Services
|
|||||||
PrivateKey = bytes;
|
PrivateKey = bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CryptoKey GetOrgKey(Guid orgId)
|
public CryptoKey GetOrgKey(string orgId)
|
||||||
{
|
{
|
||||||
if(OrgKeys == null || !OrgKeys.ContainsKey(orgId))
|
if(OrgKeys == null || !OrgKeys.ContainsKey(orgId))
|
||||||
{
|
{
|
||||||
@@ -190,7 +190,7 @@ namespace Bit.App.Services
|
|||||||
return OrgKeys[orgId];
|
return OrgKeys[orgId];
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClearOrgKey(Guid orgId)
|
public void ClearOrgKey(string orgId)
|
||||||
{
|
{
|
||||||
var localOrgKeys = OrgKeys;
|
var localOrgKeys = OrgKeys;
|
||||||
if(localOrgKeys == null || !localOrgKeys.ContainsKey(orgId))
|
if(localOrgKeys == null || !localOrgKeys.ContainsKey(orgId))
|
||||||
@@ -210,7 +210,7 @@ namespace Bit.App.Services
|
|||||||
PrivateKey = null;
|
PrivateKey = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CryptoKey AddOrgKey(Guid orgId, CipherString encOrgKey, byte[] privateKey)
|
public CryptoKey AddOrgKey(string orgId, CipherString encOrgKey, byte[] privateKey)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ namespace Bit.App.Services
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var loginUriString = new CipherString(login.Uri).Decrypt();
|
var loginUriString = new CipherString(login.Uri).Decrypt(login.OrganizationId);
|
||||||
if(string.IsNullOrWhiteSpace(loginUriString))
|
if(string.IsNullOrWhiteSpace(loginUriString))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -217,7 +217,7 @@ namespace Bit.App.Services
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var accountRevisionDate = await _accountsApiRepository.GetAccountRevisionDate();
|
var accountRevisionDate = await _accountsApiRepository.GetAccountRevisionDateAsync();
|
||||||
if(accountRevisionDate.Succeeded && accountRevisionDate.Result.HasValue &&
|
if(accountRevisionDate.Succeeded && accountRevisionDate.Result.HasValue &&
|
||||||
accountRevisionDate.Result.Value > lastSync)
|
accountRevisionDate.Result.Value > lastSync)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ namespace Bit.iOS.Extension.Models
|
|||||||
public LoginViewModel(Login login)
|
public LoginViewModel(Login login)
|
||||||
{
|
{
|
||||||
Id = login.Id;
|
Id = login.Id;
|
||||||
Name = login.Name?.Decrypt();
|
Name = login.Name?.Decrypt(login.OrganizationId);
|
||||||
Username = login.Username?.Decrypt();
|
Username = login.Username?.Decrypt(login.OrganizationId);
|
||||||
Password = login.Password?.Decrypt();
|
Password = login.Password?.Decrypt(login.OrganizationId);
|
||||||
Uri = login.Uri?.Decrypt();
|
Uri = login.Uri?.Decrypt(login.OrganizationId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
|
|||||||
Reference in New Issue
Block a user