Skip to content

Commit

Permalink
Merge branch 'develop' into feature/ARPA-1002-create-endpoint-to-expo…
Browse files Browse the repository at this point in the history
…rt-appointments
  • Loading branch information
wolfgangroese authored Apr 7, 2024
2 parents 27b2430 + 44c3b24 commit b7e095d
Show file tree
Hide file tree
Showing 25 changed files with 87 additions and 67 deletions.
39 changes: 19 additions & 20 deletions Orso.Arpa.Api/Orso.Arpa.Api.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -20,29 +20,28 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="AspNetCoreRateLimit" Version="5.0.0"/>
<PackageReference Include="HotChocolate.AspNetCore" Version="13.9.0"/>
<PackageReference Include="HotChocolate.AspNetCore.Authorization" Version="13.9.0"/>
<PackageReference Include="HotChocolate.Data" Version="13.9.0"/>
<PackageReference Include="HotChocolate.Data.EntityFramework" Version="13.9.0"/>
<PackageReference Include="Ical.Net" Version="4.2.0"/>
<PackageReference Include="MicroElements.Swashbuckle.FluentValidation" Version="6.0.0"/>
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.22.0"/>
<PackageReference Include="Microsoft.ApplicationInsights.NLogTarget" Version="2.22.0"/>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.2"/>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.2">
<PackageReference Include="AspNetCoreRateLimit" Version="5.0.0" />
<PackageReference Include="HotChocolate.AspNetCore" Version="13.9.0" />
<PackageReference Include="HotChocolate.AspNetCore.Authorization" Version="13.9.0" />
<PackageReference Include="HotChocolate.Data" Version="13.9.0" />
<PackageReference Include="HotChocolate.Data.EntityFramework" Version="13.9.0" />
<PackageReference Include="MicroElements.Swashbuckle.FluentValidation" Version="6.0.0" />
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.22.0" />
<PackageReference Include="Microsoft.ApplicationInsights.NLogTarget" Version="2.22.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="8.0.2"/>
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="8.0.1"/>
<PackageReference Include="NLog" Version="5.2.8"/>
<PackageReference Include="NLog.Web.AspNetCore" Version="5.3.8"/>
<PackageReference Include="NWebsec.AspNetCore.Middleware" Version="3.0.0"/>
<PackageReference Include="SixLabors.ImageSharp.Web" Version="3.1.0"/>
<PackageReference Include="SixLabors.ImageSharp.Web.Providers.Azure" Version="3.1.0"/>
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0"/>
<PackageReference Include="Yoh.Text.Json.NamingPolicies" Version="1.0.0"/>
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="8.0.3" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="8.0.2" />
<PackageReference Include="NLog" Version="5.2.8" />
<PackageReference Include="NLog.Web.AspNetCore" Version="5.3.8" />
<PackageReference Include="NWebsec.AspNetCore.Middleware" Version="3.0.0" />
<PackageReference Include="SixLabors.ImageSharp.Web" Version="3.1.1" />
<PackageReference Include="SixLabors.ImageSharp.Web.Providers.Azure" Version="3.1.1" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="Yoh.Text.Json.NamingPolicies" Version="1.0.0" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,15 +103,15 @@ public static IRuleBuilderOptions<T, string> RestrictedFreeText<T>(this IRuleBui
{
return ruleBuilder
.MaximumLength(maximumLength)
.Matches(@"^[a-zA-ZáàâäãåçéèêëíìîïñóòôöõúùûüýÿæœÁÀÂÄÃÅÇÉÈÊËÍÌÎÏÑÓÒÔÖÕÚÙÛÜÝŸÆŒß'\-.\s0-9\/(),$€#*%&„“"":;?!@\+]*$")
.Matches(@"^[a-zA-ZáàâäãåçéèêëíìîïñóòôöõúùûüýÿæœÁÀÂÄÃÅÇÉÈÊËÍÌÎÏÑÓÒÔÖÕÚÙÛÜÝŸÆŒß\p{IsCyrillic}'\-.\s0-9\/(),$€#*%&„“"":;?!@\+]*$")
.WithMessage("Invalid character supplied. Please use only alphanumeric and whitespace characters or one of the following: '-./(),$€#*%&„“\":;?!@+");
}

public static IRuleBuilderOptions<T, string> FreeText<T>(this IRuleBuilder<T, string> ruleBuilder, int maximumLength)
{
return ruleBuilder
.MaximumLength(maximumLength)
.Matches(@"^[a-zA-ZáàâäãåçéèêëíìîïñóòôöõúùûüýÿæœÁÀÂÄÃÅÇÉÈÊËÍÌÎÏÑÓÒÔÖÕÚÙÛÜÝŸÆŒß'\-.\s0-9\/(),$€#*%&„“"":;?!@\+\^°| +~_]*$")
.Matches(@"^[a-zA-ZáàâäãåçéèêëíìîïñóòôöõúùûüýÿæœÁÀÂÄÃÅÇÉÈÊËÍÌÎÏÑÓÒÔÖÕÚÙÛÜÝŸÆŒß\p{IsCyrillic}'\-.\s0-9\/(),$€#*%&„“"":;?!@\+\^°| +~_]*$")
.WithMessage("Invalid character supplied. Please use only alphanumeric and whitespace characters or one of the following: '-./(),$€#*%&„“\":;?!@+^°| +~_");
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Threading;
using System.Threading.Tasks;
using FluentValidation;
using FluentValidation.Results;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Orso.Arpa.Domain.AppointmentDomain.Model;
Expand Down Expand Up @@ -45,7 +46,7 @@ public Validator(IArpaContext arpaContext)
return;
}
});

