Auth Email Rework (#1567)
* Hooked up Send to for Series and volumes and fixed a bug where Email Service errors weren't propagating to the UI layer. When performing actions on series detail, don't disable the button anymore. * Added send to action to volumes * Fixed a bug where .kavitaignore wasn't being applied at library root level * Added a notification for when a device is being sent a file. * Added a check in forgot password for users that do not have an email set or aren't confirmed. * Added a new api for change email and moved change password directly into new Account tab (styling and logic needs testing) * Save approx scroll position like with jump key, but on normal click of card. * Implemented the ability to change your email address or set one. This requires a 2 step process using a confirmation token. This needs polishing and css. * Removed an unused directive from codebase * Fixed up some typos on publicly * Updated query for Pending Invites to also check if the user account has not logged in at least once. * Cleaned up the css for validate email change * Hooked in an indicator to tell user that a user has an unconfirmed email * Cleaned up code smells
This commit is contained in:
parent
3792ac3421
commit
5f17c2fb73
49 changed files with 816 additions and 274 deletions
|
|
@ -7,6 +7,7 @@ using API.DTOs.Device;
|
|||
using API.DTOs.Email;
|
||||
using API.Entities;
|
||||
using API.Entities.Enums;
|
||||
using API.SignalR;
|
||||
using Kavita.Common;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
|
|
@ -17,7 +18,7 @@ public interface IDeviceService
|
|||
Task<Device> Create(CreateDeviceDto dto, AppUser userWithDevices);
|
||||
Task<Device> Update(UpdateDeviceDto dto, AppUser userWithDevices);
|
||||
Task<bool> Delete(AppUser userWithDevices, int deviceId);
|
||||
Task<bool> SendTo(int chapterId, int deviceId);
|
||||
Task<bool> SendTo(IReadOnlyList<int> chapterIds, int deviceId);
|
||||
}
|
||||
|
||||
public class DeviceService : IDeviceService
|
||||
|
|
@ -102,9 +103,9 @@ public class DeviceService : IDeviceService
|
|||
return false;
|
||||
}
|
||||
|
||||
public async Task<bool> SendTo(int chapterId, int deviceId)
|
||||
public async Task<bool> SendTo(IReadOnlyList<int> chapterIds, int deviceId)
|
||||
{
|
||||
var files = await _unitOfWork.ChapterRepository.GetFilesForChapterAsync(chapterId);
|
||||
var files = await _unitOfWork.ChapterRepository.GetFilesForChaptersAsync(chapterIds);
|
||||
if (files.Any(f => f.Format is not (MangaFormat.Epub or MangaFormat.Pdf)))
|
||||
throw new KavitaException("Cannot Send non Epub or Pdf to devices as not supported");
|
||||
|
||||
|
|
@ -118,6 +119,7 @@ public class DeviceService : IDeviceService
|
|||
DestinationEmail = device.EmailAddress,
|
||||
FilePaths = files.Select(m => m.FilePath)
|
||||
});
|
||||
|
||||
return success;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using API.Data;
|
||||
using API.DTOs.Email;
|
||||
|
|
@ -14,7 +12,6 @@ using Kavita.Common.EnvironmentInfo;
|
|||
using Kavita.Common.Helpers;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace API.Services;
|
||||
|
||||
|
|
@ -27,6 +24,7 @@ public interface IEmailService
|
|||
Task<bool> SendFilesToEmail(SendToDto data);
|
||||
Task<EmailTestResultDto> TestConnectivity(string emailUrl);
|
||||
Task<bool> IsDefaultEmailService();
|
||||
Task SendEmailChangeEmail(ConfirmationEmailDto data);
|
||||
}
|
||||
|
||||
public class EmailService : IEmailService
|
||||
|
|
@ -84,6 +82,16 @@ public class EmailService : IEmailService
|
|||
.Equals(DefaultApiUrl);
|
||||
}
|
||||
|
||||
public async Task SendEmailChangeEmail(ConfirmationEmailDto data)
|
||||
{
|
||||
var emailLink = (await _unitOfWork.SettingsRepository.GetSettingAsync(ServerSettingKey.EmailServiceUrl)).Value;
|
||||
var success = await SendEmailWithPost(emailLink + "/api/account/email-change", data);
|
||||
if (!success)
|
||||
{
|
||||
_logger.LogError("There was a critical error sending Confirmation email");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task SendConfirmationEmail(ConfirmationEmailDto data)
|
||||
{
|
||||
var emailLink = (await _unitOfWork.SettingsRepository.GetSettingAsync(ServerSettingKey.EmailServiceUrl)).Value;
|
||||
|
|
@ -172,18 +180,20 @@ public class EmailService : IEmailService
|
|||
|
||||
if (response.StatusCode != StatusCodes.Status200OK)
|
||||
{
|
||||
return false;
|
||||
var errorMessage = await response.GetStringAsync();
|
||||
throw new KavitaException(errorMessage);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
catch (FlurlHttpException ex)
|
||||
{
|
||||
_logger.LogError(ex, "There was an exception when interacting with Email Service");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private async Task<bool> SendEmailWithFiles(string url, IEnumerable<string> filePaths, string destEmail, int timeoutSecs = 30)
|
||||
private async Task<bool> SendEmailWithFiles(string url, IEnumerable<string> filePaths, string destEmail, int timeoutSecs = 300)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -193,7 +203,8 @@ public class EmailService : IEmailService
|
|||
.WithHeader("x-api-key", "MsnvA2DfQqxSK5jh")
|
||||
.WithHeader("x-kavita-version", BuildInfo.Version)
|
||||
.WithHeader("x-kavita-installId", settings.InstallId)
|
||||
.WithTimeout(TimeSpan.FromSeconds(timeoutSecs))
|
||||
.WithTimeout(timeoutSecs)
|
||||
.AllowHttpStatus("4xx")
|
||||
.PostMultipartAsync(mp =>
|
||||
{
|
||||
mp.AddString("email", destEmail);
|
||||
|
|
@ -208,10 +219,11 @@ public class EmailService : IEmailService
|
|||
|
||||
if (response.StatusCode != StatusCodes.Status200OK)
|
||||
{
|
||||
return false;
|
||||
var errorMessage = await response.GetStringAsync();
|
||||
throw new KavitaException(errorMessage);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch (FlurlHttpException ex)
|
||||
{
|
||||
_logger.LogError(ex, "There was an exception when sending Email for SendTo");
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -82,7 +82,8 @@ public class ParseScannedFiles
|
|||
{
|
||||
// This is used in library scan, so we should check first for a ignore file and use that here as well
|
||||
var potentialIgnoreFile = _directoryService.FileSystem.Path.Join(folderPath, DirectoryService.KavitaIgnoreFile);
|
||||
var directories = _directoryService.GetDirectories(folderPath, _directoryService.CreateMatcherFromFile(potentialIgnoreFile)).ToList();
|
||||
var matcher = _directoryService.CreateMatcherFromFile(potentialIgnoreFile);
|
||||
var directories = _directoryService.GetDirectories(folderPath, matcher).ToList();
|
||||
|
||||
foreach (var directory in directories)
|
||||
{
|
||||
|
|
@ -94,7 +95,7 @@ public class ParseScannedFiles
|
|||
else
|
||||
{
|
||||
// For a scan, this is doing everything in the directory loop before the folder Action is called...which leads to no progress indication
|
||||
await folderAction(_directoryService.ScanFiles(directory), directory);
|
||||
await folderAction(_directoryService.ScanFiles(directory, matcher), directory);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue