Skip to content
Merged
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
6 changes: 5 additions & 1 deletion src/Api/appsettings.Development.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,7 +18,11 @@
"Token": "745f040659edff0ce87b545567da72d2",
"SenderName": "ProFile",
"SenderEmail": "profile@ezarp.dev",
"TemplateUuid": "9d6a8f25-65e9-4819-be7d-106ce077acf1"
"TemplateUuids": {
"ResetPassword": "9d6a8f25-65e9-4819-be7d-106ce077acf1",
"ShareEntry": "ad69df89-885a-48fb-b8f6-6d06af1a54e3",
"Request": "bce7e60c-d848-4f80-af96-cccd264dcc32"
}
},
"Seed": true,
"Serilog" : {
Expand Down
3 changes: 3 additions & 0 deletions src/Application/Borrows/Commands/BorrowDocument.cs
Original file line numberDiff line numberDiff line change
Expand Up@@ -157,7 +157,10 @@ is BorrowRequestStatus.Approved
entity.Status = BorrowRequestStatus.Approved;
}


var result = await _context.Borrows.AddAsync(entity, cancellationToken);
entity.AddDomainEvent(new RequestCreated($"{user.FirstName} {user.LastName}", "borrow request", "borrow",
document.Title, entity.Id, request.BorrowReason, document.Id));
await _context.SaveChangesAsync(cancellationToken);
using (Logging.PushProperties("Request", document.Id, user.Id))
{
Expand Down
4 changes: 3 additions & 1 deletion src/Application/Common/Interfaces/IMailService.cs
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,5 +4,7 @@ namespace Application.Common.Interfaces;

public interface IMailService
{
bool SendResetPasswordHtmlMail(string userEmail, string temporaryPassword);
bool SendResetPasswordHtmlMail(string userEmail, string temporaryPassword, string tokenHash);
bool SendShareEntryHtmlMail(bool isDirectory, string name, string sharerName, string operation, string ownerName, string email, string path);
bool SendCreateRequestHtmlMail(string userName, string requestType, string operation, string documentName, string reason, Guid documentId, string email);
}
42 changes: 38 additions & 4 deletions src/Application/Common/Models/HtmlMailData.cs
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,7 +11,7 @@ public class HtmlMailData
[JsonPropertyName("template_uuid")]
public string TemplateUuid { get; set; }
[JsonPropertyName("template_variables")]
public TemplateVariables TemplateVariables { get; set; }
public object TemplateVariables { get; set; }
}

public class From
Expand All@@ -28,12 +28,46 @@ public class To
public string Email { get; set; }
}

public class TemplateVariables
public class ResetPasswordTemplateVariables
{
[JsonPropertyName("user_email")]
public string UserEmail { get; set; }
[JsonPropertyName("reset_password_token_hash")]
public string ResetPasswordTokenHash { get; set; }
[JsonPropertyName("token_hash")]
public string TokenHash { get; set; }
[JsonPropertyName("user_password")]
public string UserPassword { get; set; }
}

public class ShareEntryTemplateVariables
{
[JsonPropertyName("entry_type")]
public string EntryType { get; set; }
[JsonPropertyName("entry_name")]
public string EntryName { get; set; }
[JsonPropertyName("sharer_name")]
public string SharerName { get; set; }
[JsonPropertyName("operation")]
public string Operation { get; set; }
[JsonPropertyName("owner_name")]
public string OwnerName { get; set; }
[JsonPropertyName("path")]
public string Path { get; set; }
}

public class CreateRequestTemplateVariables
{
[JsonPropertyName("user_name")]
public string UserName { get; set; }
[JsonPropertyName("request_type")]
public string RequestType { get; set; }
[JsonPropertyName("operation")]
public string Operation { get; set; }
[JsonPropertyName("document_name")]
public string DocumentName { get; set; }
[JsonPropertyName("reason")]
public string Reason { get; set; }
[JsonPropertyName("path")]
public string Path { get; set; }
[JsonPropertyName("id")]
public string Id { get; set; }
}
37 changes: 37 additions & 0 deletions src/Application/Documents/EventHandlers/RequestCreatedHandler.cs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
using Application.Common.Interfaces;
using Domain.Events;
using MediatR;
using Microsoft.EntityFrameworkCore;

namespace Application.Documents.EventHandlers;

