using System; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; using AyaNova.Models; using AyaNova.Api.ControllerHelpers; using AyaNova.Biz; using System.Linq; using Microsoft.EntityFrameworkCore; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; namespace AyaNova.Api.Controllers { [ApiController] [ApiVersion("8.0")] [Route("api/v{version:apiVersion}/notify")] [Produces("application/json")] [Authorize] public class NotifyController : ControllerBase { private readonly AyContext ct; private readonly ILogger log; private readonly ApiServerState serverState; /// /// ctor /// /// /// /// public NotifyController(AyContext dbcontext, ILogger logger, ApiServerState apiServerState) { ct = dbcontext; log = logger; serverState = apiServerState; } /// /// Pre-login route to confirm server is available /// /// [AllowAnonymous] [HttpGet("hello")] public async Task GetPreLoginPing() { bool showSampleLogins = false; if (AyaNova.Core.License.ActiveKey.Status == AyaNova.Core.License.AyaNovaLicenseKey.LicenseStatus.ActiveTrial) showSampleLogins = await AyaNova.Util.DbUtil.DBHasTrialUsersAsync(ct, log); bool suIsDefault = await UserBiz.SuperIsDefaultCredsAsync(ct); //confirm if there are logo's to show as well var logo = await ct.Logo.AsNoTracking().SingleOrDefaultAsync(); if (logo == null) { return Ok(ApiOkResponse.Response(new { eval = showSampleLogins, sudf = suIsDefault, ll = false, ml = false, sl = false, lcr = AyaNova.Core.License.LicenseConsentRequired })); } return Ok(ApiOkResponse.Response( new { eval = showSampleLogins, sudf = suIsDefault, ll = logo.Large != null ? true : false, ml = logo.Medium != null ? true : false, sl = logo.Small != null ? true : false, lcr = AyaNova.Core.License.LicenseConsentRequired })); } /// /// Get count of new notifications waiting /// /// [HttpGet("new-count")] public async Task GetNewCount() { var UserId = UserIdFromContext.Id(HttpContext.Items); if (serverState.IsClosed && UserId != 1)//bypass for superuser to fix fundamental problems return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); return Ok(ApiOkResponse.Response(await ct.InAppNotification.CountAsync(z => z.UserId == UserId && z.Fetched == false))); } /// /// Get all in-app notifications /// /// [HttpGet("app-notifications")] public async Task GetAppNotifications() { if (serverState.IsClosed) return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); var UserId = UserIdFromContext.Id(HttpContext.Items); var ret = await ct.InAppNotification.AsNoTracking().Where(z => z.UserId == UserId).OrderByDescending(z => z.Created).ToListAsync(); await ct.Database.ExecuteSqlInterpolatedAsync($"update ainappnotification set fetched={true} where userid = {UserId}"); return Ok(ApiOkResponse.Response(ret)); } /// /// Delete app Notification /// /// /// NoContent [HttpDelete("{id}")] public async Task DeleteAppNotification([FromRoute] long id) { if (!serverState.IsOpen) return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); if (!ModelState.IsValid) return BadRequest(new ApiErrorResponse(ModelState)); var UserId = UserIdFromContext.Id(HttpContext.Items); var n = await ct.InAppNotification.FirstOrDefaultAsync(z => z.Id == id); if (n == null) return BadRequest(new ApiErrorResponse(ApiErrorCode.NOT_FOUND, "id")); if (n.UserId != UserId) return BadRequest(new ApiErrorResponse(ApiErrorCode.NOT_AUTHORIZED, null, "Can't delete notification for another user")); ct.InAppNotification.Remove(n); await ct.SaveChangesAsync(); return NoContent(); } /// /// Get Notify Event object list from queue /// /// Notify Event objects awaiting delivery [HttpGet("queue")] public async Task GetQueue() { if (serverState.IsClosed) return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); if (!Authorized.HasReadFullRole(HttpContext.Items, AyaType.OpsNotificationSettings)) { return StatusCode(403, new ApiNotAuthorizedResponse()); } if (!ModelState.IsValid) { return BadRequest(new ApiErrorResponse(ModelState)); } var ret = new List(); var NotifyEvents = await ct.NotifyEvent.AsNoTracking().ToListAsync(); foreach (NotifyEvent ne in NotifyEvents) { var UserInfo = await ct.User.AsNoTracking().Where(x => x.Id == ne.UserId).Select(x => new { Active = x.Active, Name = x.Name }).FirstOrDefaultAsync(); var Subscription = await ct.NotifySubscription.AsNoTracking().FirstOrDefaultAsync(x => x.Id == ne.NotifySubscriptionId); ret.Add(new NotifyEventQueueItem(ne.Id, ne.Created, ne.EventDate, (ne.EventDate + Subscription.AgeValue - Subscription.AdvanceNotice), ne.UserId, UserInfo.Name, ne.EventType, ne.AyaType, ne.Name)); } return Ok(ApiOkResponse.Response(ret)); } public record NotifyEventQueueItem(long Id, DateTime Created, DateTime EventDate, DateTime DeliverAfter, long UserId, string User, NotifyEventType EventType, AyaType AyaType, string Name); /// /// Delete pending notification event /// /// /// NoContent [HttpDelete("notify-event/{id}")] public async Task DeleteNotifyEvent([FromRoute] long id) { if (!serverState.IsOpen) return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); if (!ModelState.IsValid) return BadRequest(new ApiErrorResponse(ModelState)); if (!Authorized.HasDeleteRole(HttpContext.Items, AyaType.OpsNotificationSettings)) { return StatusCode(403, new ApiNotAuthorizedResponse()); } var n = await ct.NotifyEvent.FirstOrDefaultAsync(z => z.Id == id); if (n == null) return BadRequest(new ApiErrorResponse(ApiErrorCode.NOT_FOUND, "id")); ct.NotifyEvent.Remove(n); await ct.SaveChangesAsync(); return NoContent(); } /// /// Send direct message notification to selected users /// /// NoContent on success or error [HttpPost("direct-message")] public async Task SendNotifyDirectMessage([FromBody] NotifyDirectMessage notifyDirectMessage) { if (serverState.IsClosed) return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); if (!ModelState.IsValid) return BadRequest(new ApiErrorResponse(ModelState)); foreach (long l in notifyDirectMessage.Users) { if (l != 0) await NotifyEventHelper.AddGeneralNotifyEvent( NotifyEventType.GeneralNotification, notifyDirectMessage.Message, UserNameFromContext.Name(HttpContext.Items), null, l ); } return NoContent(); } public class NotifyDirectMessage { public NotifyDirectMessage() { Users = new List(); } [Required] public string Message { get; set; } [Required] public List Users { get; set; } } //------------ }//eoc }//eons