RuleFor(x => x.ForceSending)
.CustomAsync(async (appointmentId, context, cancellation) =>
{
Expand Down Expand Up @@ -80,6 +81,10 @@ public async Task<Unit> Handle(Command request, CancellationToken cancellationTo
.Select(a => a.Id)
.ToListAsync(cancellationToken);

if(personIds.Count == 0) {
throw new ValidationException([new ValidationFailure(nameof(request.AppointmentId), "No persons are eligible for this appointment. Cannot send email to empty recipient list.")]);
}

List<Person> persons = await _arpaContext.Persons
.AsQueryable()
.Where(p => personIds.Contains(p.Id))
Expand All @@ -98,7 +103,9 @@ public async Task<Unit> Handle(Command request, CancellationToken cancellationTo
DateAndTime = $"{appointment.StartTime.ToGermanDateTimeString()} - {appointment.EndTime.ToGermanTimeString()}",
PublicDetails = appointment.PublicDetails ?? "- ohne -",
Venue = appointment.Venue?.ToString() ?? "- ohne -",
ArpaUrl = _jwtConfiguration.Audience
ArpaUrl = _jwtConfiguration.Audience,
Status = appointment.Status.ToString(),
Sections = string.Join(", ", appointment.SectionAppointments.Select(sa => sa.Section.ToString()))
};

await _emailSender.SendTemplatedEmailAsync(template, persons
Expand All @@ -109,4 +116,4 @@ await _emailSender.SendTemplatedEmailAsync(template, persons
}
}
}
}
}
2 changes: 1 addition & 1 deletion Orso.Arpa.Domain/AppointmentDomain/Model/Appointment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ internal void ClearVenue()

public override string ToString()
{
return CategoryId.HasValue ? $"{Category.ToString().ToUpperInvariant()}: {Name}" : Name;
return CategoryId.HasValue ? $"{Name} ({Category.ToString().ToUpperInvariant()})" : Name;
}
}
}
2 changes: 1 addition & 1 deletion Orso.Arpa.Domain/Orso.Arpa.Domain.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<PackageReference Include="Azure.Storage.Blobs" Version="12.19.1" />
<PackageReference Include="FluentValidation.AspNetCore" Version="11.3.0" />
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="11.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.2" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.3" />
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
</ItemGroup>

