Skip to content

Commit

Permalink
Finally making some progress
Browse files Browse the repository at this point in the history
  • Loading branch information
SpikeViper committed Jan 31, 2025
1 parent 10feb97 commit 82d4664
Show file tree
Hide file tree
Showing 22 changed files with 941 additions and 393 deletions.
2 changes: 1 addition & 1 deletion Valour/Database/Context/ValourDB.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ public partial class ValourDb : DbContext
/// <summary>
/// Table for notification subscriptions
/// </summary>
public DbSet<NotificationSubscription> NotificationSubscriptions { get; set; }
public DbSet<PushNotificationSubscription> PushNotificationSubscriptions { get; set; }

/// <summary>
/// Table for notifications
Expand Down
80 changes: 0 additions & 80 deletions Valour/Database/NotificationSubscription.cs

This file was deleted.

3 changes: 3 additions & 0 deletions Valour/Database/Planet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ public class Planet : ISharedPlanet
[InverseProperty("Planet")]
public virtual ICollection<PlanetInvite> Invites { get; set; }

[InverseProperty("Planet")]
public virtual ICollection<PushNotificationSubscription> NotificationSubscriptions { get; set; }

public virtual ICollection<Message> Messages { get; set; }

public virtual ICollection<UserChannelState> UserChannelStates { get; set; }
Expand Down
127 changes: 127 additions & 0 deletions Valour/Database/PushNotificationSubscription.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
#nullable enable

using Microsoft.EntityFrameworkCore;
using Valour.Shared.Models;

namespace Valour.Database;

public class PushNotificationSubscription : ISharedNotificationSubscription
{
///////////////////////////
// Relational Properties //
///////////////////////////

public virtual User? User { get; set; }

public virtual Planet? Planet { get; set; }

///////////////////////
// Entity Properties //
///////////////////////

public long Id { get; set; }

/// <summary>
/// The type of device this subscription is for
/// </summary>
public NotificationDeviceType DeviceType { get; set; }

/// <summary>
/// When this subscription expires
/// </summary>
public DateTime ExpiresAt { get; set; }

/// <summary>
/// The Id of the device, to prevent duplicate subscriptions
/// </summary>
public required string DeviceId { get; set; }

/// <summary>
/// The Id of the user this subscription is for
/// </summary>
public long UserId { get; set; }

/// <summary>
/// The Id of the planet (if any) this subscription is for
/// </summary>
public long? PlanetId { get; set; }

/// <summary>
/// The Id of the member this subscription is for, if a planet subscription.
/// </summary>
public long? MemberId { get; set; }

/// <summary>
/// The RoleHashKey the planet member is subscribed to. Should only be used for planet subscriptions.
/// </summary>
public long? RoleHashKey { get; set; }

public required string Endpoint { get; set; }

public string? Key { get; set; }

public string? Auth { get; set; }

public static void SetUpDbModel(ModelBuilder builder)
{
builder.Entity<PushNotificationSubscription>(e =>
{
// ToTable
e.ToTable("web_push_subscriptions");

// Key
e.HasKey(x => x.Id);

// Properties
e.Property(x => x.Id)
.HasColumnName("id");

e.Property(x => x.DeviceType)
.HasColumnName("device_type");

e.Property(x => x.ExpiresAt)
.HasColumnName("expires_at")
.HasDefaultValue("(NOW() + INTERVAL '7 days')")
.HasConversion(
x => x,
x => new DateTime(x.Ticks, DateTimeKind.Utc)
);

e.Property(x => x.UserId)
.HasColumnName("user_id");

e.Property(x => x.PlanetId)
.HasColumnName("planet_id");

e.Property(x => x.MemberId)
.HasColumnName("member_id");

e.Property(x => x.RoleHashKey)
.HasColumnName("role_hash_key");

e.Property(x => x.Key)
.HasColumnName("key");

e.Property(x => x.Auth)
.HasColumnName("auth");

// Relationships

e.HasOne(x => x.User)
.WithMany(x => x.NotificationSubscriptions)
.HasForeignKey(x => x.UserId);

e.HasOne(x => x.Planet)
.WithMany(x => x.NotificationSubscriptions)
.HasForeignKey(x => x.PlanetId);

// Indices

e.HasIndex(x => x.UserId);
e.HasIndex(x => x.PlanetId);

e.HasIndex(x => x.MemberId)
.IsUnique();
});
}
}
2 changes: 1 addition & 1 deletion Valour/Database/User.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public class User : ISharedUser
/// <summary>
/// Notification of Subscriptions for this user.
/// </summary>
public virtual ICollection<NotificationSubscription> NotificationSubscriptions { get; set; }
public virtual ICollection<PushNotificationSubscription> NotificationSubscriptions { get; set; }

