diff --git a/Morphic.Server/Community/CommunitiesEndpoint.cs b/Morphic.Server/Community/CommunitiesEndpoint.cs index cb4b042..9ac6fdd 100644 --- a/Morphic.Server/Community/CommunitiesEndpoint.cs +++ b/Morphic.Server/Community/CommunitiesEndpoint.cs @@ -26,6 +26,11 @@ using System; using System.Text.Json.Serialization; using System.Collections.Generic; +using System.Text; +using Hangfire; +using MongoDB.Bson; +using MongoDB.Bson.IO; +using Morphic.Server.Email; using Stripe; namespace Morphic.Server.Community @@ -39,10 +44,13 @@ namespace Morphic.Server.Community public class CommunitiesEndpoint: Endpoint { - public CommunitiesEndpoint(IPaymentProcessor paymentProcessor, Plans plans, IHttpContextAccessor contextAccessor, ILogger logger): base(contextAccessor, logger) + public CommunitiesEndpoint(IPaymentProcessor paymentProcessor, Plans plans, + IHttpContextAccessor contextAccessor, ILogger logger, IBackgroundJobClient jobClient) + : base(contextAccessor, logger) { this.paymentProcessor = paymentProcessor; this.plans = plans; + this.jobClient = jobClient; } public override async Task LoadResource() @@ -53,6 +61,7 @@ public override async Task LoadResource() private User User = null!; private IPaymentProcessor paymentProcessor; private Plans plans; + private readonly IBackgroundJobClient jobClient; [Method] public async Task Post() @@ -196,6 +205,24 @@ public async Task Post() member.LastName.PlainText = User.LastName?.PlainText; await db.Save(member); + + // Send an email alert when someone signs up + StringBuilder emailInfo = new StringBuilder(); + JsonWriterSettings writerSettings = new JsonWriterSettings() + { + Indent = true + }; + + emailInfo.AppendFormat("Community '{0}' created by '{1}' {2}", + community.Name, User.FullName, User.Email.PlainText).AppendLine(); + + emailInfo.AppendLine("Member:").AppendLine(member.ToJson(writerSettings)); + emailInfo.AppendLine("Community:").AppendLine(community.ToJson(writerSettings)); + + jobClient.Enqueue(x => + x.SendEmail("new community", emailInfo.ToString(), this.Request.ClientIp())); + + await Respond(new CommunityPutResponse() { Community = community diff --git a/Morphic.Server/Email/EmailSettings.cs b/Morphic.Server/Email/EmailSettings.cs index a6c8d6b..ed76c73 100644 --- a/Morphic.Server/Email/EmailSettings.cs +++ b/Morphic.Server/Email/EmailSettings.cs @@ -40,6 +40,9 @@ public class EmailSettings /// The default 'name' we use to send emails. /// public string EmailFromFullname { get; set; } = "Morphic Support"; + + public string? InternalAlertEmail { get; set; } + /// /// Some SendGrid settings. /// diff --git a/Morphic.Server/Email/InternalAlertEmail.cs b/Morphic.Server/Email/InternalAlertEmail.cs new file mode 100644 index 0000000..011f770 --- /dev/null +++ b/Morphic.Server/Email/InternalAlertEmail.cs @@ -0,0 +1,74 @@ +// Copyright 2021 Raising the Floor - International +// +// Licensed under the New BSD license. You may not use this file except in +// compliance with this License. +// +// You may obtain a copy of the License at +// https://github.com/GPII/universal/blob/master/LICENSE.txt +// +// The R&D leading to these results received funding from the: +// * Rehabilitation Services Administration, US Dept. of Education under +// grant H421A150006 (APCP) +// * National Institute on Disability, Independent Living, and +// Rehabilitation Research (NIDILRR) +// * Administration for Independent Living & Dept. of Education under grants +// H133E080022 (RERC-IT) and H133E130028/90RE5003-01-00 (UIITA-RERC) +// * European Union's Seventh Framework Programme (FP7/2007-2013) grant +// agreement nos. 289016 (Cloud4all) and 610510 (Prosperity4All) +// * William and Flora Hewlett Foundation +// * Ontario Ministry of Research and Innovation +// * Canadian Foundation for Innovation +// * Adobe Foundation +// * Consumer Electronics Association Foundation + +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using Hangfire; +using Microsoft.Extensions.Logging; +using Morphic.Server.Db; + +namespace Morphic.Server.Email +{ + /// + /// Sends an email alert, for when something interesting happens. + /// + // ReSharper disable once UnusedType.Global + public class InternalAlertEmail : EmailJob + { + public InternalAlertEmail(MorphicSettings morphicSettings, EmailSettings settings, ILogger logger, Database db) : base(morphicSettings, settings, logger, db) + { + // TODO: Re-using the invitation email for now + EmailType = EmailConstants.EmailTypes.CommunityInvitation; + } + + + [AutomaticRetry(Attempts = 20)] + public async Task SendEmail(string eventName, string details, string? clientIp) + { + if (EmailSettings.Type == EmailSettings.EmailTypeDisabled) + { + // Email shouldn't be disabled, but if it is, we want to + // fail this job so it retries + throw new Exception("Email is disabled, failing job to it will retry"); + } + + string toAddress = this.EmailSettings.InternalAlertEmail ?? this.EmailSettings.EmailFromAddress; + + Attributes.Add("EmailType", EmailType.ToString()); + Attributes.Add("ToUserName", toAddress); + Attributes.Add("ToEmail", toAddress); + Attributes.Add("FromUserName", EmailSettings.EmailFromFullname); + Attributes.Add("FromEmail", EmailSettings.EmailFromAddress); + + Attributes.Add("Message", details); + Attributes.Add("Event", eventName); + + Attributes.Add("ClientIp", clientIp ?? UnknownClientIp); + Attributes.Add("Link", this.GetFrontEndUri("/").ToString()); + + await SendOneEmail(EmailType, Attributes); + } + } +} \ No newline at end of file