Expand Down
2 changes: 1 addition & 1 deletion Orso.Arpa.Domain/UserDomain/Commands/ConfirmEmail.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public async Task<Unit> Handle(Command request, CancellationToken cancellationTo

if (await _userManager.IsEmailConfirmedAsync(user))
{
throw new ValidationException(new[] { new ValidationFailure(nameof(request.Email), "The email address is already confirmed") });
throw new ValidationException([new ValidationFailure(nameof(request.Email), "The email address is already confirmed")]);
}

IdentityResult confirmEmailResult = await _userManager.ConfirmEmailAsync(user, request.Token);
Expand Down
4 changes: 2 additions & 2 deletions Orso.Arpa.Infrastructure/Orso.Arpa.Infrastructure.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@

<ItemGroup>
<PackageReference Include="Azure.Storage.Blobs" Version="12.19.1" />
<PackageReference Include="Microsoft.AspNetCore.Authorization" Version="8.0.2" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.3.1" />
<PackageReference Include="Microsoft.AspNetCore.Authorization" Version="8.0.3" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.5.0" />
</ItemGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion Orso.Arpa.Mail/Orso.Arpa.Mail.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="MailKit" Version="4.3.0" />
<PackageReference Include="MailKit" Version="4.4.0" />
</ItemGroup>

<ItemGroup>
Expand Down
2 changes: 2 additions & 0 deletions Orso.Arpa.Mail/Templates/AppointmentChangedByStaffTemplate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,7 @@ public class AppointmentChangedByStaffTemplate : BaseTemplate
public string PublicDetails { get; set; }
public string Venue { get; set; }
public string ArpaUrl { get; set; }
public string Sections { get; set; }
public string Status { get; set; }
}
}
16 changes: 10 additions & 6 deletions Orso.Arpa.Mail/Templates/Heml/Appointment_Changed_By_Staff.heml
Original file line number Diff line number Diff line change
Expand Up @@ -47,26 +47,30 @@
</column>
</row>
<h2>Hallo,</h2>
<h3>wir möchten dich über eine Terminaktualisierung in ARPA informieren.</h3>
<h3>Die neuen Daten lauten nun wie folgt:</h3>
<h3>In ARPA wurde dieser Termin aktualisiert:</h3>
<row>
<column small="7" large ="4">
<h4>Name:</h4>
<h4>Zeitpunkt:</h4>
<h4>Zielgruppe:</h4>
<h4>Termin:</h4>
<h4>Status:</h4>
<h4>Bezeichnung:</h4>
<h4>Ort:</h4>
<h4>Details:</h4>
</column>
<column small="5" large="8">
<h4>{{AppointmentName}}</h4>
<h4>{{Sections}}</h4>
<h4>{{DateAndTime}}</h4>
<h4>{{Status}}</h4>
<h4>{{AppointmentName}}</h4>
<h4>{{Venue}}</h4>
<p><i>{{PublicDetails}}</i></p>
</column>
</row>
<hr/>
<row>
<column>
<p>Für weitere Informationen und um ggf. deinen Teilnahmestatus anzupassen,
<p>Bitte beachte, dass eine Aktualisierung manchmal auch nur den Bereich “Details” betrifft.</p>
<p>Für weitere Informationen und um ggf. deinen Teilnahmestatus anzupassen,
logge dich in <a href="{{ArpaUrl}}" target="_blank">ARPA</a> ein.</p>
</column>
</row>
Expand Down
16 changes: 10 additions & 6 deletions Orso.Arpa.Mail/Templates/Html/Appointment_Changed_By_Staff.html
Original file line number Diff line number Diff line change
Expand Up @@ -120,20 +120,23 @@ <h1 class="header h1" style="margin: 20px 0; line-height: 40px; font-family: Hel
</table>
</div>
<h2 class="header h2" style="margin: 20px 0; line-height: 30px; font-family: Helvetica,Arial,sans-serif; color: #FFFFFF; color: rgba(255, 255, 255, .87);">Hallo,</h2>
<h3 class="header h3" style="margin: 20px 0; line-height: 24px; font-family: Helvetica,Arial,sans-serif; color: #FFFFFF; color: rgba(255, 255, 255, .87);">wir möchten dich über eine Terminaktualisierung in ARPA informieren.</h3>
<h3 class="header h3" style="margin: 20px 0; line-height: 24px; font-family: Helvetica,Arial,sans-serif; color: #FFFFFF; color: rgba(255, 255, 255, .87);">Die neuen Daten lauten nun wie folgt:</h3>
<h3 class="header h3" style="margin: 20px 0; line-height: 24px; font-family: Helvetica,Arial,sans-serif; color: #FFFFFF; color: rgba(255, 255, 255, .87);">In ARPA wurde dieser Termin aktualisiert:</h3>
<div class="row">
<table class="row__table" width="100%" align="center" role="presentation" border="0" cellpadding="0" cellspacing="0" style="table-layout: fixed;">
<tr class="row__row">
<td class="column col-sm-7" width="231" style="padding: 0 10px;width: 33%" align="left" valign="top">
<h4 class="header h4" style="margin: 20px 0; font-family: Helvetica,Arial,sans-serif; color: #FFFFFF; color: rgba(255, 255, 255, .87);">Name:</h4>
<h4 class="header h4" style="margin: 20px 0; font-family: Helvetica,Arial,sans-serif; color: #FFFFFF; color: rgba(255, 255, 255, .87);">Zeitpunkt:</h4>
<h4 class="header h4" style="margin: 20px 0; font-family: Helvetica,Arial,sans-serif; color: #FFFFFF; color: rgba(255, 255, 255, .87);">Zielgruppe:</h4>
<h4 class="header h4" style="margin: 20px 0; font-family: Helvetica,Arial,sans-serif; color: #FFFFFF; color: rgba(255, 255, 255, .87);">Termin:</h4>
<h4 class="header h4" style="margin: 20px 0; font-family: Helvetica,Arial,sans-serif; color: #FFFFFF; color: rgba(255, 255, 255, .87);">Status:</h4>
<h4 class="header h4" style="margin: 20px 0; font-family: Helvetica,Arial,sans-serif; color: #FFFFFF; color: rgba(255, 255, 255, .87);">Bezeichnung:</h4>
<h4 class="header h4" style="margin: 20px 0; font-family: Helvetica,Arial,sans-serif; color: #FFFFFF; color: rgba(255, 255, 255, .87);">Ort:</h4>
<h4 class="header h4" style="margin: 20px 0; font-family: Helvetica,Arial,sans-serif; color: #FFFFFF; color: rgba(255, 255, 255, .87);">Details:</h4>
</td>
<td class="column col-sm-5" width="469" style="padding: 0 10px;width: 67%" align="left" valign="top">
<h4 class="header h4" style="margin: 20px 0; font-family: Helvetica,Arial,sans-serif; color: #FFFFFF; color: rgba(255, 255, 255, .87);">{{AppointmentName}}</h4>
<h4 class="header h4" style="margin: 20px 0; font-family: Helvetica,Arial,sans-serif; color: #FFFFFF; color: rgba(255, 255, 255, .87);">{{Sections}}</h4>
<h4 class="header h4" style="margin: 20px 0; font-family: Helvetica,Arial,sans-serif; color: #FFFFFF; color: rgba(255, 255, 255, .87);">{{DateAndTime}}</h4>
<h4 class="header h4" style="margin: 20px 0; font-family: Helvetica,Arial,sans-serif; color: #FFFFFF; color: rgba(255, 255, 255, .87);">{{Status}}</h4>
<h4 class="header h4" style="margin: 20px 0; font-family: Helvetica,Arial,sans-serif; color: #FFFFFF; color: rgba(255, 255, 255, .87);">{{AppointmentName}}</h4>
<h4 class="header h4" style="margin: 20px 0; font-family: Helvetica,Arial,sans-serif; color: #FFFFFF; color: rgba(255, 255, 255, .87);">{{Venue}}</h4>
<p class="text p" style="display: block; margin: 14px 0; font-family: Helvetica,Arial,sans-serif; line-height: 20px; color: #FFFFFF; color: rgba(255, 255, 255, .87); font-size: 14px;"><i>{{PublicDetails}}</i></p>
</td>
Expand All @@ -153,6 +156,7 @@ <h4 class="header h4" style="margin: 20px 0; font-family: Helvetica,Arial,sans-s
<table class="row__table" width="100%" align="center" role="presentation" border="0" cellpadding="0" cellspacing="0" style="table-layout: fixed;">
<tr class="row__row">
<td class="column col-sm-12" width="700" style="padding: 0 10px;width: 100%" align="left" valign="top">
<p class="text p" style="display: block; margin: 14px 0; font-family: Helvetica,Arial,sans-serif; line-height: 20px; color: #FFFFFF; color: rgba(255, 255, 255, .87); font-size: 14px;">Bitte beachte, dass eine Aktualisierung manchmal auch nur den Bereich “Details” betrifft.</p>
<p class="text p" style="display: block; margin: 14px 0; font-family: Helvetica,Arial,sans-serif; line-height: 20px; color: #FFFFFF; color: rgba(255, 255, 255, .87); font-size: 14px;">Für weitere Informationen und um ggf. deinen Teilnahmestatus anzupassen, logge dich in <a href="{{ArpaUrl}}" target="_blank" class="a" style="color: #FFFFFF; color: rgba(255, 255, 255, .87);"><span class="a__text" style="color: #FFFFFF; color: rgba(255, 255, 255, .87);">ARPA</span></a> ein.</p>
</td>
</tr>
Expand Down Expand Up @@ -189,6 +193,6 @@ <h5 class="header h5" style="margin: 20px 0; line-height: 17px; font-family: Hel
</td>
</tr>
</table>
<div style="display:none; white-space:nowrap; font-size:15px; line-height:0;"></div>
<div style="display:none; white-space:nowrap; font-size:15px; line-height:0;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </div>
</body>
</html>
4 changes: 2 additions & 2 deletions Orso.Arpa.Misc/Extensions/EnumberableExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,11 @@ public static bool AreAllSame<T>(this IEnumerable<T> enumerable)