///////////////////////
// Entity Properties //
Expand Down
4 changes: 2 additions & 2 deletions Valour/Server/Api/Dynamic/NotificationApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public class NotificationApi
[ValourRoute(HttpVerbs.Post, "api/notifications/subscribe")]
[UserRequired]
public static async Task<IResult> SubscribeAsync(
WebPushSubscription subscription,
PushNotificationSubscription subscription,
NotificationService notificationService,
UserService userService)
{
Expand All @@ -26,7 +26,7 @@ public static async Task<IResult> SubscribeAsync(
[ValourRoute(HttpVerbs.Post, "api/notifications/unsubscribe")]
[UserRequired]
public static async Task<IResult> UnsubscribeAsync(
WebPushSubscription subscription,
PushNotificationSubscription subscription,
NotificationService notificationService,
UserService userService)
{
Expand Down
11 changes: 6 additions & 5 deletions Valour/Server/Api/NotificationsApi.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Microsoft.AspNetCore.Mvc;
using Valour.Sdk.Models;
using Valour.Server.Database;
using NotificationSubscription = Valour.Sdk.Models.NotificationSubscription;

namespace Valour.Server.API;

Expand Down Expand Up @@ -37,7 +38,7 @@ public static async Task<IResult> Subscribe(ValourDb db, [FromBody] Notification
}

// Look for old subscription
var old = await db.NotificationSubscriptions.FirstOrDefaultAsync(x => x.Endpoint == subscription.Endpoint);
var old = await db.PushNotificationSubscriptions.FirstOrDefaultAsync(x => x.Endpoint == subscription.Endpoint);

if (old != null)
{
Expand All @@ -48,15 +49,15 @@ public static async Task<IResult> Subscribe(ValourDb db, [FromBody] Notification
old.Auth = subscription.Auth;
old.Key = subscription.Key;

db.NotificationSubscriptions.Update(old);
db.PushNotificationSubscriptions.Update(old);
await db.SaveChangesAsync();

return Results.Ok("Updated subscription.");
}

subscription.Id = IdManager.Generate();

await db.NotificationSubscriptions.AddAsync(subscription.ToDatabase());
await db.PushNotificationSubscriptions.AddAsync(subscription.ToDatabase());
await db.SaveChangesAsync();

return Results.Ok("Subscription was accepted.");
Expand All @@ -73,13 +74,13 @@ public static async Task<IResult> Unsubscribe(ValourDb db, [FromBody] Notificati
return ValourResult.InvalidToken();

// Look for old subscription
var old = await db.NotificationSubscriptions.FirstOrDefaultAsync(x => x.Endpoint == subscription.Endpoint);
var old = await db.PushNotificationSubscriptions.FirstOrDefaultAsync(x => x.Endpoint == subscription.Endpoint);

if (old is null)
return Results.Ok("Subscription already removed.");


db.NotificationSubscriptions.Remove(old);
db.PushNotificationSubscriptions.Remove(old);
await db.SaveChangesAsync();

return Results.Ok("Removed subscription.");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
namespace Valour.Server.Mapping;

public static class WebPushSubscriptionMapper
public static class NotificationSubscriptionMapper
{
public static WebPushSubscription ToModel(this Valour.Database.NotificationSubscription subscription)
public static PushNotificationSubscription ToModel(this Valour.Database.PushNotificationSubscription subscription)
{
if (subscription is null)
return null;

return new WebPushSubscription()
return new PushNotificationSubscription()
{
Id = subscription.Id,
UserId = subscription.UserId,
Expand All @@ -17,12 +17,12 @@ public static WebPushSubscription ToModel(this Valour.Database.NotificationSubsc
};
}

public static Valour.Database.NotificationSubscription ToDatabase(this WebPushSubscription subscription)
public static Valour.Database.PushNotificationSubscription ToDatabase(this PushNotificationSubscription subscription)
{
if (subscription is null)
return null;

return new Valour.Database.NotificationSubscription()
return new Valour.Database.PushNotificationSubscription()
{
Id = subscription.Id,
UserId = subscription.UserId,
Expand Down
9 changes: 9 additions & 0 deletions Valour/Server/Models/NotificationContent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Valour.Server.Models;

public class NotificationContent
{
public string Title { get; set; }
public string Message { get; set; }
public string IconUrl { get; set; }
public string Url { get; set; }
}
17 changes: 17 additions & 0 deletions Valour/Server/Models/PushNotificationSubscription.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using Valour.Shared.Models;

namespace Valour.Server.Models;

public class PushNotificationSubscription : ISharedNotificationSubscription
{
public long Id { get; set; }
public NotificationDeviceType DeviceType { get; set; }
public DateTime ExpiresAt { get; set; }
public long UserId { get; set; }
public long? PlanetId { get; set; }
public long? RoleHashKey { get; set; }
public long? MemberId { get; set; }
public string Endpoint { get; set; }
public string Key { get; set; }
public string Auth { get; set; }
}
11 changes: 0 additions & 11 deletions Valour/Server/Models/WebPushSubscription.cs

This file was deleted.

Loading

0 comments on commit 82d4664

Please sign in to comment.