Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Api/Auth/Controllers/EmergencyAccessController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
using Bit.Api.Auth.Models.Response;
using Bit.Api.Models.Response;
using Bit.Api.Vault.Models.Response;
using Bit.Core.Auth.Services;
using Bit.Core.Auth.UserFeatures.EmergencyAccess;
using Bit.Core.Exceptions;
using Bit.Core.Repositories;
using Bit.Core.Services;
Expand Down
2 changes: 1 addition & 1 deletion src/Api/Auth/Jobs/EmergencyAccessNotificationJob.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
๏ปฟ// FIXME: Update this file to be null safe and then delete the line below
#nullable disable

using Bit.Core.Auth.Services;
using Bit.Core.Auth.UserFeatures.EmergencyAccess;
using Bit.Core.Jobs;
using Quartz;

Expand Down
2 changes: 1 addition & 1 deletion src/Api/Auth/Jobs/EmergencyAccessTimeoutJob.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
๏ปฟ// FIXME: Update this file to be null safe and then delete the line below
#nullable disable

using Bit.Core.Auth.Services;
using Bit.Core.Auth.UserFeatures.EmergencyAccess;
using Bit.Core.Jobs;
using Quartz;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using Bit.Core.AdminConsole.Entities;
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Interfaces;
using Bit.Core.AdminConsole.Repositories;
using Bit.Core.Auth.Entities;
using Bit.Core.Auth.Enums;
using Bit.Core.Auth.Models.Business.Tokenables;
using Bit.Core.Auth.Models.Data;
Expand All @@ -19,7 +18,7 @@
using Bit.Core.Vault.Repositories;
using Bit.Core.Vault.Services;

namespace Bit.Core.Auth.Services;
namespace Bit.Core.Auth.UserFeatures.EmergencyAccess;

