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
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Coderr.Server.Api.Core.Users.Commands
{
[Message]
public class DeleteBrowserSubscription
{
public int UserId { get; set; }
public string Endpoint { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace Coderr.Server.Api.Core.Users.Commands
{
/// <summary>
/// https://tools.ietf.org/html/draft-ietf-webpush-encryption-08
/// </summary>
[Message]
public class StoreBrowserSubscription
{
public int UserId { get; set; }
public string Endpoint { get; set; }

public string PublicKey { get; set; }
public string AuthenticationSecret { get; set; }

public int? ExpirationTime { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,6 @@ public class UpdateNotifications
/// </summary>
public NotificationState NotifyOnNewIncidents { get; set; }

/// <summary>
/// How to notify when a new report is created (receive an exception)
/// </summary>
public NotificationState NotifyOnNewReport { get; set; }

/// <summary>
/// How to notify user when a peak is detected
/// </summary>
Expand All @@ -36,6 +31,7 @@ public class UpdateNotifications
/// </summary>
public NotificationState NotifyOnUserFeedback { get; set; }


/// <summary>
/// User that configured its settings.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,6 @@ public class NotificationSettings
/// </summary>
public NotificationState NotifyOnNewIncidents { get; set; }

/// <summary>
/// How to notify when a new report is created (receive an exception)
/// </summary>
public NotificationState NotifyOnNewReport { get; set; }

/// <summary>
/// How to notify user when a peak is detected
/// </summary>
Expand Down
13 changes: 9 additions & 4 deletions src/Server/Coderr.Server.Api/Core/Users/NotificationState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,26 @@ public enum NotificationState
/// <summary>
/// Use global setting
/// </summary>
UseGlobalSetting,
UseGlobalSetting = 1,

/// <summary>
/// Do not notify
/// </summary>
Disabled,
Disabled = 2,

/// <summary>
/// By cellphone (text message)
/// </summary>
Cellphone,
Cellphone = 3,

/// <summary>
/// By email
/// </summary>
Email
Email = 4,

/// <summary>
/// Use browser/desktop notifications.
/// </summary>
BrowserNotification = 5
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System.Threading.Tasks;
using Coderr.Server.Api.Core.Users.Commands;
using DotNetCqs;

namespace Coderr.Server.App.Core.Notifications.Commands
{
internal class DeleteBrowserSubscriptionHandler : IMessageHandler<DeleteBrowserSubscription>
{
private readonly INotificationsRepository _repository;

public DeleteBrowserSubscriptionHandler(INotificationsRepository repository)
{
_repository = repository;
}

public async Task HandleAsync(IMessageContext context, DeleteBrowserSubscription message)
{
await _repository.DeleteBrowserSubscription(message.UserId, message.Endpoint);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System;
using System.Threading.Tasks;
using Coderr.Server.Abstractions.Security;
using Coderr.Server.Api.Core.Users.Commands;
using Coderr.Server.Domain.Modules.UserNotifications;
using DotNetCqs;

namespace Coderr.Server.App.Core.Notifications.Commands
{
internal class StoreBrowserSubscriptionHandler : IMessageHandler<StoreBrowserSubscription>
{
private readonly INotificationsRepository _notificationsRepository;

public StoreBrowserSubscriptionHandler(INotificationsRepository notificationsRepository)
{
_notificationsRepository = notificationsRepository;
}

public async Task HandleAsync(IMessageContext context, StoreBrowserSubscription message)
{
var subscription = new BrowserSubscription
{
AccountId = context.Principal.GetAccountId(),
AuthenticationSecret = message.AuthenticationSecret,
Endpoint = message.Endpoint,
PublicKey = message.PublicKey,
ExpiresAtUtc = message.ExpirationTime == null
? (DateTime?) null
: DateTime.UtcNow.AddMilliseconds(message.ExpirationTime.Value)
};
await _notificationsRepository.Save(subscription);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Threading.Tasks;
using Coderr.Server.Api.Core.Users.Commands;
using Coderr.Server.Domain.Modules.UserNotifications;

namespace Coderr.Server.App.Core.Notifications
{
/// <summary>
/// Repository for notification settings
/// Repository for managing notification settings
/// </summary>
public interface INotificationsRepository
{
Expand Down Expand Up @@ -45,5 +46,8 @@ public interface INotificationsRepository
/// <returns>task</returns>
/// <exception cref="ArgumentNullException">notificationSettings</exception>
Task UpdateAsync(UserNotificationSettings notificationSettings);

Task Save(BrowserSubscription message);
Task DeleteBrowserSubscription(int accountId, string endpoint);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using System.Collections.Generic;
using Coderr.Server.Abstractions.Config;
using Coderr.Server.Infrastructure.Configuration;
//using Coderr.Server.ReportAnalyzer.Abstractions.ErrorReports;

namespace Coderr.Server.App.Core.Reports.Config
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System;
using System.Data;
using System.Diagnostics;
using Coderr.Server.Abstractions.Boot;
using Coderr.Server.Abstractions.Config;
using Coderr.Server.App.Core.Reports.Config;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ public async Task<GetUserSettingsResult> HandleAsync(IMessageContext context, Ge
NotifyOnReOpenedIncident = settings.ReopenedIncident.ConvertEnum<NotificationState>(),
NotifyOnUserFeedback = settings.UserFeedback.ConvertEnum<NotificationState>(),
NotifyOnPeaks = settings.ApplicationSpike.ConvertEnum<NotificationState>(),
NotifyOnNewReport = settings.NewReport.ConvertEnum<NotificationState>(),
NotifyOnNewIncidents = settings.NewIncident.ConvertEnum<NotificationState>()
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ public async Task HandleAsync(IMessageContext context, UpdateNotifications comma

settings.ApplicationSpike = command.NotifyOnPeaks.ConvertEnum<NotificationState>();
settings.NewIncident = command.NotifyOnNewIncidents.ConvertEnum<NotificationState>();
settings.NewReport = command.NotifyOnNewReport.ConvertEnum<NotificationState>();
settings.ReopenedIncident = command.NotifyOnReOpenedIncident.ConvertEnum<NotificationState>();
settings.UserFeedback = command.NotifyOnUserFeedback.ConvertEnum<NotificationState>();
await _notificationsRepository.UpdateAsync(settings);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System;

namespace Coderr.Server.Domain.Modules.UserNotifications
{
public class BrowserSubscription
{
public int AccountId { get; set; }

public DateTime CreatedAtUtc { get; set; } = DateTime.UtcNow;

/// <summary>
/// </summary>
public string AuthenticationSecret { get; set; }

public string Endpoint { get; set; }

public DateTime? ExpiresAtUtc { get; set; }

public int Id { get; set; }

/// <summary>
/// https://developer.mozilla.org/en-US/docs/Web/API/PushSubscription/getKey
/// </summary>
public string PublicKey { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,9 @@ public interface IUserNotificationsRepository
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
Task<IEnumerable<UserNotificationSettings>> GetAllAsync(int applicationId);

Task<IReadOnlyList<BrowserSubscription>> GetSubscriptions(int accountId);
Task Delete(BrowserSubscription subscription);

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,31 @@ public enum NotificationState
/// <summary>
/// Use global setting
/// </summary>
UseGlobalSetting,
UseGlobalSetting = 1,

/// <summary>
/// Do not notify
/// </summary>
Disabled,
Disabled = 2,

/// <summary>
/// By cellphone (text message)
/// </summary>
Cellphone,
Cellphone = 3,

/// <summary>
/// By email
/// </summary>
Email
Email = 4,

/// <summary>
/// Send a browser notification to the user
/// </summary>
/// <remarks>
/// <para>
/// Requires that the user have approved it (by a javascript request).
/// </para>
/// </remarks>
BrowserNotification = 5
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ public UserNotificationSettings(int accountId, int applicationId)
if (accountId <= 0) throw new ArgumentOutOfRangeException("accountId");
AccountId = accountId;
ApplicationId = applicationId;
if (applicationId != 0)
return;

ApplicationSpike = NotificationState.Disabled;
NewIncident = NotificationState.Disabled;
ReopenedIncident = NotificationState.Disabled;
UserFeedback = NotificationState.Disabled;
}

/// <summary>
Expand Down Expand Up @@ -47,11 +54,6 @@ protected UserNotificationSettings()
/// </summary>
public NotificationState NewIncident { get; set; }

/// <summary>
/// Notify each time a new exception is received (no matter if it's unique or not)
/// </summary>
public NotificationState NewReport { get; set; }

/// <summary>
/// Notify when we received a report for an incident that has been closed
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@
/// </summary>
public class FeedbackAttachedToIncident
{
/// <summary>
/// Application that the incident belongs to.
/// </summary>
public int ApplicationId { get; set; }

/// <summary>
/// Name of the application that the feedback is for.
/// </summary>
public string ApplicationName { get; set; }

/// <summary>
/// Incident that the feedback was attached to.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@ public async Task HandleAsync(IMessageContext context, ReportAddedToIncident e)
return;

feedback.AssignToReport(e.Report.Id, e.Incident.Id, e.Incident.ApplicationId);

var evt = new FeedbackAttachedToIncident
{
ApplicationId = e.Incident.ApplicationId,
ApplicationName = e.Incident.ApplicationName,
IncidentId = e.Incident.Id,
Message = feedback.Description,
UserEmailAddress = feedback.EmailAddress
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,9 @@ private async Task<AppInfo> GetAppAsync(string appKey)
{
using (var cmd = _unitOfWork.CreateDbCommand())
{
cmd.CommandText = "SELECT Id, SharedSecret FROM Applications WHERE AppKey = @key";
cmd.CommandText = "SELECT Id, SharedSecret FROM Applications WHERE AppKey = @key OR AppKey = @key2";
cmd.AddParameter("key", appKey);
cmd.AddParameter("key2", appKey.Replace("-", ""));
using (var reader = await cmd.ExecuteReaderAsync())
{
if (!await reader.ReadAsync())
Expand Down
Loading