mirror of
https://github.com/Kareadita/Kavita.git
synced 2025-05-31 04:04:19 -04:00
Private Email Service Support (#1028)
* Added ServerSettingKey's for SMTP and moved email service code to Kavita. Nothing integrated in the UI yet. * Undo all the custom SMTP stuff and prepare for custom email service url. * Foundation for email service to use a custom url is setup. * Implemented the ability to hook up custom email url
This commit is contained in:
parent
2517ee75b2
commit
2ae9f8c203
@ -101,6 +101,9 @@
|
||||
<Compile Remove="logs\**" />
|
||||
<Compile Remove="temp\**" />
|
||||
<Compile Remove="covers\**" />
|
||||
<Compile Remove="DTOs\Email\SmtpConfig.cs" />
|
||||
<Compile Remove="DTOs\Email\EmailOptionsDto.cs" />
|
||||
<Compile Remove="Helpers\Converters\SmtpConverter.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -1,8 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
@ -17,8 +15,6 @@ using API.Errors;
|
||||
using API.Extensions;
|
||||
using API.Services;
|
||||
using AutoMapper;
|
||||
using AutoMapper.QueryableExtensions;
|
||||
using Flurl.Util;
|
||||
using Kavita.Common;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
@ -113,14 +109,6 @@ namespace API.Controllers
|
||||
ApiKey = HashUtil.ApiKey()
|
||||
};
|
||||
|
||||
// I am removing Authentication disabled code
|
||||
// var settings = await _unitOfWork.SettingsRepository.GetSettingsDtoAsync();
|
||||
// if (!settings.EnableAuthentication && !registerDto.IsAdmin)
|
||||
// {
|
||||
// _logger.LogInformation("User {UserName} is being registered as non-admin with no server authentication. Using default password", registerDto.Username);
|
||||
// registerDto.Password = AccountService.DefaultPassword;
|
||||
// }
|
||||
|
||||
var result = await _userManager.CreateAsync(user, registerDto.Password);
|
||||
if (!result.Succeeded) return BadRequest(result.Errors);
|
||||
|
||||
@ -132,22 +120,6 @@ namespace API.Controllers
|
||||
var roleResult = await _userManager.AddToRoleAsync(user, PolicyConstants.AdminRole);
|
||||
if (!roleResult.Succeeded) return BadRequest(result.Errors);
|
||||
|
||||
// // When we register an admin, we need to grant them access to all Libraries.
|
||||
// if (registerDto.IsAdmin)
|
||||
// {
|
||||
// _logger.LogInformation("{UserName} is being registered as admin. Granting access to all libraries",
|
||||
// user.UserName);
|
||||
// var libraries = (await _unitOfWork.LibraryRepository.GetLibrariesAsync()).ToList();
|
||||
// foreach (var lib in libraries)
|
||||
// {
|
||||
// lib.AppUsers ??= new List<AppUser>();
|
||||
// lib.AppUsers.Add(user);
|
||||
// }
|
||||
//
|
||||
// if (libraries.Any() && !await _unitOfWork.CommitAsync())
|
||||
// _logger.LogError("There was an issue granting library access. Please do this manually");
|
||||
// }
|
||||
|
||||
return new UserDto
|
||||
{
|
||||
Username = user.UserName,
|
||||
|
@ -4,14 +4,17 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using API.Data;
|
||||
using API.DTOs.Email;
|
||||
using API.DTOs.Settings;
|
||||
using API.Entities.Enums;
|
||||
using API.Extensions;
|
||||
using API.Helpers.Converters;
|
||||
using API.Services;
|
||||
using AutoMapper;
|
||||
using Flurl.Http;
|
||||
using Kavita.Common;
|
||||
using Kavita.Common.Extensions;
|
||||
using Kavita.Common.Helpers;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
@ -25,15 +28,17 @@ namespace API.Controllers
|
||||
private readonly ITaskScheduler _taskScheduler;
|
||||
private readonly IDirectoryService _directoryService;
|
||||
private readonly IMapper _mapper;
|
||||
private readonly IEmailService _emailService;
|
||||
|
||||
public SettingsController(ILogger<SettingsController> logger, IUnitOfWork unitOfWork, ITaskScheduler taskScheduler,
|
||||
IDirectoryService directoryService, IMapper mapper)
|
||||
IDirectoryService directoryService, IMapper mapper, IEmailService emailService)
|
||||
{
|
||||
_logger = logger;
|
||||
_unitOfWork = unitOfWork;
|
||||
_taskScheduler = taskScheduler;
|
||||
_directoryService = directoryService;
|
||||
_mapper = mapper;
|
||||
_emailService = emailService;
|
||||
}
|
||||
|
||||
[AllowAnonymous]
|
||||
@ -64,6 +69,36 @@ namespace API.Controllers
|
||||
return await UpdateSettings(_mapper.Map<ServerSettingDto>(Seed.DefaultSettings));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets the email service url
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[Authorize(Policy = "RequireAdminRole")]
|
||||
[HttpPost("reset-email-url")]
|
||||
public async Task<ActionResult<ServerSettingDto>> ResetEmailServiceUrlSettings()
|
||||
{
|
||||
_logger.LogInformation("{UserName} is resetting Email Service Url Setting", User.GetUsername());
|
||||
var emailSetting = await _unitOfWork.SettingsRepository.GetSettingAsync(ServerSettingKey.EmailServiceUrl);
|
||||
emailSetting.Value = EmailService.DefaultApiUrl;
|
||||
_unitOfWork.SettingsRepository.Update(emailSetting);
|
||||
|
||||
if (!await _unitOfWork.CommitAsync())
|
||||
{
|
||||
await _unitOfWork.RollbackAsync();
|
||||
}
|
||||
|
||||
return Ok(await _unitOfWork.SettingsRepository.GetSettingsDtoAsync());
|
||||
}
|
||||
|
||||
[Authorize(Policy = "RequireAdminRole")]
|
||||
[HttpPost("test-email-url")]
|
||||
public async Task<ActionResult<bool>> TestEmailServiceUrl(TestEmailDto dto)
|
||||
{
|
||||
return Ok(await _emailService.TestConnectivity(dto.Url));
|
||||
}
|
||||
|
||||
|
||||
|
||||
[Authorize(Policy = "RequireAdminRole")]
|
||||
[HttpPost]
|
||||
public async Task<ActionResult<ServerSettingDto>> UpdateSettings(ServerSettingDto updateSettingsDto)
|
||||
@ -173,6 +208,15 @@ namespace API.Controllers
|
||||
await _taskScheduler.ScheduleStatsTasks();
|
||||
}
|
||||
}
|
||||
|
||||
if (setting.Key == ServerSettingKey.EmailServiceUrl && updateSettingsDto.EmailServiceUrl + string.Empty != setting.Value)
|
||||
{
|
||||
setting.Value = string.IsNullOrEmpty(updateSettingsDto.EmailServiceUrl) ? EmailService.DefaultApiUrl : updateSettingsDto.EmailServiceUrl;
|
||||
FlurlHttp.ConfigureClient(setting.Value, cli =>
|
||||
cli.Settings.HttpClientFactory = new UntrustedCertClientFactory());
|
||||
|
||||
_unitOfWork.SettingsRepository.Update(setting);
|
||||
}
|
||||
}
|
||||
|
||||
if (!_unitOfWork.HasChanges()) return Ok(updateSettingsDto);
|
||||
|
6
API/DTOs/Email/TestEmailDto.cs
Normal file
6
API/DTOs/Email/TestEmailDto.cs
Normal file
@ -0,0 +1,6 @@
|
||||
namespace API.DTOs.Email;
|
||||
|
||||
public class TestEmailDto
|
||||
{
|
||||
public string Url { get; set; }
|
||||
}
|
@ -32,5 +32,10 @@ namespace API.DTOs.Settings
|
||||
/// </summary>
|
||||
/// <remarks>If null or empty string, will default back to default install setting aka <see cref="DirectoryService.BookmarkDirectory"/></remarks>
|
||||
public string BookmarksDirectory { get; set; }
|
||||
/// <summary>
|
||||
/// Email service to use for the invite user flow, forgot password, etc.
|
||||
/// </summary>
|
||||
/// <remarks>If null or empty string, will default back to default install setting aka <see cref="EmailService.DefaultApiUrl"/></remarks>
|
||||
public string EmailServiceUrl { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -60,6 +60,7 @@ namespace API.Data
|
||||
new () {Key = ServerSettingKey.InstallId, Value = HashUtil.AnonymousToken()},
|
||||
new () {Key = ServerSettingKey.InstallVersion, Value = BuildInfo.Version.ToString()},
|
||||
new () {Key = ServerSettingKey.BookmarkDirectory, Value = directoryService.BookmarkDirectory},
|
||||
new () {Key = ServerSettingKey.EmailServiceUrl, Value = EmailService.DefaultApiUrl},
|
||||
};
|
||||
|
||||
foreach (var defaultSetting in DefaultSettings)
|
||||
|
@ -71,6 +71,10 @@ namespace API.Entities.Enums
|
||||
/// </summary>
|
||||
[Description("BookmarkDirectory")]
|
||||
BookmarkDirectory = 12,
|
||||
|
||||
/// <summary>
|
||||
/// If SMTP is enabled on the server
|
||||
/// </summary>
|
||||
[Description("CustomEmailService")]
|
||||
EmailServiceUrl = 13,
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,6 @@ namespace API.Extensions
|
||||
services.AddScoped<IAccountService, AccountService>();
|
||||
services.AddScoped<IEmailService, EmailService>();
|
||||
|
||||
|
||||
services.AddScoped<IFileSystem, FileSystem>();
|
||||
services.AddScoped<IFileService, FileService>();
|
||||
services.AddScoped<ICacheHelper, CacheHelper>();
|
||||
|
@ -2,6 +2,7 @@
|
||||
using System.Linq;
|
||||
using API.DTOs;
|
||||
using API.DTOs.CollectionTags;
|
||||
using API.DTOs.Email;
|
||||
using API.DTOs.Metadata;
|
||||
using API.DTOs.Reader;
|
||||
using API.DTOs.ReadingLists;
|
||||
@ -148,7 +149,6 @@ namespace API.Helpers
|
||||
|
||||
CreateMap<IEnumerable<ServerSetting>, ServerSettingDto>()
|
||||
.ConvertUsing<ServerSettingConverter>();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,6 +42,9 @@ namespace API.Helpers.Converters
|
||||
case ServerSettingKey.BookmarkDirectory:
|
||||
destination.BookmarksDirectory = row.Value;
|
||||
break;
|
||||
case ServerSettingKey.EmailServiceUrl:
|
||||
destination.EmailServiceUrl = row.Value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using API.Data;
|
||||
using API.DTOs.Email;
|
||||
using API.Services.Tasks;
|
||||
using API.Entities.Enums;
|
||||
using Flurl.Http;
|
||||
using Kavita.Common.EnvironmentInfo;
|
||||
using Kavita.Common.Helpers;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
@ -16,25 +17,39 @@ public interface IEmailService
|
||||
Task<bool> CheckIfAccessible(string host);
|
||||
Task SendMigrationEmail(EmailMigrationDto data);
|
||||
Task SendPasswordResetEmail(PasswordResetEmailDto data);
|
||||
Task<bool> TestConnectivity(string emailUrl);
|
||||
}
|
||||
|
||||
public class EmailService : IEmailService
|
||||
{
|
||||
private readonly ILogger<EmailService> _logger;
|
||||
private const string ApiUrl = "https://email.kavitareader.com";
|
||||
private readonly IUnitOfWork _unitOfWork;
|
||||
|
||||
public EmailService(ILogger<EmailService> logger)
|
||||
/// <summary>
|
||||
/// This is used to initially set or reset the ServerSettingKey. Do not access from the code, access via UnitOfWork
|
||||
/// </summary>
|
||||
public const string DefaultApiUrl = "https://email.kavitareader.com";
|
||||
|
||||
public EmailService(ILogger<EmailService> logger, IUnitOfWork unitOfWork)
|
||||
{
|
||||
_logger = logger;
|
||||
_unitOfWork = unitOfWork;
|
||||
|
||||
FlurlHttp.ConfigureClient(ApiUrl, cli =>
|
||||
FlurlHttp.ConfigureClient(DefaultApiUrl, cli =>
|
||||
cli.Settings.HttpClientFactory = new UntrustedCertClientFactory());
|
||||
}
|
||||
|
||||
public async Task<bool> TestConnectivity(string emailUrl)
|
||||
{
|
||||
FlurlHttp.ConfigureClient(emailUrl, cli =>
|
||||
cli.Settings.HttpClientFactory = new UntrustedCertClientFactory());
|
||||
|
||||
return await SendEmailWithGet(emailUrl + "/api/email/test");
|
||||
}
|
||||
|
||||
public async Task SendConfirmationEmail(ConfirmationEmailDto data)
|
||||
{
|
||||
|
||||
var success = await SendEmailWithPost(ApiUrl + "/api/email/confirm", data);
|
||||
var success = await SendEmailWithPost(DefaultApiUrl + "/api/email/confirm", data);
|
||||
if (!success)
|
||||
{
|
||||
_logger.LogError("There was a critical error sending Confirmation email");
|
||||
@ -43,17 +58,20 @@ public class EmailService : IEmailService
|
||||
|
||||
public async Task<bool> CheckIfAccessible(string host)
|
||||
{
|
||||
return await SendEmailWithGet(ApiUrl + "/api/email/reachable?host=" + host);
|
||||
// This is the only exception for using the default because we need an external service to check if the server is accessible for emails
|
||||
return await SendEmailWithGet(DefaultApiUrl + "/api/email/reachable?host=" + host);
|
||||
}
|
||||
|
||||
public async Task SendMigrationEmail(EmailMigrationDto data)
|
||||
{
|
||||
await SendEmailWithPost(ApiUrl + "/api/email/email-migration", data);
|
||||
var emailLink = (await _unitOfWork.SettingsRepository.GetSettingAsync(ServerSettingKey.EmailServiceUrl)).Value;
|
||||
await SendEmailWithPost(emailLink + "/api/email/email-migration", data);
|
||||
}
|
||||
|
||||
public async Task SendPasswordResetEmail(PasswordResetEmailDto data)
|
||||
{
|
||||
await SendEmailWithPost(ApiUrl + "/api/email/email-password-reset", data);
|
||||
var emailLink = (await _unitOfWork.SettingsRepository.GetSettingAsync(ServerSettingKey.EmailServiceUrl)).Value;
|
||||
await SendEmailWithPost(emailLink + "/api/email/email-password-reset", data);
|
||||
}
|
||||
|
||||
private static async Task<bool> SendEmailWithGet(string url)
|
||||
@ -106,4 +124,5 @@ public class EmailService : IEmailService
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ using API.DTOs.Stats;
|
||||
using API.Entities.Enums;
|
||||
using Flurl.Http;
|
||||
using Kavita.Common.EnvironmentInfo;
|
||||
using Kavita.Common.Helpers;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
|
@ -1,14 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using API.DTOs.Update;
|
||||
using API.SignalR;
|
||||
using API.SignalR.Presence;
|
||||
using Flurl.Http;
|
||||
using Flurl.Http.Configuration;
|
||||
using Kavita.Common.EnvironmentInfo;
|
||||
using Kavita.Common.Helpers;
|
||||
using MarkdownDeep;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
@ -44,15 +43,6 @@ internal class GithubReleaseMetadata
|
||||
public string Published_At { get; init; }
|
||||
}
|
||||
|
||||
public class UntrustedCertClientFactory : DefaultHttpClientFactory
|
||||
{
|
||||
public override HttpMessageHandler CreateMessageHandler() {
|
||||
return new HttpClientHandler {
|
||||
ServerCertificateCustomValidationCallback = (_, _, _, _) => true
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public interface IVersionUpdaterService
|
||||
{
|
||||
Task<UpdateNotificationDto> CheckForUpdate();
|
||||
|
13
Kavita.Common/Helpers/UntrustedCertClientFactory.cs
Normal file
13
Kavita.Common/Helpers/UntrustedCertClientFactory.cs
Normal file
@ -0,0 +1,13 @@
|
||||
using System.Net.Http;
|
||||
using Flurl.Http.Configuration;
|
||||
|
||||
namespace Kavita.Common.Helpers;
|
||||
|
||||
public class UntrustedCertClientFactory : DefaultHttpClientFactory
|
||||
{
|
||||
public override HttpMessageHandler CreateMessageHandler() {
|
||||
return new HttpClientHandler {
|
||||
ServerCertificateCustomValidationCallback = (_, _, _, _) => true
|
||||
};
|
||||
}
|
||||
}
|
@ -9,6 +9,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Flurl.Http" Version="3.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.0" />
|
||||
<PackageReference Include="SonarAnalyzer.CSharp" Version="8.33.0.40503">
|
||||
|
22
Kavita.Email/Kavita.Email.csproj
Normal file
22
Kavita.Email/Kavita.Email.csproj
Normal file
@ -0,0 +1,22 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Flurl.Http" Version="3.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Kavita.Common\Kavita.Common.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="DTOs" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -8,4 +8,5 @@ export interface ServerSettings {
|
||||
enableOpds: boolean;
|
||||
baseUrl: string;
|
||||
bookmarksDirectory: string;
|
||||
emailServiceUrl: string;
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { FormControl, FormGroup, Validators } from '@angular/forms';
|
||||
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
|
||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { ConfirmService } from 'src/app/shared/confirm.service';
|
||||
import { Library } from 'src/app/_models/library';
|
||||
|
@ -64,6 +64,28 @@
|
||||
<label for="opds" class="form-check-label">Enable OPDS</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4>Email Services (SMTP)</h4>
|
||||
<p class="accent">Kavita comes out of the box with an email service to power flows like invite user, forgot password, etc. Emails sent via our service are deleted immediately. You can use your own
|
||||
email service. Set the url of the email service and use the Test button to ensure it works. At any time you can reset to ours. There is no way to disable emails.
|
||||
</p>
|
||||
<div class="form-group">
|
||||
<label for="settings-emailservice">Email Service Url</label> <i class="fa fa-info-circle" placement="right" [ngbTooltip]="emailServiceTooltip" role="button" tabindex="0"></i>
|
||||
<ng-template #emailServiceTooltip>Location where bookmarks will be stored. Bookmarks are source files and can be large. Choose a location with adequate storage. Directory is managed, other files within directory will be deleted.</ng-template>
|
||||
<span class="sr-only" id="settings-emailservice-help"><ng-container [ngTemplateOutlet]="emailServiceTooltip"></ng-container></span>
|
||||
<div class="input-group">
|
||||
<input id="settings-emailservice" aria-describedby="settings-emailservice-help" class="form-control" formControlName="emailServiceUrl" type="text" aria-describedby="change-bookmarks-dir">
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-secondary" (click)="resetEmailServiceUrl()">
|
||||
Reset
|
||||
</button>
|
||||
<button class="btn btn-secondary" (click)="testEmailServiceUrl()">
|
||||
Test
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<h4>Reoccuring Tasks</h4>
|
||||
<div class="form-group">
|
||||
|
@ -41,6 +41,7 @@ export class ManageSettingsComponent implements OnInit {
|
||||
this.settingsForm.addControl('allowStatCollection', new FormControl(this.serverSettings.allowStatCollection, [Validators.required]));
|
||||
this.settingsForm.addControl('enableOpds', new FormControl(this.serverSettings.enableOpds, [Validators.required]));
|
||||
this.settingsForm.addControl('baseUrl', new FormControl(this.serverSettings.baseUrl, [Validators.required]));
|
||||
this.settingsForm.addControl('emailServiceUrl', new FormControl(this.serverSettings.emailServiceUrl, [Validators.required]));
|
||||
});
|
||||
}
|
||||
|
||||
@ -54,6 +55,7 @@ export class ManageSettingsComponent implements OnInit {
|
||||
this.settingsForm.get('allowStatCollection')?.setValue(this.serverSettings.allowStatCollection);
|
||||
this.settingsForm.get('enableOpds')?.setValue(this.serverSettings.enableOpds);
|
||||
this.settingsForm.get('baseUrl')?.setValue(this.serverSettings.baseUrl);
|
||||
this.settingsForm.get('emailServiceUrl')?.setValue(this.serverSettings.emailServiceUrl);
|
||||
}
|
||||
|
||||
async saveSettings() {
|
||||
@ -90,4 +92,28 @@ export class ManageSettingsComponent implements OnInit {
|
||||
});
|
||||
}
|
||||
|
||||
resetEmailServiceUrl() {
|
||||
this.settingsService.resetEmailServerSettings().pipe(take(1)).subscribe(async (settings: ServerSettings) => {
|
||||
this.serverSettings.emailServiceUrl = settings.emailServiceUrl;
|
||||
this.resetForm();
|
||||
this.toastr.success('Email Service Reset');
|
||||
}, (err: any) => {
|
||||
console.error('error: ', err);
|
||||
});
|
||||
}
|
||||
|
||||
testEmailServiceUrl() {
|
||||
this.settingsService.testEmailServerSettings(this.settingsForm.get('emailServiceUrl')?.value || '').pipe(take(1)).subscribe(async (successful: boolean) => {
|
||||
if (successful) {
|
||||
this.toastr.success('Email Service Url validated');
|
||||
} else {
|
||||
this.toastr.error('Email Service Url did not respond');
|
||||
}
|
||||
|
||||
}, (err: any) => {
|
||||
console.error('error: ', err);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -25,6 +25,14 @@ export class SettingsService {
|
||||
return this.http.post<ServerSettings>(this.baseUrl + 'settings/reset', {});
|
||||
}
|
||||
|
||||
resetEmailServerSettings() {
|
||||
return this.http.post<ServerSettings>(this.baseUrl + 'settings/reset-email-url', {});
|
||||
}
|
||||
|
||||
testEmailServerSettings(emailUrl: string) {
|
||||
return this.http.post<boolean>(this.baseUrl + 'settings/test-email-url', {url: emailUrl}, {responseType: 'text' as 'json'});
|
||||
}
|
||||
|
||||
getTaskFrequencies() {
|
||||
return this.http.get<string[]>(this.baseUrl + 'settings/task-frequencies');
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user