while (enumerator.MoveNext())
{
if (toCompare == null && enumerator.Current != null)
if (Equals(toCompare, default) && !Equals(enumerator.Current, default))
{
return false;
}
if (toCompare != null && !toCompare.Equals(enumerator.Current))
if (!Equals(toCompare, default) && !toCompare.Equals(enumerator.Current))
{
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion Orso.Arpa.Misc/Orso.Arpa.Misc.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.1" />
<PackageReference Include="QRCoder-ImageSharp" Version="0.10.0" />
</ItemGroup>
</Project>
4 changes: 2 additions & 2 deletions Orso.Arpa.Persistence/Orso.Arpa.Persistence.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
<ItemGroup>
<PackageReference Include="EFCore.NamingConventions" Version="8.0.3" />
<PackageReference Include="HotChocolate.Types" Version="13.9.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="8.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="8.0.3" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.2" />
</ItemGroup>

Expand Down
1 change: 1 addition & 0 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ Rebuilding the API on source updates.
- Set the smtp configuration via [dotnet user-secrets](https://learn.microsoft.com/en-us/aspnet/core/security/app-secrets) (see appsettings.Development.json EmailConfiguration)
- Run the project with the command `dotnet run --project Orso.Arpa.Api`
- Open the Swagger UI on `https://localhost:5001`
- Calling the local backend via the frontend may lead to certificate errors. In this case, run `dotnet dev-certs https` and `dotnet dev-certs https --trust`

## Login
The initial database contains a single user with an admin role. You can login using the following credentials:
Expand Down
Loading

0 comments on commit b7e095d

Please sign in to comment.