public class RequestCreatedHandler : INotificationHandler<RequestCreated>
{
private readonly IApplicationDbContext _context;
private readonly IMailService _mailService;

public RequestCreatedHandler(IMailService mailService, IApplicationDbContext context)
{
_mailService = mailService;
_context = context;
}

public async Task Handle(RequestCreated notification, CancellationToken cancellationToken)
{
var document = await _context.Documents
.Include(x => x.Department)
.FirstOrDefaultAsync(x => x.Id == notification.DocumentId, cancellationToken);

var departmentId = document!.Department!.Id;

var staff = await _context.Staffs
.Include(x => x.User)
.FirstOrDefaultAsync(x => x.Room!.DepartmentId == departmentId, cancellationToken);

if (staff is not null)
{
_mailService.SendCreateRequestHtmlMail(notification.UserName, notification.RequestType, notification.Operation,
notification.DocumentTitle, notification.Reason, notification.RequestId, staff.User.Email);
}
}
}
10 changes: 10 additions & 0 deletions src/Application/Entries/Commands/ShareEntry.cs
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,6 +7,7 @@
using AutoMapper;
using Domain.Entities;
using Domain.Entities.Digital;
using Domain.Events;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
Expand DownExpand Up@@ -103,6 +104,15 @@ public async Task<EntryPermissionDto> Handle(Command request, CancellationToken
await GrantOrRevokePermission(childEntry, user, childAllowOperations, request.ExpiryDate, false, cancellationToken);
}
}

if (request.CanView)
{
var p = "view";

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p for permission LMAO!
We are in hurry so yeh...
As long as it works.

if (request.CanEdit) p = "edit";
entry.AddDomainEvent(new ShareEntryEvent(entry.Name,
request.CurrentUser.FirstName + request.CurrentUser.LastName,
entry.Owner.FirstName + entry.Owner.LastName, user.Email, entry.IsDirectory, p, entry.Id.ToString()));
}
await _context.SaveChangesAsync(cancellationToken);
using (Logging.PushProperties(nameof(Entry), entry.Id, request.CurrentUser.Id))
{
Expand Down
21 changes: 21 additions & 0 deletions src/Application/Entries/EventHandlers/ShareEntryEventHandler.cs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
using Application.Common.Interfaces;
using Domain.Events;
using MediatR;

namespace Application.Entries.EventHandlers;

public class ShareEntryEventHandler : INotificationHandler<ShareEntryEvent>
{
private readonly IMailService _mailService;

public ShareEntryEventHandler(IMailService mailService)
{
_mailService = mailService;
}

public async Task Handle(ShareEntryEvent notification, CancellationToken cancellationToken)
{
_mailService.SendShareEntryHtmlMail(notification.IsDirectory, notification.EntryName, notification.SharerName,
notification.Operation, notification.OwnerName, notification.SharedUserEmail, notification.Path);
}
}
Original file line numberDiff line numberDiff line change
Expand Up@@ -35,6 +35,6 @@ public async Task Handle(UserCreatedEvent notification, CancellationToken cancel
await _authDbContext.ResetPasswordTokens.AddAsync(resetPasswordToken, cancellationToken);
await _authDbContext.SaveChangesAsync(cancellationToken);

_mailService.SendResetPasswordHtmlMail(notification.User.Email, notification.Password);
_mailService.SendResetPasswordHtmlMail(notification.User.Email, notification.Password, resetPasswordToken.TokenHash);
}
}
24 changes: 24 additions & 0 deletions src/Domain/Events/RequestCreated.cs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
using Domain.Common;

namespace Domain.Events;

public class RequestCreated : BaseEvent
{
public RequestCreated(string userName, string requestType, string operation, string documentTitle, Guid requestId, string reason, Guid documentId)
{
UserName = userName;
RequestType = requestType;
Operation = operation;
DocumentTitle = documentTitle;
RequestId = requestId;
Reason = reason;
DocumentId = documentId;
}
public string UserName { get; }
public string RequestType { get; }
public string Operation { get; }
public string DocumentTitle { get; }
public string Reason { get; }
public Guid DocumentId { get; }
public Guid RequestId { get; }
}
25 changes: 25 additions & 0 deletions src/Domain/Events/ShareEntryEvent.cs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
using Domain.Common;

namespace Domain.Events;

public class ShareEntryEvent : BaseEvent
{
public ShareEntryEvent(string entryName, string sharerName, string ownerName, string sharedUserEmail, bool isDirectory, string operation, string path)
{
EntryName = entryName;
SharerName = sharerName;
OwnerName = ownerName;
SharedUserEmail = sharedUserEmail;
IsDirectory = isDirectory;
Operation = operation;
Path = path;
}

public string EntryName { get; }
public string SharerName { get; }
public string OwnerName { get; }
public string SharedUserEmail { get; }
public bool IsDirectory { get; }
public string Operation { get; }
public string Path { get; }
}
2 changes: 1 addition & 1 deletion src/Infrastructure/ConfigureServices.cs
Original file line numberDiff line numberDiff line change
Expand Up@@ -108,7 +108,7 @@ private static IServiceCollection AddMailService(this IServiceCollection service
options.Token = mailSettings!.Token;
options.SenderEmail = mailSettings!.SenderEmail;
options.SenderName = mailSettings!.SenderName;
options.TemplateUuid = mailSettings!.TemplateUuid;
options.TemplateUuids = mailSettings!.TemplateUuids;
});

