mirror of
https://github.com/bitwarden/server.git
synced 2024-12-24 17:17:40 +01:00
email notifications on user approval process
This commit is contained in:
parent
1cf38397f3
commit
0b4ba6399b
@ -1,5 +1,6 @@
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Models.Table;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
@ -11,5 +12,7 @@ namespace Bit.Core.Services
|
||||
Task SendNoMasterPasswordHintEmailAsync(string email);
|
||||
Task SendMasterPasswordHintEmailAsync(string email, string hint);
|
||||
Task SendOrganizationInviteEmailAsync(string organizationName, OrganizationUser orgUser, string token);
|
||||
Task SendOrganizationAcceptedEmailAsync(string organizationName, string userEmail, IEnumerable<string> adminEmails);
|
||||
Task SendOrganizationConfirmedEmailAsync(string organizationName, string email);
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Models.Table;
|
||||
|
||||
@ -26,6 +27,16 @@ namespace Bit.Core.Services
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public Task SendOrganizationAcceptedEmailAsync(string organizationName, string userEmail, IEnumerable<string> adminEmails)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task SendOrganizationConfirmedEmailAsync(string organizationName, string email)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task SendOrganizationInviteEmailAsync(string organizationName, OrganizationUser orgUser, string token)
|
||||
{
|
||||
return Task.FromResult(0);
|
||||
|
@ -632,7 +632,7 @@ namespace Bit.Core.Services
|
||||
}
|
||||
|
||||
public async Task<OrganizationUser> InviteUserAsync(Guid organizationId, Guid invitingUserId, string email,
|
||||
Enums.OrganizationUserType type, IEnumerable<SubvaultUser> subvaults)
|
||||
OrganizationUserType type, IEnumerable<SubvaultUser> subvaults)
|
||||
{
|
||||
var organization = await _organizationRepository.GetByIdAsync(organizationId);
|
||||
if(organization == null)
|
||||
@ -667,7 +667,7 @@ namespace Bit.Core.Services
|
||||
Email = email,
|
||||
Key = null,
|
||||
Type = type,
|
||||
Status = Enums.OrganizationUserStatusType.Invited,
|
||||
Status = OrganizationUserStatusType.Invited,
|
||||
CreationDate = DateTime.UtcNow,
|
||||
RevisionDate = DateTime.UtcNow
|
||||
};
|
||||
@ -683,7 +683,7 @@ namespace Bit.Core.Services
|
||||
{
|
||||
var orgUser = await _organizationUserRepository.GetByIdAsync(organizationUserId);
|
||||
if(orgUser == null || orgUser.OrganizationId != organizationId ||
|
||||
orgUser.Status != Enums.OrganizationUserStatusType.Invited)
|
||||
orgUser.Status != OrganizationUserStatusType.Invited)
|
||||
{
|
||||
throw new BadRequestException("User invalid.");
|
||||
}
|
||||
@ -708,7 +708,7 @@ namespace Bit.Core.Services
|
||||
throw new BadRequestException("User invalid.");
|
||||
}
|
||||
|
||||
if(orgUser.Status != Enums.OrganizationUserStatusType.Invited)
|
||||
if(orgUser.Status != OrganizationUserStatusType.Invited)
|
||||
{
|
||||
throw new BadRequestException("Already accepted.");
|
||||
}
|
||||
@ -741,12 +741,12 @@ namespace Bit.Core.Services
|
||||
throw new BadRequestException("Invalid token.");
|
||||
}
|
||||
|
||||
orgUser.Status = Enums.OrganizationUserStatusType.Accepted;
|
||||
orgUser.Status = OrganizationUserStatusType.Accepted;
|
||||
orgUser.UserId = user.Id;
|
||||
orgUser.Email = null;
|
||||
await _organizationUserRepository.ReplaceAsync(orgUser);
|
||||
|
||||
// TODO: send email
|
||||
// TODO: send notification emails to org admins
|
||||
|
||||
return orgUser;
|
||||
}
|
||||
@ -761,12 +761,17 @@ namespace Bit.Core.Services
|
||||
throw new BadRequestException("User not valid.");
|
||||
}
|
||||
|
||||
orgUser.Status = Enums.OrganizationUserStatusType.Confirmed;
|
||||
orgUser.Status = OrganizationUserStatusType.Confirmed;
|
||||
orgUser.Key = key;
|
||||
orgUser.Email = null;
|
||||
await _organizationUserRepository.ReplaceAsync(orgUser);
|
||||
|
||||
// TODO: send email
|
||||
var user = await _userRepository.GetByIdAsync(orgUser.UserId.Value);
|
||||
var org = await _organizationRepository.GetByIdAsync(organizationId);
|
||||
if(user != null && org != null)
|
||||
{
|
||||
await _mailService.SendOrganizationConfirmedEmailAsync(org.Name, user.Email);
|
||||
}
|
||||
|
||||
return orgUser;
|
||||
}
|
||||
@ -779,7 +784,7 @@ namespace Bit.Core.Services
|
||||
}
|
||||
|
||||
var confirmedOwners = (await GetConfirmedOwnersAsync(user.OrganizationId)).ToList();
|
||||
if(user.Type != Enums.OrganizationUserType.Owner && confirmedOwners.Count == 1 && confirmedOwners[0].Id == user.Id)
|
||||
if(user.Type != OrganizationUserType.Owner && confirmedOwners.Count == 1 && confirmedOwners[0].Id == user.Id)
|
||||
{
|
||||
throw new BadRequestException("Organization must have at least one confirmed owner.");
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ using Bit.Core.Models.Table;
|
||||
using SendGrid;
|
||||
using SendGrid.Helpers.Mail;
|
||||
using System.Net;
|
||||
using System.Linq;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
@ -16,6 +17,8 @@ namespace Bit.Core.Services
|
||||
private const string NoMasterPasswordHintTemplateId = "136eb299-e102-495a-88bd-f96736eea159";
|
||||
private const string MasterPasswordHintTemplateId = "be77cfde-95dd-4cb9-b5e0-8286b53885f1";
|
||||
private const string OrganizationInviteTemplateId = "1eff5512-e36c-49a8-b9e2-2b215d6bbced";
|
||||
private const string OrganizationAcceptedTemplateId = "28f7f741-598e-449c-85fe-601e1cc32ba3";
|
||||
private const string OrganizationConfirmedTemplateId = "a8afe2a0-6161-4eb9-b40c-08a7f520ec50";
|
||||
|
||||
private const string AdministrativeCategoryName = "Administrative";
|
||||
private const string MarketingCategoryName = "Marketing";
|
||||
@ -101,7 +104,33 @@ namespace Bit.Core.Services
|
||||
message.AddSubstitution("{{token}}", token);
|
||||
message.AddSubstitution("{{email}}", WebUtility.UrlEncode(orgUser.Email));
|
||||
message.AddSubstitution("{{organizationNameUrlEncoded}}", WebUtility.UrlEncode(organizationName));
|
||||
message.AddCategories(new List<string> { AdministrativeCategoryName, "Organization Invite" });
|
||||
message.AddCategories(new List<string> { AdministrativeCategoryName, "Organization User Invite" });
|
||||
|
||||
await _client.SendEmailAsync(message);
|
||||
}
|
||||
|
||||
public async Task SendOrganizationAcceptedEmailAsync(string organizationName, string userEmail,
|
||||
IEnumerable<string> adminEmails)
|
||||
{
|
||||
var message = CreateDefaultMessage(OrganizationAcceptedTemplateId);
|
||||
|
||||
message.Subject = $"User {userEmail} Has Accepted Invite";
|
||||
message.AddTos(adminEmails.Select(e => new EmailAddress(e)).ToList());
|
||||
message.AddSubstitution("{{userEmail}}", userEmail);
|
||||
message.AddSubstitution("{{organizationName}}", organizationName);
|
||||
message.AddCategories(new List<string> { AdministrativeCategoryName, "Organization User Accepted" });
|
||||
|
||||
await _client.SendEmailAsync(message);
|
||||
}
|
||||
|
||||
public async Task SendOrganizationConfirmedEmailAsync(string organizationName, string email)
|
||||
{
|
||||
var message = CreateDefaultMessage(OrganizationConfirmedTemplateId);
|
||||
|
||||
message.Subject = $"You Have Been Confirmed To {organizationName}";
|
||||
message.AddTo(new EmailAddress(email));
|
||||
message.AddSubstitution("{{organizationName}}", organizationName);
|
||||
message.AddCategories(new List<string> { AdministrativeCategoryName, "Organization User Confirmed" });
|
||||
|
||||
await _client.SendEmailAsync(message);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user