diff --git a/server/AyaNova/Controllers/AuthController.cs b/server/AyaNova/Controllers/AuthController.cs index caf2b6ba..a128e9dd 100644 --- a/server/AyaNova/Controllers/AuthController.cs +++ b/server/AyaNova/Controllers/AuthController.cs @@ -663,6 +663,24 @@ namespace AyaNova.Api.Controllers await ct.SaveChangesAsync(); return NoContent(); } + + + //generate an internal JWT key for reporting purposes used by corejobnotify to send reports as manager account + internal static string GenRpt() + { + byte[] secretKey = System.Text.Encoding.ASCII.GetBytes(ServerBootConfig.AYANOVA_JWT_SECRET); + var iat = new DateTimeOffset(DateTime.Now.ToUniversalTime(), TimeSpan.Zero); + var exp = new DateTimeOffset(DateTime.Now.AddMinutes(ServerBootConfig.AYANOVA_REPORT_RENDERING_TIMEOUT).ToUniversalTime(), TimeSpan.Zero); + var payload = new Dictionary() + { + { "exp", exp.ToUnixTimeSeconds().ToString() },//in payload exp must be in unix epoch time per standard + { "iss", "ayanova.com" }, + { "id", "1"}, + { "int","1" } + }; + return Jose.JWT.Encode(payload, secretKey, Jose.JwsAlgorithm.HS256); + } + //------------------------------------------------------ public class CredentialsParam diff --git a/server/AyaNova/Startup.cs b/server/AyaNova/Startup.cs index d5f8f7fa..1ddaa04b 100644 --- a/server/AyaNova/Startup.cs +++ b/server/AyaNova/Startup.cs @@ -469,6 +469,8 @@ namespace AyaNova context.Request.HttpContext.Items["AY_TRANSLATION_ID"] = u.translationId; context.Request.HttpContext.Items["AY_USER_TYPE"] = u.UserType; + var currentAuthToken=u.currentAuthToken; + //turned out didn't need this for v8 migrate so far, but keeping in case it turns out to be handy down the road // //Is import mode header set? // if (context.Request.Headers.ContainsKey("X-AY-Import-Mode")) diff --git a/server/AyaNova/generator/CoreJobNotify.cs b/server/AyaNova/generator/CoreJobNotify.cs index 8ace11f5..85b714ee 100644 --- a/server/AyaNova/generator/CoreJobNotify.cs +++ b/server/AyaNova/generator/CoreJobNotify.cs @@ -6,6 +6,7 @@ using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using AyaNova.Models; using AyaNova.Util; +using Newtonsoft.Json.Linq; namespace AyaNova.Biz { @@ -338,8 +339,67 @@ namespace AyaNova.Biz IMailer m = AyaNova.Util.ServiceProviderProvider.Mailer; try { +#if (DEBUG) + //generate a workorder report here get the path and send it with the message + using (AyContext ct = AyaNova.Util.ServiceProviderProvider.DBContext) + { + + ReportBiz biz = ReportBiz.GetBiz(ct); + //example with workorder report + //{"AType":34,"selectedRowIds":[355],"ReportId":9,"ClientMeta":{"UserName":"AyaNova SuperUser","Authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOiIxNjQ2NzgyNTc4IiwiaXNzIjoiYXlhbm92YS5jb20iLCJpZCI6IjEifQ.ad7Acq54JCRGitDWKDJFFnqKkidbdaKaFmj-RA_RG5E","DownloadToken":"NdoU8ca3LG4L39Tj2oi3UReeeM7FLevTgbgopTPhGbA","TimeZoneName":"America/Los_Angeles","LanguageName":"en-US","Hour12":true,"CurrencyName":"USD","DefaultLocale":"en","PDFDate":"3/3/22","PDFTime":"3:38 PM"}} + + var reportRequest = new DataListReportRequest(); + reportRequest.AType = AyaType.WorkOrder; + reportRequest.ReportId = 9; + reportRequest.SelectedRowIds = new long[] { 1 }; + var jwt= Api.Controllers.AuthController.GenRpt(); + reportRequest.ClientMeta = JToken.Parse($"{{'UserName':'AyaNova SuperUser','Authorization':'Bearer {jwt}','TimeZoneName':'America/Los_Angeles','LanguageName':'en-US','Hour12':true,'CurrencyName':'USD','DefaultLocale':'en','PDFDate':'3/3/22','PDFTime':'3:38 PM'}}"); + //get port number + var match = System.Text.RegularExpressions.Regex.Match(ServerBootConfig.AYANOVA_USE_URLS,"[0-9]+"); + var API_URL = $"http://127.0.0.1:{match.Value}/api/{AyaNovaVersion.CurrentApiVersion}/"; + var jobid = await biz.RequestRenderReport(reportRequest, DateTime.UtcNow.AddMinutes(ServerBootConfig.AYANOVA_REPORT_RENDERING_TIMEOUT), API_URL, "AUTOMATED NO USER"); + if (jobid == null) + { + return "JOB FAILED"; + } + else + { + bool done = false; + //todo: need a timeout here that sets done as failed due to timeout + while (!done) + { + var status = await JobsBiz.GetJobStatusAsync((Guid)jobid); + switch (status) + { + case JobStatus.Completed: + { + //todo: get report path and send it + //get job logs and parse file name from it + JobOperationsBiz jobopsbiz = new JobOperationsBiz(ct, 1, AuthorizationRoles.BizAdmin); + List log = await jobopsbiz.GetJobLogListAsync((Guid)jobid); + var lastLog=log[log.Count-1]; + var lastLogJ=JObject.Parse(lastLog.StatusText); + + //await m.SendEmailAsync(toAddress, "DEBUG Test from Notification system", "This is a DEBUG test to confirm notification system is working", ServerGlobalOpsSettingsCache.Notify); + return "ok"; + } + case JobStatus.Failed: + return $"JOB {jobid} started but failed"; + } + if (status == JobStatus.Failed) + { + return $"JOB {jobid} started but failed"; + } + } + return "JOB FAILED DUE TO TIMEOUT"; + } + } + +#else await m.SendEmailAsync(toAddress, "Test from Notification system", "This is a test to confirm notification system is working", ServerGlobalOpsSettingsCache.Notify); return "ok"; +#endif + } catch (Exception ex) { diff --git a/server/AyaNova/util/Mailer.cs b/server/AyaNova/util/Mailer.cs index 6cffc7d4..8487291b 100644 --- a/server/AyaNova/util/Mailer.cs +++ b/server/AyaNova/util/Mailer.cs @@ -3,12 +3,13 @@ using MimeKit; using System; using System.Threading.Tasks; using MimeKit.Text; +using System.IO; namespace AyaNova.Util { public interface IMailer { - Task SendEmailAsync(string email, string subject, string body, AyaNova.Models.GlobalOpsNotificationSettings smtpSettings, string bodyHTML = null); + Task SendEmailAsync(string email, string subject, string body, AyaNova.Models.GlobalOpsNotificationSettings smtpSettings, string attachPDF = null); } public class Mailer : IMailer @@ -18,7 +19,7 @@ namespace AyaNova.Util } - public async Task SendEmailAsync(string email, string subject, string body, AyaNova.Models.GlobalOpsNotificationSettings smtpSettings, string bodyHTML = null) + public async Task SendEmailAsync(string email, string subject, string body, AyaNova.Models.GlobalOpsNotificationSettings smtpSettings, string attachPDFPath = null) { try { @@ -26,13 +27,28 @@ namespace AyaNova.Util message.From.Add(new MailboxAddress(smtpSettings.NotifyFromAddress, smtpSettings.NotifyFromAddress)); message.To.Add(MailboxAddress.Parse(email)); message.Subject = subject; - if (!string.IsNullOrWhiteSpace(body)) - message.Body = new TextPart(TextFormat.Plain) { Text = body }; - if (!string.IsNullOrWhiteSpace(bodyHTML)) - message.Body = new TextPart("html") + + if (!string.IsNullOrWhiteSpace(attachPDFPath)) + { + var attachment = new MimePart("application/pdf", "pdf") { - Text = body + Content = new MimeContent(File.OpenRead(attachPDFPath), ContentEncoding.Default), + ContentDisposition = new ContentDisposition(ContentDisposition.Attachment), + ContentTransferEncoding = ContentEncoding.Base64, + FileName = Path.GetFileName(attachPDFPath) }; + + var multipart = new Multipart("mixed"); + if (!string.IsNullOrWhiteSpace(body)) + multipart.Add(new TextPart(TextFormat.Plain) { Text = body }); + multipart.Add(attachment); + message.Body = multipart; + } + else + { + if (!string.IsNullOrWhiteSpace(body)) + message.Body = new TextPart(TextFormat.Plain) { Text = body }; + } using (var client = new SmtpClient()) {