services.AddTransient<IMailService, MailService>();
Expand Down
90 changes: 87 additions & 3 deletions src/Infrastructure/Services/MailService.cs
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,7 +17,7 @@ public MailService(IOptions<MailSettings> mailSettingsOptions)
_mailSettings = mailSettingsOptions.Value;
}

public bool SendResetPasswordHtmlMail(string userEmail, string temporaryPassword)
public bool SendResetPasswordHtmlMail(string userEmail, string temporaryPassword, string tokenHash)
{
var data = new HtmlMailData()
{
Expand All@@ -30,11 +30,95 @@ public bool SendResetPasswordHtmlMail(string userEmail, string temporaryPassword
{
new (){ Email = userEmail },
},
TemplateUuid = _mailSettings.TemplateUuid,
TemplateVariables = new TemplateVariables()
TemplateUuid = _mailSettings.TemplateUuids.ResetPassword,
TemplateVariables = new ResetPasswordTemplateVariables()
{
UserEmail = userEmail,
UserPassword = temporaryPassword,
TokenHash = tokenHash
},
};

var json = JsonSerializer.Serialize(data, new JsonSerializerOptions(JsonSerializerDefaults.Web));

var client = new RestClient(_mailSettings.ClientUrl);
var request = new RestRequest
{
Method = Method.Post
};

request.AddHeader("Authorization", $"{JwtBearerDefaults.AuthenticationScheme} {_mailSettings.Token}");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", json, ParameterType.RequestBody);
var response = client.Execute(request);
return response.IsSuccessStatusCode;
}

public bool SendShareEntryHtmlMail(bool isDirectory, string name, string sharerName, string operation, string ownerName,
string email, string path)
{
var data = new HtmlMailData()
{
From = new From()
{
Email = _mailSettings.SenderEmail,
Name = _mailSettings.SenderName,
},
To = new To[]
{
new (){ Email = email },
},
TemplateUuid = _mailSettings.TemplateUuids.ShareEntry,
TemplateVariables = new ShareEntryTemplateVariables()
{
EntryName = name,
Operation = operation,
EntryType = isDirectory ? "Folder" : "File",
OwnerName = ownerName,
SharerName = sharerName,
Path = path
},
};

var json = JsonSerializer.Serialize(data, new JsonSerializerOptions(JsonSerializerDefaults.Web));

var client = new RestClient(_mailSettings.ClientUrl);
var request = new RestRequest
{
Method = Method.Post
};

request.AddHeader("Authorization", $"{JwtBearerDefaults.AuthenticationScheme} {_mailSettings.Token}");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", json, ParameterType.RequestBody);
var response = client.Execute(request);
return response.IsSuccessStatusCode;
}

public bool SendCreateRequestHtmlMail(string userName, string requestType, string operation, string documentName,
string reason, Guid documentId, string email)
{
var data = new HtmlMailData()
{
From = new From()
{
Email = _mailSettings.SenderEmail,
Name = _mailSettings.SenderName,
},
To = new To[]
{
new (){ Email = email },
},
TemplateUuid = _mailSettings.TemplateUuids.Request,
TemplateVariables = new CreateRequestTemplateVariables()
{
Operation = operation,
Reason = reason,
DocumentName = documentName,
UserName = userName,
Id = documentId.ToString(),
RequestType = requestType,
Path = !requestType.Equals("borrow request") ? "import/manage" : "requests"
},
};

Expand Down
10 changes: 9 additions & 1 deletion src/Infrastructure/Shared/MailSettings.cs
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,5 +6,13 @@ public class MailSettings
public string Token { get; set; }
public string SenderName { get; set; }
public string SenderEmail { get; set; }
public string TemplateUuid { get; set; }

public Template TemplateUuids { get; set; }
}

public class Template
{
public string ResetPassword { get; set; }
public string ShareEntry { get; set; }
public string Request { get; set; }
}
14 changes: 13 additions & 1 deletion tests/Application.Tests.Integration/CustomMailService.cs
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,7 +4,19 @@ namespace Application.Tests.Integration;

public class CustomMailService : IMailService
{
public bool SendResetPasswordHtmlMail(string userEmail, string temporaryPassword)
public bool SendResetPasswordHtmlMail(string userEmail, string temporaryPassword, string tokenHash)
{
return true;
}

public bool SendShareEntryHtmlMail(bool isDirectory, string name, string sharerName, string operation, string ownerName,
string email, string path)
{
return true;
}

public bool SendCreateRequestHtmlMail(string userName, string requestType, string operation, string documentName,
string reason, Guid documentId, string email)
{
return true;
}
Expand Down