public class EmergencyAccessService : IEmergencyAccessService
{
Expand Down Expand Up @@ -61,7 +60,7 @@ public EmergencyAccessService(
_removeOrganizationUserCommand = removeOrganizationUserCommand;
}

public async Task<EmergencyAccess> InviteAsync(User grantorUser, string emergencyContactEmail, EmergencyAccessType accessType, int waitTime)
public async Task<Entities.EmergencyAccess> InviteAsync(User grantorUser, string emergencyContactEmail, EmergencyAccessType accessType, int waitTime)
{
if (!await _userService.CanAccessPremium(grantorUser))
{
Expand All @@ -73,7 +72,7 @@ public async Task<EmergencyAccess> InviteAsync(User grantorUser, string emergenc
throw new BadRequestException("You cannot use Emergency Access Takeover because you are using Key Connector.");
}

var emergencyAccess = new EmergencyAccess
var emergencyAccess = new Entities.EmergencyAccess
{
GrantorId = grantorUser.Id,
Email = emergencyContactEmail.ToLowerInvariant(),
Expand Down Expand Up @@ -113,7 +112,7 @@ public async Task ResendInviteAsync(User grantorUser, Guid emergencyAccessId)
await SendInviteAsync(emergencyAccess, NameOrEmail(grantorUser));
}

public async Task<EmergencyAccess> AcceptUserAsync(Guid emergencyAccessId, User granteeUser, string token, IUserService userService)
public async Task<Entities.EmergencyAccess> AcceptUserAsync(Guid emergencyAccessId, User granteeUser, string token, IUserService userService)
{
var emergencyAccess = await _emergencyAccessRepository.GetByIdAsync(emergencyAccessId);
if (emergencyAccess == null)
Expand Down Expand Up @@ -175,7 +174,7 @@ public async Task DeleteAsync(Guid emergencyAccessId, Guid grantorId)
await _emergencyAccessRepository.DeleteAsync(emergencyAccess);
}

public async Task<EmergencyAccess> ConfirmUserAsync(Guid emergencyAccessId, string key, Guid grantorId)
public async Task<Entities.EmergencyAccess> ConfirmUserAsync(Guid emergencyAccessId, string key, Guid grantorId)
{
var emergencyAccess = await _emergencyAccessRepository.GetByIdAsync(emergencyAccessId);
if (emergencyAccess == null || emergencyAccess.Status != EmergencyAccessStatusType.Accepted ||
Expand All @@ -201,7 +200,7 @@ public async Task<EmergencyAccess> ConfirmUserAsync(Guid emergencyAccessId, stri
return emergencyAccess;
}

public async Task SaveAsync(EmergencyAccess emergencyAccess, User grantorUser)
public async Task SaveAsync(Entities.EmergencyAccess emergencyAccess, User grantorUser)
{
if (!await _userService.CanAccessPremium(grantorUser))
{
Expand Down Expand Up @@ -311,7 +310,7 @@ public async Task<ICollection<Policy>> GetPoliciesAsync(Guid emergencyAccessId,
}

// TODO PM-21687: rename this to something like InitiateRecoveryTakeoverAsync
public async Task<(EmergencyAccess, User)> TakeoverAsync(Guid emergencyAccessId, User granteeUser)
public async Task<(Entities.EmergencyAccess, User)> TakeoverAsync(Guid emergencyAccessId, User granteeUser)
{
var emergencyAccess = await _emergencyAccessRepository.GetByIdAsync(emergencyAccessId);

Expand Down Expand Up @@ -429,7 +428,7 @@ public async Task<AttachmentResponseData> GetAttachmentDownloadAsync(Guid emerge
return await _cipherService.GetAttachmentDownloadDataAsync(cipher, attachmentId);
}

private async Task SendInviteAsync(EmergencyAccess emergencyAccess, string invitingUsersName)
private async Task SendInviteAsync(Entities.EmergencyAccess emergencyAccess, string invitingUsersName)
{
var token = _dataProtectorTokenizer.Protect(new EmergencyAccessInviteTokenable(emergencyAccess, _globalSettings.OrganizationInviteExpirationHours));
await _mailService.SendEmergencyAccessInviteEmailAsync(emergencyAccess, invitingUsersName, token);
Expand All @@ -449,7 +448,7 @@ private static string NameOrEmail(User user)
*/
//TODO PM-21687: this IsValidRequest() checks the validity based on the granteeUser. There should be a complementary method for the grantorUser
private static bool IsValidRequest(
EmergencyAccess availableAccess,
Entities.EmergencyAccess availableAccess,
User requestingUser,
EmergencyAccessType requestedAccessType)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
๏ปฟusing Bit.Core.AdminConsole.Entities;
using Bit.Core.Auth.Entities;
using Bit.Core.Auth.Enums;
using Bit.Core.Auth.Models.Data;
using Bit.Core.Entities;
using Bit.Core.Enums;
using Bit.Core.Services;
using Bit.Core.Vault.Models.Data;

namespace Bit.Core.Auth.Services;
namespace Bit.Core.Auth.UserFeatures.EmergencyAccess;

public interface IEmergencyAccessService
{
Expand All @@ -20,7 +19,7 @@ public interface IEmergencyAccessService
/// <param name="accessType">Type of emergency access allowed to the emergency contact</param>
/// <param name="waitTime">The amount of time to pass before the invite is auto confirmed</param>
/// <returns>a new Emergency Access object</returns>
Task<EmergencyAccess> InviteAsync(User grantorUser, string emergencyContactEmail, EmergencyAccessType accessType, int waitTime);
Task<Entities.EmergencyAccess> InviteAsync(User grantorUser, string emergencyContactEmail, EmergencyAccessType accessType, int waitTime);
/// <summary>
/// Sends an invite to the emergency contact associated with the emergency access id.
/// </summary>
Expand All @@ -37,7 +36,7 @@ public interface IEmergencyAccessService
/// <param name="token">the tokenable that was sent via email</param>
/// <param name="userService">service dependency</param>
/// <returns>void</returns>
Task<EmergencyAccess> AcceptUserAsync(Guid emergencyAccessId, User granteeUser, string token, IUserService userService);
Task<Entities.EmergencyAccess> AcceptUserAsync(Guid emergencyAccessId, User granteeUser, string token, IUserService userService);
/// <summary>
/// The creator of the emergency access request can delete the request.
/// </summary>
Expand All @@ -53,7 +52,7 @@ public interface IEmergencyAccessService
/// <param name="key">The grantor user key encrypted by the grantee public key; grantee.PubicKey(grantor.User.Key)</param>
/// <param name="grantorId">Id of grantor user</param>
/// <returns>emergency access object associated with the Id passed in</returns>
Task<EmergencyAccess> ConfirmUserAsync(Guid emergencyAccessId, string key, Guid grantorId);
Task<Entities.EmergencyAccess> ConfirmUserAsync(Guid emergencyAccessId, string key, Guid grantorId);
/// <summary>
/// Fetches an emergency access object. The grantor user must own the object being fetched.
/// </summary>
Expand All @@ -67,7 +66,7 @@ public interface IEmergencyAccessService
/// <param name="emergencyAccess">emergency access entity being updated</param>
/// <param name="grantorUser">grantor user</param>
/// <returns>void</returns>
Task SaveAsync(EmergencyAccess emergencyAccess, User grantorUser);
Task SaveAsync(Entities.EmergencyAccess emergencyAccess, User grantorUser);
/// <summary>
/// Initiates the recovery process. For either Takeover or view. Will send an email to the Grantor User notifying of the initiation.
/// </summary>
Expand Down Expand Up @@ -107,7 +106,7 @@ public interface IEmergencyAccessService
/// <param name="emergencyAccessId">Id of entity being accessed</param>
/// <param name="granteeUser">grantee user of the emergency access entity</param>
/// <returns>emergency access entity and the grantorUser</returns>
Task<(EmergencyAccess, User)> TakeoverAsync(Guid emergencyAccessId, User granteeUser);
Task<(Entities.EmergencyAccess, User)> TakeoverAsync(Guid emergencyAccessId, User granteeUser);
/// <summary>
/// Updates the grantor's password hash and updates the key for the EmergencyAccess entity.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
๏ปฟusing Bit.Core.Platform.Mail.Mailer;

namespace Bit.Core.Auth.UserFeatures.EmergencyAccess.Mail;

public class EmergencyAccessRemoveGranteesMailView : BaseMailView
{
public required IEnumerable<string> RemovedGranteeNames { get; set; }
public string EmergencyAccessHelpPageUrl => "https://bitwarden.com/help/emergency-access/";
}

public class EmergencyAccessRemoveGranteesMail : BaseMail<EmergencyAccessRemoveGranteesMailView>
{
public override string Subject { get; set; } = "Emergency contacts removed";
}
Loading
Loading