diff --git a/src/server/domain/Models/Push/PushNotificationData.cs b/src/server/domain/Models/Push/PushNotificationData.cs index 0cd9ad2..2cae2cf 100644 --- a/src/server/domain/Models/Push/PushNotificationData.cs +++ b/src/server/domain/Models/Push/PushNotificationData.cs @@ -195,6 +195,18 @@ public string GetBody(string lang) => }; } + public record TestNotification(string Title, string Body) : IPushNotificationData + { + public string Type => "test-notification"; + + public Dictionary OnActionClick => + new() { { "default", new($"/events") } }; + + public string GetTitle(string lang) => Title; + + public string GetBody(string lang) => Body; + } + private static string NormalizeLang(string lang) { if (lang.StartsWith("de", StringComparison.OrdinalIgnoreCase)) diff --git a/src/server/host/Endpoints/Notifications/SendNotificationEndpoint.cs b/src/server/host/Endpoints/Notifications/SendNotificationEndpoint.cs new file mode 100644 index 0000000..280f7a2 --- /dev/null +++ b/src/server/host/Endpoints/Notifications/SendNotificationEndpoint.cs @@ -0,0 +1,126 @@ +using System.ComponentModel.DataAnnotations; +using FastEndpoints; +using FluentValidation; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure.Internal; +using MinigolfFriday.Data; +using MinigolfFriday.Domain.Models; +using MinigolfFriday.Domain.Models.Push; +using MinigolfFriday.Domain.Models.RealtimeEvents; +using MinigolfFriday.Host.Common; +using MinigolfFriday.Host.Mappers; +using MinigolfFriday.Host.Services; +using MinigolfFriday.Host.Utilities; + +namespace MinigolfFriday.Host.Endpoints.Notifications; + +public record SendNotificationRequest(string? UserId, string? Title, string? Body); + +public class SendNotificationRequestValidator : Validator +{ + public SendNotificationRequestValidator(IIdService idService) + { + // RuleFor(x => x.UserId).NotNull().ValidSqid(idService.User); + } +} + +public class SendNotificationEndpoint( + DatabaseContext databaseContext, + IJwtService jwtService, + IIdService idService, + IUserPushSubscriptionMapper userPushSubscriptionMapper, + IWebPushService webPushService +) : Endpoint +{ + public override void Configure() + { + Post(""); + Group(); + this.ProducesErrors(EndpointErrors.UserIdNotInClaims); + } + + public override async Task HandleAsync(SendNotificationRequest req, CancellationToken ct) + { + // var userId = idService.User.DecodeSingle(req.UserId); + if (!jwtService.TryGetUserId(User, out var currendUserId)) + { + Logger.LogWarning(EndpointErrors.UserIdNotInClaims); + await this.SendErrorAsync(EndpointErrors.UserIdNotInClaims, ct); + return; + } + // Logger.LogWarning("user found. id: {}", userId); + Logger.LogWarning("current User: {} ", currendUserId); + + var user = await databaseContext + .Users.Include(x => x.Settings) + .FirstAsync(x => x.Id == currendUserId, ct); + + Logger.LogWarning(user.Alias); + + var notifications = await databaseContext + .Users.Where(u => u.Id == currendUserId) + .Select(u => new + { + Subscriptions = u.PushSubscriptions.Select(x => new UserPushSubscription( + x.Id, + x.UserId, + x.Lang, + x.Endpoint, + x.P256DH, + x.Auth + )), + NotificationData = new PushNotificationData.TestNotification( + req.Title != null ? req.Title : "Body", + req.Body != null ? req.Body : "Test" + ) + }) + .ToArrayAsync(ct); + foreach (var notification in notifications) + await webPushService.SendAsync( + notification.Subscriptions, + notification.NotificationData, + ct + ); + + // var user = await databaseContext + // .Users.Include(x => x.Settings) + // .FirstAsync(x => x.Id == userId, ct); + + // if (user.Settings == null) + // { + // user.Settings = new() + // { + // EnableNotifications = req.EnableNotifications ?? true, + // NotifyOnEventPublish = req.NotifyOnEventPublish ?? true, + // NotifyOnEventStart = req.NotifyOnEventStart ?? true, + // NotifyOnEventUpdated = req.NotifyOnEventUpdated ?? true, + // NotifyOnTimeslotStart = req.NotifyOnTimeslotStart ?? true, + // SecondsToNotifyBeforeTimeslotStart = req.SecondsToNotifyBeforeTimeslotStart ?? 600 + // }; + // } + // else + // { + // user.Settings.EnableNotifications = + // req.EnableNotifications ?? user.Settings.EnableNotifications; + // user.Settings.NotifyOnEventPublish = + // req.NotifyOnEventPublish ?? user.Settings.NotifyOnEventPublish; + // user.Settings.NotifyOnEventStart = + // req.NotifyOnEventStart ?? user.Settings.NotifyOnEventStart; + // user.Settings.NotifyOnEventUpdated = + // req.NotifyOnEventUpdated ?? user.Settings.NotifyOnEventUpdated; + // user.Settings.NotifyOnTimeslotStart = + // req.NotifyOnTimeslotStart ?? user.Settings.NotifyOnTimeslotStart; + // user.Settings.SecondsToNotifyBeforeTimeslotStart = + // req.SecondsToNotifyBeforeTimeslotStart + // ?? user.Settings.SecondsToNotifyBeforeTimeslotStart; + // } + + // await databaseContext.SaveChangesAsync(ct); + await SendOkAsync(ct); + + // await realtimeEventsService.SendEventAsync( + // new RealtimeEvent.UserSettingsChanged(idService.User.Encode(userId)), + // ct + // ); + } +}