(feature): dkim cert upload and managing through gridfs data provider
This commit is contained in:
parent
44a4b7a5e9
commit
cac3d2502e
47
db/DML/sites.json
Normal file
47
db/DML/sites.json
Normal file
@ -0,0 +1,47 @@
|
||||
[
|
||||
{
|
||||
"_id": "404c8232-9048-4519-bfba-6e78dc7005ca",
|
||||
"locale": 0,
|
||||
"name": "Contoso",
|
||||
"hosts": [
|
||||
"localhost:7174",
|
||||
"maks-it.com"
|
||||
],
|
||||
"address": {
|
||||
"street": "123 456th St",
|
||||
"city": "New York",
|
||||
"region": "NY"
|
||||
"postCode": "10001",
|
||||
"country": "US"
|
||||
},
|
||||
"poweredBy": {
|
||||
"target": "https://maks-it.com",
|
||||
"anchorText": "MAKS-IT.com"
|
||||
},
|
||||
"passwordRecoverySettings": {
|
||||
"smtpSettings": {
|
||||
"server": "smtp.ionos.it",
|
||||
"port": 587
|
||||
"useSsl": true,
|
||||
"userName": "commercial@maks-it.com",
|
||||
"password": "nECbzrWqwzM5Lv4zCxV91g=="
|
||||
},
|
||||
"dkimSettings": {
|
||||
"hostName": "maks-it.com",
|
||||
"selector": "default",
|
||||
"dkimId": "0c5527ca-c10f-45a1-b1b2-4b153e89e209"
|
||||
},
|
||||
"templateId": "",
|
||||
"email": {
|
||||
"type": 0,
|
||||
"name": "support",
|
||||
"value": "support@maks-it.com"
|
||||
},
|
||||
"subject": "Password recovery service",
|
||||
"paragraphs": [
|
||||
"Your recovery link: {{recoveryLink}}"
|
||||
]
|
||||
|
||||
}
|
||||
}
|
||||
]
|
||||
@ -1,152 +0,0 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Simple Transactional Email</title>
|
||||
<style>
|
||||
@media only screen and (max-width: 620px) {
|
||||
table.body h1 {
|
||||
font-size: 28px !important;
|
||||
margin-bottom: 10px !important;
|
||||
}
|
||||
|
||||
table.body p,
|
||||
table.body ul,
|
||||
table.body ol,
|
||||
table.body td,
|
||||
table.body span,
|
||||
table.body a {
|
||||
font-size: 16px !important;
|
||||
}
|
||||
|
||||
table.body .wrapper,
|
||||
table.body .article {
|
||||
padding: 10px !important;
|
||||
}
|
||||
|
||||
table.body .content {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
table.body .container {
|
||||
padding: 0 !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
table.body .main {
|
||||
border-left-width: 0 !important;
|
||||
border-radius: 0 !important;
|
||||
border-right-width: 0 !important;
|
||||
}
|
||||
|
||||
table.body .btn table {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
table.body .btn a {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
table.body .img-responsive {
|
||||
height: auto !important;
|
||||
max-width: 100% !important;
|
||||
width: auto !important;
|
||||
}
|
||||
}
|
||||
@media all {
|
||||
.ExternalClass {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ExternalClass,
|
||||
.ExternalClass p,
|
||||
.ExternalClass span,
|
||||
.ExternalClass font,
|
||||
.ExternalClass td,
|
||||
.ExternalClass div {
|
||||
line-height: 100%;
|
||||
}
|
||||
|
||||
.apple-link a {
|
||||
color: inherit !important;
|
||||
font-family: inherit !important;
|
||||
font-size: inherit !important;
|
||||
font-weight: inherit !important;
|
||||
line-height: inherit !important;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
#MessageViewBody a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
font-size: inherit;
|
||||
font-family: inherit;
|
||||
font-weight: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
.btn-primary table td:hover {
|
||||
background-color: #34495e !important;
|
||||
}
|
||||
|
||||
.btn-primary a:hover {
|
||||
background-color: #34495e !important;
|
||||
border-color: #34495e !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body style="background-color: #f6f6f6; font-family: sans-serif; -webkit-font-smoothing: antialiased; font-size: 14px; line-height: 1.4; margin: 0; padding: 0; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%;">
|
||||
<span class="preheader" style="color: transparent; display: none; height: 0; max-height: 0; max-width: 0; opacity: 0; overflow: hidden; mso-hide: all; visibility: hidden; width: 0;">This is preheader text. Some clients will show this text as a preview.</span>
|
||||
<table role="presentation" border="0" cellpadding="0" cellspacing="0" class="body" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; background-color: #f6f6f6; width: 100%;" width="100%" bgcolor="#f6f6f6">
|
||||
<tr>
|
||||
<td style="font-family: sans-serif; font-size: 14px; vertical-align: top;" valign="top"> </td>
|
||||
<td class="container" style="font-family: sans-serif; font-size: 14px; vertical-align: top; display: block; max-width: 580px; padding: 10px; width: 580px; margin: 0 auto;" width="580" valign="top">
|
||||
<div class="content" style="box-sizing: border-box; display: block; margin: 0 auto; max-width: 580px; padding: 10px;">
|
||||
|
||||
<!-- START CENTERED WHITE CONTAINER -->
|
||||
<table role="presentation" class="main" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; background: #ffffff; border-radius: 3px; width: 100%;" width="100%">
|
||||
|
||||
<!-- START MAIN CONTENT AREA -->
|
||||
<tr>
|
||||
<td class="wrapper" style="font-family: sans-serif; font-size: 14px; vertical-align: top; box-sizing: border-box; padding: 20px;" valign="top">
|
||||
<table role="presentation" border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;" width="100%">
|
||||
<tr>
|
||||
<td style="font-family: sans-serif; font-size: 14px; vertical-align: top;" valign="top">
|
||||
{{content}}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- END MAIN CONTENT AREA -->
|
||||
</table>
|
||||
<!-- END CENTERED WHITE CONTAINER -->
|
||||
|
||||
<!-- START FOOTER -->
|
||||
<div class="footer" style="clear: both; margin-top: 10px; text-align: center; width: 100%;">
|
||||
<table role="presentation" border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;" width="100%">
|
||||
<tr>
|
||||
<td class="content-block" style="font-family: sans-serif; vertical-align: top; padding-bottom: 10px; padding-top: 10px; color: #999999; font-size: 12px; text-align: center;" valign="top" align="center">
|
||||
<span class="apple-link" style="color: #999999; font-size: 12px; text-align: center;">{{address}}</span>
|
||||
<br> {{usubscribeText}} <a href="https://maks-it.com" style="text-decoration: underline; color: #999999; font-size: 12px; text-align: center;">{{unsubscribe}}</a>.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="content-block powered-by" style="font-family: sans-serif; vertical-align: top; padding-bottom: 10px; padding-top: 10px; color: #999999; font-size: 12px; text-align: center;" valign="top" align="center">
|
||||
Powered by <a href="https://maks-it.com" style="color: #999999; font-size: 12px; text-align: center; text-decoration: none;">MAKS-IT.com</a>.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<!-- END FOOTER -->
|
||||
|
||||
</div>
|
||||
</td>
|
||||
<td style="font-family: sans-serif; font-size: 14px; vertical-align: top;" valign="top"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
145
postman/templates/password-recovery-template.html
Normal file
145
postman/templates/password-recovery-template.html
Normal file
@ -0,0 +1,145 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>{{subject}}</title>
|
||||
<style>
|
||||
@media only screen and (max-width: 620px) {
|
||||
table.body h1 {
|
||||
font-size: 28px !important;
|
||||
margin-bottom: 10px !important;
|
||||
}
|
||||
|
||||
table.body p,
|
||||
table.body ul,
|
||||
table.body ol,
|
||||
table.body td,
|
||||
table.body span,
|
||||
table.body a {
|
||||
font-size: 16px !important;
|
||||
}
|
||||
|
||||
table.body .wrapper,
|
||||
table.body .article {
|
||||
padding: 10px !important;
|
||||
}
|
||||
|
||||
table.body .content {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
table.body .container {
|
||||
padding: 0 !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
table.body .main {
|
||||
border-left-width: 0 !important;
|
||||
border-radius: 0 !important;
|
||||
border-right-width: 0 !important;
|
||||
}
|
||||
|
||||
table.body .btn table {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
table.body .btn a {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
table.body .img-responsive {
|
||||
height: auto !important;
|
||||
max-width: 100% !important;
|
||||
width: auto !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media all {
|
||||
.ExternalClass {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ExternalClass,
|
||||
.ExternalClass p,
|
||||
.ExternalClass span,
|
||||
.ExternalClass font,
|
||||
.ExternalClass td,
|
||||
.ExternalClass div {
|
||||
line-height: 100%;
|
||||
}
|
||||
|
||||
.apple-link a {
|
||||
color: inherit !important;
|
||||
font-family: inherit !important;
|
||||
font-size: inherit !important;
|
||||
font-weight: inherit !important;
|
||||
line-height: inherit !important;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
#MessageViewBody a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
font-size: inherit;
|
||||
font-family: inherit;
|
||||
font-weight: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
.btn-primary table td:hover {
|
||||
background-color: #34495e !important;
|
||||
}
|
||||
|
||||
.btn-primary a:hover {
|
||||
background-color: #34495e !important;
|
||||
border-color: #34495e !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body style="background-color: #f6f6f6; font-family: sans-serif; -webkit-font-smoothing: antialiased; font-size: 14px; line-height: 1.4; margin: 0; padding: 0; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%;">
|
||||
<span class="preheader" style="color: transparent; display: none; height: 0; max-height: 0; max-width: 0; opacity: 0; overflow: hidden; mso-hide: all; visibility: hidden; width: 0;">This is preheader text. Some clients will show this text as a preview.</span>
|
||||
<table role="presentation" border="0" cellpadding="0" cellspacing="0" class="body" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; background-color: #f6f6f6; width: 100%;" width="100%" bgcolor="#f6f6f6">
|
||||
<tr>
|
||||
<td style="font-family: sans-serif; font-size: 14px; vertical-align: top;" valign="top"> </td>
|
||||
<td class="container" style="font-family: sans-serif; font-size: 14px; vertical-align: top; display: block; max-width: 580px; padding: 10px; width: 580px; margin: 0 auto;" width="580" valign="top">
|
||||
<div class="content" style="box-sizing: border-box; display: block; margin: 0 auto; max-width: 580px; padding: 10px;">
|
||||
|
||||
<!-- START CENTERED WHITE CONTAINER -->
|
||||
<table role="presentation" class="main" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; background: #ffffff; border-radius: 3px; width: 100%;" width="100%">
|
||||
<!-- START MAIN CONTENT AREA -->
|
||||
<tr>
|
||||
<td class="wrapper" style="font-family: sans-serif; font-size: 14px; vertical-align: top; box-sizing: border-box; padding: 20px;" valign="top">
|
||||
<table role="presentation" border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;" width="100%">
|
||||
<tr>
|
||||
<td style="font-family: sans-serif; font-size: 14px; vertical-align: top;" valign="top">
|
||||
{{paragraphs}}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- END MAIN CONTENT AREA -->
|
||||
</table>
|
||||
<!-- END CENTERED WHITE CONTAINER -->
|
||||
|
||||
<!-- START FOOTER -->
|
||||
<div class="footer" style="clear: both; margin-top: 10px; text-align: center; width: 100%;">
|
||||
<table role="presentation" border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;" width="100%">
|
||||
<tr>
|
||||
<td class="content-block powered-by" style="font-family: sans-serif; vertical-align: top; padding-bottom: 10px; padding-top: 10px; color: #999999; font-size: 12px; text-align: center;" valign="top" align="center">
|
||||
Powered by <a href="{{poweredBy.target}}" style="color: #999999; font-size: 12px; text-align: center; text-decoration: none;">{{poweredBy.anchorText}}</a>.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<!-- END FOOTER -->
|
||||
|
||||
</div>
|
||||
</td>
|
||||
<td style="font-family: sans-serif; font-size: 14px; vertical-align: top;" valign="top"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
@ -1,5 +1,4 @@
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
using DomainResults.Common;
|
||||
|
||||
@ -27,8 +26,20 @@ namespace DataProviders.Buckets {
|
||||
/// <param name="fileId"></param>
|
||||
/// <returns></returns>
|
||||
(BucketFile?, IDomainResult) Download(Guid siteId, Guid fileId);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="siteId"></param>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="fileId"></param>
|
||||
/// <returns></returns>
|
||||
IDomainResult DeleteOne(Guid siteId, Guid fileId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class DkimBucketDataProvider : BucketDataProviderBase, IDkimBucketDataProvider {
|
||||
|
||||
/// <summary>
|
||||
@ -60,5 +71,15 @@ namespace DataProviders.Buckets {
|
||||
|
||||
return (list.First(), result);
|
||||
}
|
||||
|
||||
|
||||
public IDomainResult DeleteOne(Guid siteId, Guid fileId) =>
|
||||
DeleteOneAsync(siteId, fileId).Result;
|
||||
|
||||
public Task<IDomainResult> DeleteOneAsync(Guid siteId, Guid fileId) =>
|
||||
DeleteAsync(Builders<GridFSFileInfo>.Filter.And(
|
||||
Builders<GridFSFileInfo>.Filter.Eq(x => x.Metadata["siteId"], $"{siteId}"),
|
||||
Builders<GridFSFileInfo>.Filter.Eq(x => x.Filename, $"{fileId}")
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,13 +1,11 @@
|
||||
using DataProviders.Buckets.Abstractions;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
using DomainResults.Common;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
using MongoDB.Driver;
|
||||
using MongoDB.Driver.GridFS;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using DataProviders.Buckets.Abstractions;
|
||||
|
||||
namespace DataProviders.Buckets {
|
||||
|
||||
@ -32,6 +30,14 @@ namespace DataProviders.Buckets {
|
||||
/// <param name="fileId"></param>
|
||||
/// <returns></returns>
|
||||
(BucketFile?, IDomainResult) Download(Guid siteId, Guid fileId);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="siteId"></param>
|
||||
/// <param name="fileId"></param>
|
||||
/// <returns></returns>
|
||||
IDomainResult DeleteOne(Guid siteId, Guid fileId);
|
||||
}
|
||||
|
||||
public class TemplateBucketDataProvider : BucketDataProviderBase, ITemplateBucketDataProvider {
|
||||
@ -40,6 +46,14 @@ namespace DataProviders.Buckets {
|
||||
IMongoClient client
|
||||
) : base(logger, client, "reactredux", "templates") { }
|
||||
|
||||
// TODO: Manage TempleteTypes Enumeration and Metadata in Model and DataProvider
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="siteId"></param>
|
||||
/// <param name="fileId"></param>
|
||||
/// <returns></returns>
|
||||
public (BucketFile?, IDomainResult) Download(Guid siteId, Guid fileId) {
|
||||
var filter = Builders<GridFSFileInfo>.Filter.And(
|
||||
Builders<GridFSFileInfo>.Filter.Eq(x => x.Metadata["siteId"], $"{siteId}"),
|
||||
@ -54,5 +68,25 @@ namespace DataProviders.Buckets {
|
||||
return (list.First(), result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="siteId"></param>
|
||||
/// <param name="fileId"></param>
|
||||
/// <returns></returns>
|
||||
public IDomainResult DeleteOne(Guid siteId, Guid fileId) =>
|
||||
DeleteOneAsync(siteId, fileId).Result;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="siteId"></param>
|
||||
/// <param name="fileId"></param>
|
||||
/// <returns></returns>
|
||||
public Task<IDomainResult> DeleteOneAsync(Guid siteId, Guid fileId) =>
|
||||
DeleteAsync(Builders<GridFSFileInfo>.Filter.And(
|
||||
Builders<GridFSFileInfo>.Filter.Eq(x => x.Metadata["siteId"], $"{siteId}"),
|
||||
Builders<GridFSFileInfo>.Filter.Eq(x => x.Filename, $"{fileId}")
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,9 +4,8 @@ using DomainResults.Common;
|
||||
|
||||
using MongoDB.Bson.Serialization;
|
||||
using MongoDB.Driver;
|
||||
|
||||
using DomainObjects.Documents;
|
||||
using DataProviders.Collections.Abstractions;
|
||||
using DomainObjects.Documents.Posts;
|
||||
|
||||
namespace DataProviders.Collections
|
||||
{
|
||||
|
||||
@ -4,33 +4,33 @@ using MongoDB.Driver;
|
||||
using MongoDB.Bson.Serialization;
|
||||
|
||||
using DomainResults.Common;
|
||||
using DomainObjects.Documents;
|
||||
using DomainObjects.L10n;
|
||||
using DomainObjects.Enumerations;
|
||||
using DataProviders.Collections.Abstractions;
|
||||
using DomainObjects.Documents.Categories;
|
||||
using DomainObjects.Documents.Categories.L10n;
|
||||
|
||||
namespace DataProviders.Collections
|
||||
{
|
||||
|
||||
public interface ICategoryDataProvider {
|
||||
(Guid?, IDomainResult) Insert(CategoryDocument obj);
|
||||
(Guid?, IDomainResult) Insert(Category obj);
|
||||
(Guid?, IDomainResult) CreateDefault(Guid siteId);
|
||||
(CategoryDocument?, IDomainResult) Get(Guid siteId, Guid categoryId);
|
||||
(List<CategoryDocument>?, IDomainResult) GetMany(Guid siteId, List<Guid> categoryIds);
|
||||
(CategoryDocument?, IDomainResult) GetBySlug(Guid siteId, string slug);
|
||||
(List<CategoryDocument>?, IDomainResult) GetBySlugs(Guid siteId, List<string> slugs);
|
||||
(List<CategoryDocument>?, IDomainResult) GetAll(Guid siteId);
|
||||
(Guid?, IDomainResult) Update(CategoryDocument obj);
|
||||
(Category?, IDomainResult) Get(Guid siteId, Guid categoryId);
|
||||
(List<Category>?, IDomainResult) GetMany(Guid siteId, List<Guid> categoryIds);
|
||||
(Category?, IDomainResult) GetBySlug(Guid siteId, string slug);
|
||||
(List<Category>?, IDomainResult) GetBySlugs(Guid siteId, List<string> slugs);
|
||||
(List<Category>?, IDomainResult) GetAll(Guid siteId);
|
||||
(Guid?, IDomainResult) Update(Category obj);
|
||||
IDomainResult Delete(Guid id);
|
||||
IDomainResult DeleteAll(Guid siteId);
|
||||
}
|
||||
|
||||
public class CategoryDataProvider : CollectionDataProviderBase<CategoryDocument>, ICategoryDataProvider {
|
||||
public class CategoryDataProvider : CollectionDataProviderBase<Category>, ICategoryDataProvider {
|
||||
|
||||
private const string _databaseName = "reactredux";
|
||||
private const string _collectionName = "categories";
|
||||
public CategoryDataProvider(
|
||||
ILogger<CollectionDataProviderBase<CategoryDocument>> logger,
|
||||
ILogger<CollectionDataProviderBase<Category>> logger,
|
||||
IMongoClient client,
|
||||
IIdGenerator idGenerator,
|
||||
ISessionService sessionService) : base(logger, client, idGenerator, sessionService, _databaseName, _collectionName) {
|
||||
@ -42,7 +42,7 @@ namespace DataProviders.Collections
|
||||
if (result.IsSuccess && list != null)
|
||||
return (list.First().Id, result);
|
||||
|
||||
return Insert(new CategoryDocument {
|
||||
return Insert(new Category {
|
||||
SiteId = siteId,
|
||||
L10n = new List<CategoryL10n> {
|
||||
new CategoryL10n {
|
||||
@ -54,7 +54,7 @@ namespace DataProviders.Collections
|
||||
});
|
||||
}
|
||||
|
||||
public (CategoryDocument?, IDomainResult) Get(Guid siteId, Guid categoryId) {
|
||||
public (Category?, IDomainResult) Get(Guid siteId, Guid categoryId) {
|
||||
var (list, result) = GetWithPredicate(x => x.SiteId == siteId && x.Id == categoryId, x => x);
|
||||
|
||||
if (!result.IsSuccess || list == null)
|
||||
@ -63,10 +63,10 @@ namespace DataProviders.Collections
|
||||
return (list.First(), result);
|
||||
}
|
||||
|
||||
public (List<CategoryDocument>?, IDomainResult) GetMany(Guid siteId, List<Guid> categoryIds) =>
|
||||
public (List<Category>?, IDomainResult) GetMany(Guid siteId, List<Guid> categoryIds) =>
|
||||
GetWithPredicate(x => x.SiteId == siteId && categoryIds.Contains(x.Id), x => x);
|
||||
|
||||
public (CategoryDocument?, IDomainResult) GetBySlug(Guid siteId, string slug) {
|
||||
public (Category?, IDomainResult) GetBySlug(Guid siteId, string slug) {
|
||||
var (list, result) = GetBySlugs(siteId, new List<string> { slug });
|
||||
|
||||
if (!result.IsSuccess || list == null)
|
||||
@ -75,13 +75,13 @@ namespace DataProviders.Collections
|
||||
return (list.First(), result);
|
||||
}
|
||||
|
||||
public (List<CategoryDocument>?, IDomainResult) GetBySlugs(Guid siteId, List<string> slugs) =>
|
||||
public (List<Category>?, IDomainResult) GetBySlugs(Guid siteId, List<string> slugs) =>
|
||||
GetWithPredicate(x => x.SiteId == siteId && x.L10n.Any(y => slugs.Contains(y.Slug)), x => x);
|
||||
|
||||
public (List<CategoryDocument>?, IDomainResult) GetAll(Guid siteId) =>
|
||||
public (List<Category>?, IDomainResult) GetAll(Guid siteId) =>
|
||||
GetWithPredicate(x => x.SiteId == siteId, x => x);
|
||||
|
||||
public (Guid?, IDomainResult) Update(CategoryDocument obj) =>
|
||||
public (Guid?, IDomainResult) Update(Category obj) =>
|
||||
UpdateWithPredicate(obj, x => x.Id == obj.Id);
|
||||
|
||||
public IDomainResult Delete(Guid id) =>
|
||||
|
||||
@ -4,8 +4,8 @@ using DomainResults.Common;
|
||||
|
||||
using MongoDB.Bson.Serialization;
|
||||
using MongoDB.Driver;
|
||||
using DomainObjects.Documents;
|
||||
using DataProviders.Collections.Abstractions;
|
||||
using DomainObjects.Documents.Posts;
|
||||
|
||||
namespace DataProviders.Collections
|
||||
{
|
||||
|
||||
@ -12,6 +12,9 @@ using DomainObjects.Pages;
|
||||
using DomainObjects.Documents;
|
||||
using DomainObjects.Documents.Users;
|
||||
using DomainObjects.Documents.Sites;
|
||||
using DomainObjects.Documents.Categories;
|
||||
using DomainObjects.Documents.Categories.L10n;
|
||||
using DomainObjects.Documents.Posts;
|
||||
|
||||
namespace DataProviders
|
||||
{
|
||||
@ -70,8 +73,8 @@ namespace DataProviders
|
||||
});
|
||||
}
|
||||
|
||||
if (!BsonClassMap.IsClassMapRegistered(typeof(CategoryDocument))) {
|
||||
BsonClassMap.RegisterClassMap<CategoryDocument>(cm => {
|
||||
if (!BsonClassMap.IsClassMapRegistered(typeof(Category))) {
|
||||
BsonClassMap.RegisterClassMap<Category>(cm => {
|
||||
cm.AutoMap();
|
||||
});
|
||||
}
|
||||
|
||||
@ -5,8 +5,13 @@ namespace DomainObjects;
|
||||
|
||||
public class Contact : DomainObjectBase<Contact> {
|
||||
public ContactTypes Type { get; set; }
|
||||
|
||||
public string? Name { get; set; }
|
||||
|
||||
public string Value { get; set; }
|
||||
|
||||
public bool? Confirmed { get; set; }
|
||||
|
||||
public bool? Primary { get; set; }
|
||||
|
||||
public Contact(ContactTypes type, string value) {
|
||||
|
||||
@ -4,6 +4,7 @@ public class Address
|
||||
{
|
||||
public string Street { get; set; }
|
||||
public string City { get; set; }
|
||||
public string Region { get; set; }
|
||||
public string PostCode { get; set; }
|
||||
public string Country { get; set; }
|
||||
}
|
||||
|
||||
@ -1,34 +0,0 @@
|
||||
using DomainObjects.Abstractions;
|
||||
|
||||
namespace DomainObjects.Documents;
|
||||
|
||||
public class BlogDocument : PostItemBase<BlogDocument> {
|
||||
|
||||
public uint? ReadTime { get; set; }
|
||||
|
||||
public uint? Likes { get; set; }
|
||||
|
||||
public override int GetHashCode() {
|
||||
unchecked {
|
||||
int hash = 17;
|
||||
hash = hash * 23 + Id.GetHashCode();
|
||||
hash = hash * 23 + SiteId.GetHashCode();
|
||||
hash = hash * 23 + L10n.GetHashCode();
|
||||
if (MediaAttachments != null)
|
||||
hash = hash * 23 + MediaAttachments.Sum(x => x.GetHashCode());
|
||||
hash = hash * 23 + Author.GetHashCode();
|
||||
hash = hash * 23 + Created.GetHashCode();
|
||||
if(Tags != null)
|
||||
hash = hash * 23 + Tags.Sum(x => x.GetHashCode());
|
||||
|
||||
if(Categories != null)
|
||||
hash = hash * 23 + Categories.Sum(x => x.GetHashCode());
|
||||
|
||||
hash = hash * 23 + ReadTime.GetHashCode();
|
||||
hash = hash * 23 + Likes.GetHashCode();
|
||||
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
22
src/DomainObjects/Documents/Categories/Category.cs
Normal file
22
src/DomainObjects/Documents/Categories/Category.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using DomainObjects.Abstractions;
|
||||
using DomainObjects.Documents.Categories.L10n;
|
||||
|
||||
namespace DomainObjects.Documents.Categories
|
||||
{
|
||||
public class Category : DomainObjectDocumentBase<Category>
|
||||
{
|
||||
public Guid SiteId { get; set; }
|
||||
public List<CategoryL10n> L10n { get; set; }
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
int hash = 17;
|
||||
hash = hash * 23 + Id.GetHashCode();
|
||||
hash += L10n.Sum(x => x.GetHashCode() * 23);
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
24
src/DomainObjects/Documents/Categories/L10n/CategoryL10n.cs
Normal file
24
src/DomainObjects/Documents/Categories/L10n/CategoryL10n.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using DomainObjects.Abstractions;
|
||||
using DomainObjects.Enumerations;
|
||||
|
||||
namespace DomainObjects.Documents.Categories.L10n;
|
||||
|
||||
public class CategoryL10n : DomainObjectBase<CategoryL10n>
|
||||
{
|
||||
public Locales Locale { get; set; }
|
||||
public string Slug { get; set; }
|
||||
public string Text { get; set; }
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
int hash = 17;
|
||||
hash = hash * 23 + Locale.GetHashCode();
|
||||
hash = hash * 23 + Slug.GetHashCode();
|
||||
hash = hash * 23 + Text.GetHashCode();
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,18 +0,0 @@
|
||||
using DomainObjects.Abstractions;
|
||||
using DomainObjects.L10n;
|
||||
|
||||
namespace DomainObjects.Documents {
|
||||
public class CategoryDocument : DomainObjectDocumentBase<CategoryDocument> {
|
||||
public Guid SiteId { get; set; }
|
||||
public List<CategoryL10n> L10n { get; set; }
|
||||
|
||||
public override int GetHashCode() {
|
||||
unchecked {
|
||||
int hash = 17;
|
||||
hash = hash * 23 + Id.GetHashCode();
|
||||
hash += L10n.Sum(x => x.GetHashCode() * 23);
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,10 +1,5 @@
|
||||
using CryptoProvider;
|
||||
using DomainObjects.Abstractions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DomainObjects.Documents;
|
||||
|
||||
@ -19,10 +14,17 @@ public class MailboxConnectionSettings : DomainObjectBase<MailboxConnectionSetti
|
||||
public string UserName { get; set; }
|
||||
|
||||
public string Password { get; private set; }
|
||||
|
||||
public void SetPassword (IAesKey aesKey, string password) =>
|
||||
SetPassword(aesKey.IV, aesKey.Key, password);
|
||||
|
||||
public void SetPassword(string iv, string key, string password) {
|
||||
Password = AesService.EncryptString(iv, key, password);
|
||||
}
|
||||
|
||||
public string GetPassword(IAesKey aesKey) =>
|
||||
GetPassword(aesKey.IV, aesKey.Key);
|
||||
|
||||
public string GetPassword(string iv, string key) =>
|
||||
AesService.DecryptString(iv, key, Password);
|
||||
|
||||
|
||||
37
src/DomainObjects/Documents/Posts/BlogDocument.cs
Normal file
37
src/DomainObjects/Documents/Posts/BlogDocument.cs
Normal file
@ -0,0 +1,37 @@
|
||||
using DomainObjects.Abstractions;
|
||||
|
||||
namespace DomainObjects.Documents.Posts;
|
||||
|
||||
public class BlogDocument : PostItemBase<BlogDocument>
|
||||
{
|
||||
|
||||
public uint? ReadTime { get; set; }
|
||||
|
||||
public uint? Likes { get; set; }
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
int hash = 17;
|
||||
hash = hash * 23 + Id.GetHashCode();
|
||||
hash = hash * 23 + SiteId.GetHashCode();
|
||||
hash = hash * 23 + L10n.GetHashCode();
|
||||
if (MediaAttachments != null)
|
||||
hash = hash * 23 + MediaAttachments.Sum(x => x.GetHashCode());
|
||||
hash = hash * 23 + Author.GetHashCode();
|
||||
hash = hash * 23 + Created.GetHashCode();
|
||||
if (Tags != null)
|
||||
hash = hash * 23 + Tags.Sum(x => x.GetHashCode());
|
||||
|
||||
if (Categories != null)
|
||||
hash = hash * 23 + Categories.Sum(x => x.GetHashCode());
|
||||
|
||||
hash = hash * 23 + ReadTime.GetHashCode();
|
||||
hash = hash * 23 + Likes.GetHashCode();
|
||||
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
39
src/DomainObjects/Documents/Posts/ShopDocument.cs
Normal file
39
src/DomainObjects/Documents/Posts/ShopDocument.cs
Normal file
@ -0,0 +1,39 @@
|
||||
using DomainObjects.Abstractions;
|
||||
|
||||
namespace DomainObjects.Documents.Posts;
|
||||
|
||||
public class ShopDocument : PostItemBase<ShopDocument>
|
||||
{
|
||||
public string BrandName { get; set; }
|
||||
public string Sku { get; set; }
|
||||
public decimal? Rating { get; set; }
|
||||
public decimal Price { get; set; }
|
||||
public decimal? NewPrice { get; set; }
|
||||
public uint Quantity { get; set; }
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
int hash = 17;
|
||||
hash = hash * 23 + Id.GetHashCode();
|
||||
hash = hash * 23 + SiteId.GetHashCode();
|
||||
hash = hash * 23 + L10n.GetHashCode();
|
||||
if (MediaAttachments != null)
|
||||
hash = hash * 23 + MediaAttachments.Sum(x => x.GetHashCode());
|
||||
hash = hash * 23 + Author.GetHashCode();
|
||||
hash = hash * 23 + Created.GetHashCode();
|
||||
hash = hash * 23 + Tags.GetHashCode();
|
||||
hash = hash * 23 + Categories.Sum(x => x.GetHashCode());
|
||||
|
||||
hash = hash * 23 + BrandName.GetHashCode();
|
||||
hash = hash * 23 + Sku.GetHashCode();
|
||||
hash = hash * 23 + Rating.GetHashCode();
|
||||
hash = hash * 23 + Price.GetHashCode();
|
||||
hash = hash * 23 + NewPrice.GetHashCode();
|
||||
hash = hash * 23 + Quantity.GetHashCode();
|
||||
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,36 +0,0 @@
|
||||
using DomainObjects.Abstractions;
|
||||
|
||||
namespace DomainObjects.Documents;
|
||||
|
||||
public class ShopDocument : PostItemBase<ShopDocument> {
|
||||
public string BrandName { get; set; }
|
||||
public string Sku { get; set; }
|
||||
public decimal? Rating { get; set; }
|
||||
public decimal Price { get; set; }
|
||||
public decimal? NewPrice { get; set; }
|
||||
public uint Quantity { get; set; }
|
||||
|
||||
public override int GetHashCode() {
|
||||
unchecked {
|
||||
int hash = 17;
|
||||
hash = hash * 23 + Id.GetHashCode();
|
||||
hash = hash * 23 + SiteId.GetHashCode();
|
||||
hash = hash * 23 + L10n.GetHashCode();
|
||||
if (MediaAttachments != null)
|
||||
hash = hash * 23 + MediaAttachments.Sum(x => x.GetHashCode());
|
||||
hash = hash * 23 + Author.GetHashCode();
|
||||
hash = hash * 23 + Created.GetHashCode();
|
||||
hash = hash * 23 + Tags.GetHashCode();
|
||||
hash = hash * 23 + Categories.Sum(x => x.GetHashCode());
|
||||
|
||||
hash = hash * 23 + BrandName.GetHashCode();
|
||||
hash = hash * 23 + Sku.GetHashCode();
|
||||
hash = hash * 23 + Rating.GetHashCode();
|
||||
hash = hash * 23 + Price.GetHashCode();
|
||||
hash = hash * 23 + NewPrice.GetHashCode();
|
||||
hash = hash * 23 + Quantity.GetHashCode();
|
||||
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4,6 +4,8 @@ namespace DomainObjects.Documents.Sites;
|
||||
|
||||
public class PassworRecoverySettings : DomainObjectBase<PassworRecoverySettings> {
|
||||
|
||||
public MailboxConnectionSettings SmtpSettings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// DomainKeys Identified Mail (DKIM) is an email authentication method designed to detect forged sender addresses in email (email spoofing),<br />
|
||||
/// a technique often used in phishing and email spam.
|
||||
@ -12,14 +14,16 @@ public class PassworRecoverySettings : DomainObjectBase<PassworRecoverySettings>
|
||||
|
||||
public Guid TemplateId { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public Contact Email { get; set; }
|
||||
|
||||
|
||||
public string Subject { get; set; }
|
||||
|
||||
public List<string> Paragraphs { get; set; }
|
||||
|
||||
|
||||
|
||||
|
||||
public override int GetHashCode() {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
@ -1,20 +1,19 @@
|
||||
using DomainObjects.Abstractions;
|
||||
using DomainObjects.Enumerations;
|
||||
|
||||
namespace DomainObjects.Documents.Sites {
|
||||
|
||||
public class Site : DomainObjectDocumentBase<Site> {
|
||||
|
||||
public Locales Locale { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public List<string> Hosts { get; set; }
|
||||
|
||||
public Address Address { get; set; }
|
||||
|
||||
public string PoweredBy { get; set; }
|
||||
|
||||
public MailboxConnectionSettings SmtpSettings { get; set; }
|
||||
|
||||
public MailboxConnectionSettings ImapSettings { get; set; }
|
||||
public Link PoweredBy { get; set; }
|
||||
|
||||
public PassworRecoverySettings PassworRecoverySettings { get; set; }
|
||||
|
||||
|
||||
@ -1,21 +0,0 @@
|
||||
using DomainObjects.Abstractions;
|
||||
using DomainObjects.Enumerations;
|
||||
|
||||
namespace DomainObjects.L10n;
|
||||
|
||||
public class CategoryL10n : DomainObjectBase<CategoryL10n> {
|
||||
public Locales Locale { get; set; }
|
||||
public string Slug { get; set; }
|
||||
public string Text { get; set; }
|
||||
|
||||
public override int GetHashCode() {
|
||||
unchecked {
|
||||
int hash = 17;
|
||||
hash = hash * 23 + Locale.GetHashCode();
|
||||
hash = hash * 23 + Slug.GetHashCode();
|
||||
hash = hash * 23 + Text.GetHashCode();
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,6 +50,11 @@ namespace WeatherForecast {
|
||||
/// </summary>
|
||||
public AesKey? JwtTokenEncryption { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public AesKey? MailPasswordEncryption { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
|
||||
@ -10,7 +10,7 @@ using Core.Enumerations;
|
||||
using DataProviders.Collections;
|
||||
using Extensions;
|
||||
using DomainResults.Common;
|
||||
using DomainObjects.Documents;
|
||||
using DomainObjects.Documents.Posts;
|
||||
|
||||
namespace WeatherForecast.Controllers;
|
||||
|
||||
|
||||
@ -34,7 +34,7 @@ public class DkimController : ControllerBase {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allows to upload private dkim certificate
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="siteId"></param>
|
||||
/// <param name="file"></param>
|
||||
@ -52,4 +52,17 @@ public class DkimController : ControllerBase {
|
||||
|
||||
return result.ToActionResult();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Delete private dkim cert
|
||||
/// </summary>
|
||||
/// <param name="siteId"></param>
|
||||
/// <param name="fileId"></param>
|
||||
/// <returns></returns>
|
||||
[HttpDelete("{siteId}/{fileId}")]
|
||||
public IActionResult Delete([FromRoute] Guid siteId, [FromRoute] Guid fileId) {
|
||||
|
||||
var result = _dkimService.Delete(siteId, fileId);
|
||||
return result.ToActionResult();
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,9 +8,9 @@ using WeatherForecast.Models.Requests;
|
||||
using WeatherForecast.Policies;
|
||||
using Core.Enumerations;
|
||||
using DataProviders.Collections;
|
||||
using DomainObjects.Documents;
|
||||
using DomainResults.Common;
|
||||
using Extensions;
|
||||
using DomainObjects.Documents.Posts;
|
||||
|
||||
namespace WeatherForecast.Controllers;
|
||||
|
||||
|
||||
@ -53,4 +53,18 @@ public class TemplateController : ControllerBase {
|
||||
|
||||
return result.ToActionResult();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Delete template
|
||||
/// </summary>
|
||||
/// <param name="siteId"></param>
|
||||
/// <param name="fileId"></param>
|
||||
/// <returns></returns>
|
||||
[HttpDelete("{siteId}/{fileId}")]
|
||||
public IActionResult Delete([FromRoute] Guid siteId, [FromRoute] Guid fileId) {
|
||||
|
||||
var result = _templateService.Delete(siteId, fileId);
|
||||
return result.ToActionResult();
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ using DomainResults.Mvc;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using WeatherForecast.Models.Initialization.Requests;
|
||||
using WeatherForecast.Models.Utils.Requests;
|
||||
using WeatherForecast.Services;
|
||||
|
||||
namespace WeatherForecast.Controllers;
|
||||
@ -27,5 +28,19 @@ public class UtilsController : ControllerBase {
|
||||
return Ok(AesService.GenerateKey());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="requestData"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("[action]")]
|
||||
public IActionResult EncryptStringAes([FromBody] EncryptStringAesRequestModel requestData) {
|
||||
var result = AesService.EncryptString(requestData.IV, requestData.Key, requestData.InputString);
|
||||
if(result != null)
|
||||
return Ok(result);
|
||||
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1,19 +1,19 @@
|
||||
using DomainObjects.Abstractions;
|
||||
using DomainObjects.Documents;
|
||||
using DomainObjects.Enumerations;
|
||||
|
||||
using Core.Abstractions.Models;
|
||||
|
||||
using WeatherForecast.Models.Category.Responses;
|
||||
using DomainObjects.Documents.Categories;
|
||||
|
||||
namespace WeatherForecast.Models.Abstractions.PostItem.Responses
|
||||
{
|
||||
|
||||
namespace WeatherForecast.Models.Abstractions.PostItem.Responses {
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public abstract class PostItemResponseModelBase<T> : ResponseModelBase {
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public abstract class PostItemResponseModelBase<T> : ResponseModelBase {
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
@ -122,7 +122,7 @@ namespace WeatherForecast.Models.Abstractions.PostItem.Responses {
|
||||
/// </summary>
|
||||
/// <param name="postItem"></param>
|
||||
/// <param name="categories"></param>
|
||||
public PostItemResponseModelBase(PostItemBase<T> postItem, List<CategoryDocument> categories) : this(postItem) {
|
||||
public PostItemResponseModelBase(PostItemBase<T> postItem, List<DomainObjects.Documents.Categories.Category> categories) : this(postItem) {
|
||||
L10n = postItem.L10n.Select(x => new PostItemL10nModel(x)).ToList();
|
||||
Categories = categories.Select(x => new CategoryItemResponseModel(x)).ToList();
|
||||
MediaAttachemnts = postItem.MediaAttachments?.Select(x => new MediaAttachmentResponseModel(x)).ToList();
|
||||
@ -134,7 +134,7 @@ namespace WeatherForecast.Models.Abstractions.PostItem.Responses {
|
||||
/// <param name="postItem"></param>
|
||||
/// <param name="categories"></param>
|
||||
/// <param name="locale"></param>
|
||||
public PostItemResponseModelBase(PostItemBase<T> postItem, List<CategoryDocument> categories, Locales locale) : this(postItem) {
|
||||
public PostItemResponseModelBase(PostItemBase<T> postItem, List<DomainObjects.Documents.Categories.Category> categories, Locales locale) : this(postItem) {
|
||||
|
||||
var postItemL10n = postItem.L10n.Single(x => x.Locale == locale);
|
||||
|
||||
|
||||
@ -1,15 +1,16 @@
|
||||
using DomainObjects.Documents;
|
||||
using Core.Enumerations;
|
||||
using Core.Enumerations;
|
||||
using Extensions;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using WeatherForecast.Models.Abstractions.PostItem.Requests;
|
||||
using DomainObjects.Documents.Posts;
|
||||
|
||||
namespace WeatherForecast.Models.Blog.Requests {
|
||||
namespace WeatherForecast.Models.Blog.Requests
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class BlogItemRequestModel : PostItemRequestModelBase<BlogDocument> {
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class BlogItemRequestModel : PostItemRequestModelBase<BlogDocument> {
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
|
||||
@ -1,14 +1,15 @@
|
||||
using DomainObjects.Documents;
|
||||
|
||||
using WeatherForecast.Models.Abstractions.PostItem.Responses;
|
||||
using WeatherForecast.Models.Abstractions.PostItem.Responses;
|
||||
using DomainObjects.Enumerations;
|
||||
using DomainObjects.Documents.Categories;
|
||||
using DomainObjects.Documents.Posts;
|
||||
|
||||
namespace WeatherForecast.Models.Blog.Responses {
|
||||
namespace WeatherForecast.Models.Blog.Responses
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class BlogItemResponseModel : PostItemResponseModelBase<BlogDocument> {
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class BlogItemResponseModel : PostItemResponseModelBase<BlogDocument> {
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
@ -25,7 +26,7 @@ namespace WeatherForecast.Models.Blog.Responses {
|
||||
/// </summary>
|
||||
/// <param name="blogItem"></param>
|
||||
/// <param name="categories"></param>
|
||||
public BlogItemResponseModel(BlogDocument blogItem, List<CategoryDocument> categories) : base(blogItem, categories) {
|
||||
public BlogItemResponseModel(BlogDocument blogItem, List<DomainObjects.Documents.Categories.Category> categories) : base(blogItem, categories) {
|
||||
ReadTime = blogItem.ReadTime;
|
||||
Likes = blogItem.Likes;
|
||||
}
|
||||
@ -36,7 +37,7 @@ namespace WeatherForecast.Models.Blog.Responses {
|
||||
/// <param name="blogItem"></param>
|
||||
/// <param name="categories"></param>
|
||||
/// <param name="locale"></param>
|
||||
public BlogItemResponseModel(BlogDocument blogItem, List<CategoryDocument> categories, Locales locale) : base(blogItem, categories, locale) {
|
||||
public BlogItemResponseModel(BlogDocument blogItem, List<DomainObjects.Documents.Categories.Category> categories, Locales locale) : base(blogItem, categories, locale) {
|
||||
ReadTime = blogItem.ReadTime;
|
||||
Likes = blogItem.Likes;
|
||||
}
|
||||
|
||||
@ -1,15 +1,16 @@
|
||||
using Core.Abstractions.Models;
|
||||
using DomainObjects.Documents;
|
||||
using Core.Enumerations;
|
||||
using Extensions;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using DomainObjects.Documents.Categories;
|
||||
|
||||
namespace WeatherForecast.Models.Category.Requests {
|
||||
namespace WeatherForecast.Models.Category.Requests
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class CategoryItemRequestModel : RequestModelBase<CategoryDocument> {
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class CategoryItemRequestModel : RequestModelBase<DomainObjects.Documents.Categories.Category> {
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
@ -20,7 +21,7 @@ namespace WeatherForecast.Models.Category.Requests {
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public CategoryDocument ToDomainObject(Guid siteId) => new CategoryDocument() {
|
||||
public DomainObjects.Documents.Categories.Category ToDomainObject(Guid siteId) => new DomainObjects.Documents.Categories.Category() {
|
||||
SiteId = siteId,
|
||||
|
||||
L10n = L10n.Select(x => x.ToDomainObject()).ToList()
|
||||
|
||||
@ -2,16 +2,17 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Core.Abstractions;
|
||||
using Core.Abstractions.Models;
|
||||
using DomainObjects.L10n;
|
||||
using Core.Enumerations;
|
||||
using DomainObjects.Enumerations;
|
||||
using DomainObjects.Documents.Categories.L10n;
|
||||
|
||||
namespace WeatherForecast.Models.Category.Requests {
|
||||
namespace WeatherForecast.Models.Category.Requests
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class CategoryL10nModel : RequestModelBase<CategoryL10n> {
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class CategoryL10nModel : RequestModelBase<CategoryL10n> {
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
using DomainObjects.Documents;
|
||||
|
||||
using Core.Abstractions.Models;
|
||||
using Core.Abstractions.Models;
|
||||
using DomainObjects.Enumerations;
|
||||
using DomainObjects.Documents.Categories;
|
||||
|
||||
namespace WeatherForecast.Models.Category.Responses {
|
||||
namespace WeatherForecast.Models.Category.Responses
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class CategoryItemResponseModel : ResponseModelBase {
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class CategoryItemResponseModel : ResponseModelBase {
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
@ -39,7 +39,7 @@ namespace WeatherForecast.Models.Category.Responses {
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="category"></param>
|
||||
public CategoryItemResponseModel(CategoryDocument category) {
|
||||
public CategoryItemResponseModel(DomainObjects.Documents.Categories.Category category) {
|
||||
Id = category.Id;
|
||||
SiteId = category.SiteId;
|
||||
|
||||
@ -51,7 +51,7 @@ namespace WeatherForecast.Models.Category.Responses {
|
||||
/// </summary>
|
||||
/// <param name="category"></param>
|
||||
/// <param name="locale"></param>
|
||||
public CategoryItemResponseModel(CategoryDocument category, Locales locale) {
|
||||
public CategoryItemResponseModel(DomainObjects.Documents.Categories.Category category, Locales locale) {
|
||||
Id = category.Id;
|
||||
SiteId = category.SiteId;
|
||||
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
using Core.Abstractions.Models;
|
||||
using DomainObjects.L10n;
|
||||
using DomainObjects.Documents.Categories.L10n;
|
||||
|
||||
namespace WeatherForecast.Models.Category.Responses {
|
||||
namespace WeatherForecast.Models.Category.Responses
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class CategoryL10nModel : ResponseModelBase {
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class CategoryL10nModel : ResponseModelBase {
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
|
||||
@ -41,15 +41,8 @@ namespace WeatherForecast.Models.Initialization.Requests {
|
||||
/// </summary>
|
||||
public string RePassword { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string DkimBase64 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string ServiceEmlTemplateBase64 { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
@ -88,11 +81,11 @@ namespace WeatherForecast.Models.Initialization.Requests {
|
||||
if (string.Compare(Password, RePassword) != 0)
|
||||
yield return new ValidationResult($"{nameof(Password)} and {nameof(RePassword)} ${Errors.NotMatched}");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(DkimBase64))
|
||||
yield return new ValidationResult($"{nameof(DkimBase64)} {Errors.NullOrWhiteSpace}");
|
||||
//if (string.IsNullOrWhiteSpace(DkimBase64))
|
||||
// yield return new ValidationResult($"{nameof(DkimBase64)} {Errors.NullOrWhiteSpace}");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(ServiceEmlTemplateBase64))
|
||||
yield return new ValidationResult($"{nameof(ServiceEmlTemplateBase64)} {Errors.NullOrWhiteSpace}");
|
||||
//if (string.IsNullOrWhiteSpace(ServiceEmlTemplateBase64))
|
||||
// yield return new ValidationResult($"{nameof(ServiceEmlTemplateBase64)} {Errors.NullOrWhiteSpace}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,16 +1,16 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
using DomainObjects.Documents;
|
||||
using Core.Enumerations;
|
||||
using Extensions;
|
||||
using WeatherForecast.Models.Abstractions.PostItem.Requests;
|
||||
using DomainObjects.Documents.Posts;
|
||||
|
||||
namespace WeatherForecast.Models.Requests {
|
||||
namespace WeatherForecast.Models.Requests
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ShopItemRequestModel : PostItemRequestModelBase<ShopDocument> {
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ShopItemRequestModel : PostItemRequestModelBase<ShopDocument> {
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
|
||||
@ -1,14 +1,16 @@
|
||||
using Core.Abstractions.Models;
|
||||
using DomainObjects.Documents;
|
||||
using DomainObjects.Documents.Posts;
|
||||
using DomainObjects.Enumerations;
|
||||
using WeatherForecast.Models.Abstractions.PostItem.Responses;
|
||||
|
||||
namespace WeatherForecast.Models.Responses {
|
||||
namespace WeatherForecast.Models.Responses
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ShopCartItemResponseModel : ResponseModelBase {
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ShopCartItemResponseModel : ResponseModelBase {
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
|
||||
@ -1,13 +1,15 @@
|
||||
using DomainObjects.Documents;
|
||||
using DomainObjects.Documents.Categories;
|
||||
using DomainObjects.Documents.Posts;
|
||||
using DomainObjects.Enumerations;
|
||||
using WeatherForecast.Models.Abstractions.PostItem.Responses;
|
||||
|
||||
namespace WeatherForecast.Models.Shop.Responses {
|
||||
namespace WeatherForecast.Models.Shop.Responses
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ShopItemResponseModel : PostItemResponseModelBase<ShopDocument> {
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ShopItemResponseModel : PostItemResponseModelBase<ShopDocument> {
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
@ -39,7 +41,7 @@ namespace WeatherForecast.Models.Shop.Responses {
|
||||
/// </summary>
|
||||
/// <param name="shopCatalogItem"></param>
|
||||
/// <param name="categories"></param>
|
||||
public ShopItemResponseModel(ShopDocument shopCatalogItem, List<CategoryDocument> categories) : base(shopCatalogItem, categories) {
|
||||
public ShopItemResponseModel(ShopDocument shopCatalogItem, List<DomainObjects.Documents.Categories.Category> categories) : base(shopCatalogItem, categories) {
|
||||
Sku = shopCatalogItem.Sku;
|
||||
Rating = shopCatalogItem.Rating;
|
||||
Price = shopCatalogItem.Price;
|
||||
@ -53,7 +55,7 @@ namespace WeatherForecast.Models.Shop.Responses {
|
||||
/// <param name="shopCatalogItem"></param>
|
||||
/// <param name="categories"></param>
|
||||
/// <param name="locale"></param>
|
||||
public ShopItemResponseModel(ShopDocument shopCatalogItem, List<CategoryDocument> categories, Locales locale) : base(shopCatalogItem, categories, locale) {
|
||||
public ShopItemResponseModel(ShopDocument shopCatalogItem, List<DomainObjects.Documents.Categories.Category> categories, Locales locale) : base(shopCatalogItem, categories, locale) {
|
||||
Sku = shopCatalogItem.Sku;
|
||||
Rating = shopCatalogItem.Rating;
|
||||
Price = shopCatalogItem.Price;
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
using Core.Abstractions.Models;
|
||||
using Core.Enumerations;
|
||||
using Extensions;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace WeatherForecast.Models.Utils.Requests {
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class EncryptStringAesRequestModel : RequestModelBase {
|
||||
|
||||
/// <summary>
|
||||
/// String to encrypt
|
||||
/// </summary>
|
||||
public string InputString { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string IV { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Key { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="validationContext"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public override IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
|
||||
if (string.IsNullOrEmpty(InputString))
|
||||
yield return new ValidationResult($"{nameof(InputString)} {Errors.NullOrEmpty}");
|
||||
|
||||
if (string.IsNullOrEmpty(IV))
|
||||
yield return new ValidationResult($"{nameof(IV)} {Errors.NullOrEmpty}");
|
||||
|
||||
if (string.IsNullOrEmpty(Key))
|
||||
yield return new ValidationResult($"{nameof(Key)} {Errors.NullOrEmpty}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,4 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
|
||||
using DomainObjects.Documents;
|
||||
using Core.Enumerations;
|
||||
|
||||
using DataProviders.Collections;
|
||||
@ -8,6 +6,7 @@ using DataProviders.Collections;
|
||||
using WeatherForecast.Policies.Abstractions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using DomainObjects.Documents.Users;
|
||||
using DomainObjects.Documents.Posts;
|
||||
|
||||
namespace WeatherForecast.Policies;
|
||||
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
using Core.Enumerations;
|
||||
using DataProviders.Collections;
|
||||
using DomainObjects.Documents;
|
||||
using DomainObjects.Documents.Posts;
|
||||
using DomainObjects.Documents.Users;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.Extensions.Options;
|
||||
using WeatherForecast.Policies.Abstractions;
|
||||
|
||||
namespace WeatherForecast.Policies {
|
||||
namespace WeatherForecast.Policies
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
|
||||
@ -55,7 +55,9 @@ namespace WeatherForecast.Services {
|
||||
/// </summary>
|
||||
public class AccountService : ServiceBase<AccountService>, IAccountService {
|
||||
|
||||
private readonly IAesKey _aesKey;
|
||||
private readonly IAesKey _jwtTokenEncryption;
|
||||
private readonly IAesKey _mailPasswordEncryption;
|
||||
|
||||
private readonly IJwtConfig _jwtConfig;
|
||||
|
||||
private readonly IUserDataProvider _userDataProvider;
|
||||
@ -84,9 +86,16 @@ namespace WeatherForecast.Services {
|
||||
if (options.Value.JwtTokenEncryption == null)
|
||||
throw new ArgumentNullException();
|
||||
|
||||
_aesKey = options.Value.JwtTokenEncryption;
|
||||
_jwtTokenEncryption = options.Value.JwtTokenEncryption;
|
||||
|
||||
if(options.Value.JwtConfig == null)
|
||||
|
||||
if (options.Value.MailPasswordEncryption == null)
|
||||
throw new ArgumentNullException();
|
||||
|
||||
_mailPasswordEncryption = options.Value.MailPasswordEncryption;
|
||||
|
||||
|
||||
if (options.Value.JwtConfig == null)
|
||||
throw new ArgumentNullException();
|
||||
|
||||
_jwtConfig = options.Value.JwtConfig;
|
||||
@ -104,12 +113,6 @@ namespace WeatherForecast.Services {
|
||||
/// <returns></returns>
|
||||
public (string?, IDomainResult) Authenticate(AuthenticationRequestModel requestData) {
|
||||
|
||||
if (_aesKey?.IV == null || _aesKey?.Key == null)
|
||||
return IDomainResult.Failed<string?>("IV or Key are not set");
|
||||
|
||||
if (_jwtConfig?.Secret == null || _jwtConfig?.Expires == null)
|
||||
return IDomainResult.Failed<string?>("Secret or Expires are not set");
|
||||
|
||||
// Retrieve user from database by userName
|
||||
var (user, getUserResult) = _userDataProvider.GetByUsername(requestData.Username);
|
||||
if (!getUserResult.IsSuccess || user == null)
|
||||
@ -119,7 +122,7 @@ namespace WeatherForecast.Services {
|
||||
if (!user.Authentication.ValidatePassword(requestData.Password))
|
||||
return IDomainResult.Unauthorized<string?>();
|
||||
|
||||
var token = user.AddToken(_aesKey.IV, _aesKey.Key, _jwtConfig.Secret, _jwtConfig.Expires);
|
||||
var token = user.AddToken(_jwtTokenEncryption.IV, _jwtTokenEncryption.Key, _jwtConfig.Secret, _jwtConfig.Expires);
|
||||
|
||||
var (_, usdateUserResult) = _userDataProvider.Update(user);
|
||||
if (!usdateUserResult.IsSuccess)
|
||||
@ -166,7 +169,7 @@ namespace WeatherForecast.Services {
|
||||
_userDataProvider.Update(user);
|
||||
|
||||
var emailBuilder = new EmailMessageBuilder();
|
||||
emailBuilder.AddFrom(site.PassworRecoverySettings.Name, site.PassworRecoverySettings.Email.Value);
|
||||
emailBuilder.AddFrom(site.PassworRecoverySettings.Email.Name ?? site.PassworRecoverySettings.Email.Value, site.PassworRecoverySettings.Email.Value);
|
||||
emailBuilder.AddTo(user.Username, email.Value);
|
||||
emailBuilder.AddSubject(site.PassworRecoverySettings.Subject);
|
||||
emailBuilder.AddHtmlBody(htmlBody);
|
||||
@ -174,9 +177,9 @@ namespace WeatherForecast.Services {
|
||||
|
||||
using var smtpService = new SMTPService();
|
||||
|
||||
// TODO: change email password and manage configs inside database
|
||||
smtpService.Connect(site.SmtpSettings.Server, site.SmtpSettings.Port, site.SmtpSettings.UseSsl);
|
||||
//smtpService.Authenticate(site.PassworRecoverySettings.SmtpSettings.UserName, site.PassworRecoverySettings.SmtpSettings.GetPassword());
|
||||
var smtpSettings = site.PassworRecoverySettings.SmtpSettings;
|
||||
smtpService.Connect(smtpSettings.Server, smtpSettings.Port, smtpSettings.UseSsl);
|
||||
smtpService.Authenticate(smtpSettings.UserName, smtpSettings.GetPassword(_mailPasswordEncryption));
|
||||
|
||||
smtpService.Send(emailBuilder.Build());
|
||||
|
||||
|
||||
@ -2,18 +2,18 @@
|
||||
|
||||
using DataProviders.Collections;
|
||||
|
||||
using DomainObjects.Documents;
|
||||
|
||||
using WeatherForecast.Services.Abstractions;
|
||||
using WeatherForecast.Models.Blog.Responses;
|
||||
using WeatherForecast.Models.Blog.Requests;
|
||||
using DomainObjects.Documents.Posts;
|
||||
|
||||
namespace WeatherForecast.Services {
|
||||
namespace WeatherForecast.Services
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public interface IBlogItemService {
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public interface IBlogItemService {
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
|
||||
@ -16,6 +16,14 @@ namespace WeatherForecast.Services {
|
||||
/// <param name="file"></param>
|
||||
/// <returns></returns>
|
||||
(Guid?, IDomainResult) Post(BucketFile file);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="siteId"></param>
|
||||
/// <param name="fileId"></param>
|
||||
/// <returns></returns>
|
||||
IDomainResult Delete(Guid siteId, Guid fileId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -38,7 +46,7 @@ namespace WeatherForecast.Services {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// Upload dkim private cert for website
|
||||
/// </summary>
|
||||
/// <param name="file"></param>
|
||||
/// <returns></returns>
|
||||
@ -50,5 +58,20 @@ namespace WeatherForecast.Services {
|
||||
|
||||
return IDomainResult.Success(fileId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="siteId"></param>
|
||||
/// <param name="fileId"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public IDomainResult Delete(Guid siteId, Guid fileId) {
|
||||
var result = _dkimBucketDataProvider.DeleteOne(siteId, fileId);
|
||||
if (!result.IsSuccess)
|
||||
return IDomainResult.Failed();
|
||||
|
||||
return IDomainResult.Success();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,6 +42,7 @@ namespace WeatherForecast.Services {
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="imageBucketDataProvider"></param>
|
||||
/// <param name="imageProvider"></param>
|
||||
/// <param name="contentDataProvider"></param>
|
||||
public ImageService(
|
||||
ILogger<ImageService> logger,
|
||||
IImageBucketDataProvider imageBucketDataProvider,
|
||||
|
||||
@ -57,7 +57,15 @@ public class InitializationService : ServiceBase<InitializationService>, IInitia
|
||||
IDkimBucketDataProvider dkimBucketDataProvider,
|
||||
ITemplateBucketDataProvider serviceEmlTemplateBucketDataProvider
|
||||
) : base(logger) {
|
||||
|
||||
if (options.Value.JwtTokenEncryption == null)
|
||||
throw new ArgumentNullException(nameof(options.Value.JwtTokenEncryption));
|
||||
|
||||
_aesKey = options.Value.JwtTokenEncryption;
|
||||
|
||||
if (options.Value.JwtConfig == null)
|
||||
throw new ArgumentNullException(nameof(options.Value.JwtConfig));
|
||||
|
||||
_jwtConfig = options.Value.JwtConfig;
|
||||
_siteDataProvider = siteDataProvider;
|
||||
_userDataProvider = userDataProvider;
|
||||
@ -76,46 +84,46 @@ public class InitializationService : ServiceBase<InitializationService>, IInitia
|
||||
var userId = "fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60".ToGuid();
|
||||
var siteId = "404c8232-9048-4519-bfba-6e78dc7005ca".ToGuid();
|
||||
|
||||
#region Upload dkim for service email
|
||||
var (_, dkimUpdloadResult) = _dkimBucketDataProvider.Upload(new BucketFile(
|
||||
siteId,
|
||||
requestData.Host,
|
||||
Convert.FromBase64String(requestData.DkimBase64),
|
||||
"application/x-pem-file"
|
||||
));
|
||||
//#region Upload dkim for service email
|
||||
//var (_, dkimUpdloadResult) = _dkimBucketDataProvider.Upload(new BucketFile(
|
||||
// siteId,
|
||||
// requestData.Host,
|
||||
// Convert.FromBase64String(requestData.DkimBase64),
|
||||
// "application/x-pem-file"
|
||||
//));
|
||||
|
||||
if (!dkimUpdloadResult.IsSuccess)
|
||||
return IDomainResult.Failed();
|
||||
#endregion
|
||||
//if (!dkimUpdloadResult.IsSuccess)
|
||||
// return IDomainResult.Failed();
|
||||
//#endregion
|
||||
|
||||
#region Upload basic service email templates
|
||||
var (templateId, _) = _serviceEmlTemplateBucketDataProvider.Upload(new BucketFile(
|
||||
siteId,
|
||||
"template.html",
|
||||
Convert.FromBase64String(requestData.ServiceEmlTemplateBase64),
|
||||
"text/html"
|
||||
));
|
||||
//#region Upload basic service email templates
|
||||
//var (templateId, _) = _serviceEmlTemplateBucketDataProvider.Upload(new BucketFile(
|
||||
// siteId,
|
||||
// "template.html",
|
||||
// Convert.FromBase64String(requestData.ServiceEmlTemplateBase64),
|
||||
// "text/html"
|
||||
//));
|
||||
|
||||
if (!dkimUpdloadResult.IsSuccess || templateId == null)
|
||||
return IDomainResult.Failed();
|
||||
#endregion
|
||||
//if (!dkimUpdloadResult.IsSuccess || templateId == null)
|
||||
// return IDomainResult.Failed();
|
||||
//#endregion
|
||||
|
||||
var (_, siteInsetResult) = _siteDataProvider.Insert(new Site(requestData.SiteName, new List<string> { requestData.Host }) {
|
||||
Id = siteId,
|
||||
PassworRecoverySettings = new PassworRecoverySettings {
|
||||
Name = "Password recovery support",
|
||||
Email = new Contact(ContactTypes.Email, $"support@{requestData.Host}"),
|
||||
TemplateId = templateId.Value
|
||||
}
|
||||
});
|
||||
//var (_, siteInsetResult) = _siteDataProvider.Insert(new Site(requestData.SiteName, new List<string> { requestData.Host }) {
|
||||
// Id = siteId,
|
||||
// PassworRecoverySettings = new PassworRecoverySettings {
|
||||
// Name = "Password recovery support",
|
||||
// Email = new Contact(ContactTypes.Email, $"support@{requestData.Host}"),
|
||||
// TemplateId = templateId.Value
|
||||
// }
|
||||
//});
|
||||
|
||||
var user = new User(new List<SiteRole> { new SiteRole(siteId, Roles.Admin) }, requestData.Username, requestData.Email, requestData.Password) {
|
||||
Id = userId
|
||||
};
|
||||
//var user = new User(new List<SiteRole> { new SiteRole(siteId, Roles.Admin) }, requestData.Username, requestData.Email, requestData.Password) {
|
||||
// Id = userId
|
||||
//};
|
||||
|
||||
user.Contacts.ForEach(x => x.Confirmed = true);
|
||||
//user.Contacts.ForEach(x => x.Confirmed = true);
|
||||
|
||||
var (_, userInsertResult) = _userDataProvider.Insert(user);
|
||||
//var (_, userInsertResult) = _userDataProvider.Insert(user);
|
||||
|
||||
return IDomainResult.Success();
|
||||
}
|
||||
|
||||
@ -4,16 +4,17 @@ using DataProviders.Collections;
|
||||
|
||||
using WeatherForecast.Models.Requests;
|
||||
using WeatherForecast.Services.Abstractions;
|
||||
using DomainObjects.Documents;
|
||||
using WeatherForecast.Models.Shop.Responses;
|
||||
using DomainObjects.Enumerations;
|
||||
using DomainObjects.Documents.Posts;
|
||||
|
||||
namespace WeatherForecast.Services {
|
||||
namespace WeatherForecast.Services
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public interface IShopItemService {
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public interface IShopItemService {
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
|
||||
@ -2,53 +2,74 @@
|
||||
using DataProviders.Buckets;
|
||||
using DomainResults.Common;
|
||||
|
||||
namespace WeatherForecast.Services {
|
||||
namespace WeatherForecast.Services;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public interface ITemplateService {
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public interface ITemplateService {
|
||||
/// <param name="file"></param>
|
||||
/// <returns></returns>
|
||||
(Guid?, IDomainResult) Post(BucketFile file);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="file"></param>
|
||||
/// <returns></returns>
|
||||
(Guid?, IDomainResult) Post(BucketFile file);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="siteId"></param>
|
||||
/// <param name="fileId"></param>
|
||||
/// <returns></returns>
|
||||
IDomainResult Delete(Guid siteId, Guid fileId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class TemplateService : ServiceBase<TemplateService>, ITemplateService {
|
||||
|
||||
|
||||
private readonly ITemplateBucketDataProvider _templateBucketDataProvider;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="templateBucketDataProvider"></param>
|
||||
public TemplateService(
|
||||
ILogger<TemplateService> logger,
|
||||
ITemplateBucketDataProvider templateBucketDataProvider
|
||||
) : base(logger) {
|
||||
_templateBucketDataProvider = templateBucketDataProvider;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class TemplateService : ServiceBase<TemplateService>, ITemplateService {
|
||||
/// <param name="file"></param>
|
||||
/// <returns></returns>
|
||||
public (Guid?, IDomainResult) Post(BucketFile file) {
|
||||
|
||||
var (fileId, uploadFileResult) = _templateBucketDataProvider.Upload(file);
|
||||
if (!uploadFileResult.IsSuccess || fileId == null)
|
||||
return IDomainResult.Failed<Guid?>();
|
||||
|
||||
private readonly ITemplateBucketDataProvider _templateBucketDataProvider;
|
||||
return IDomainResult.Success(fileId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="templateBucketDataProvider"></param>
|
||||
public TemplateService(
|
||||
ILogger<TemplateService> logger,
|
||||
ITemplateBucketDataProvider templateBucketDataProvider
|
||||
) : base(logger) {
|
||||
_templateBucketDataProvider = templateBucketDataProvider;
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="siteId"></param>
|
||||
/// <param name="fileId"></param>
|
||||
/// <returns></returns>
|
||||
public IDomainResult Delete(Guid siteId, Guid fileId) {
|
||||
var result = _templateBucketDataProvider.DeleteOne(siteId, fileId);
|
||||
if (!result.IsSuccess)
|
||||
return IDomainResult.Failed();
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="file"></param>
|
||||
/// <returns></returns>
|
||||
public (Guid?, IDomainResult) Post(BucketFile file) {
|
||||
|
||||
var (fileId, uploadFileResult) = _templateBucketDataProvider.Upload(file);
|
||||
if (!uploadFileResult.IsSuccess || fileId == null)
|
||||
return IDomainResult.Failed<Guid?>();
|
||||
|
||||
return IDomainResult.Success(fileId);
|
||||
}
|
||||
return IDomainResult.Success();
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,6 +25,11 @@
|
||||
"Key": "KBsLNL2/pju3uX6Wtjkf2zUS1TbJ0YiD84zusIyPVUM="
|
||||
},
|
||||
|
||||
"MailPasswordEncryption": {
|
||||
"IV": "1DCr+7GMT1skaTTTNSO3lA==",
|
||||
"Key": "36m7ZAWCZdQC05xOyUvqBmz3sgzGShSCDTBmwvNEWNM="
|
||||
},
|
||||
|
||||
|
||||
"Database": {
|
||||
"ConnectionString": "mongodb://root:example@mongo:27017"
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<DockerTargetOS>Linux</DockerTargetOS>
|
||||
<ProjectGuid>7fc6f0ba-2dcb-4b53-a3b3-61ceef42b9d0</ProjectGuid>
|
||||
<DockerLaunchAction>LaunchBrowser</DockerLaunchAction>
|
||||
<DockerServiceUrl>{Scheme}://localhost:{ServicePort}</DockerServiceUrl>
|
||||
<DockerServiceUrl>{Scheme}://localhost:{ServicePort}/swagger</DockerServiceUrl>
|
||||
<DockerServiceName>reverseproxy</DockerServiceName>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@ -3,4 +3,4 @@ WiredTiger 10.0.2: (December 21, 2021)
|
||||
WiredTiger version
|
||||
major=10,minor=0,patch=2
|
||||
file:WiredTiger.wt
|
||||
access_pattern_hint=none,allocation_size=4KB,app_metadata=,assert=(commit_timestamp=none,durable_timestamp=none,read_timestamp=none,write_timestamp=off),block_allocation=best,block_compressor=,cache_resident=false,checksum=on,collator=,columns=,dictionary=0,encryption=(keyid=,name=),format=btree,huffman_key=,huffman_value=,id=0,ignore_in_memory_cache_size=false,internal_item_max=0,internal_key_max=0,internal_key_truncate=true,internal_page_max=4KB,key_format=S,key_gap=10,leaf_item_max=0,leaf_key_max=0,leaf_page_max=32KB,leaf_value_max=0,log=(enabled=true),memory_page_image_max=0,memory_page_max=5MB,os_cache_dirty_max=0,os_cache_max=0,prefix_compression=false,prefix_compression_min=4,readonly=false,split_deepen_min_child=0,split_deepen_per_child=0,split_pct=90,tiered_object=false,tiered_storage=(auth_token=,bucket=,bucket_prefix=,cache_directory=,local_retention=300,name=,object_target_size=0),value_format=S,verbose=[],version=(major=1,minor=1),write_timestamp_usage=none,checkpoint=(WiredTigerCheckpoint.98221=(addr="018081e4af72785d8181e4aac961f88281e479ff3f5b808080e301bfc0e2dfc0",order=98221,time=1674344889,size=69632,newest_start_durable_ts=0,oldest_start_ts=0,newest_txn=202,newest_stop_durable_ts=0,newest_stop_ts=-1,newest_stop_txn=-11,prepare=0,write_gen=295056,run_write_gen=294763)),checkpoint_backup_info=,checkpoint_lsn=(38,77312)
|
||||
access_pattern_hint=none,allocation_size=4KB,app_metadata=,assert=(commit_timestamp=none,durable_timestamp=none,read_timestamp=none,write_timestamp=off),block_allocation=best,block_compressor=,cache_resident=false,checksum=on,collator=,columns=,dictionary=0,encryption=(keyid=,name=),format=btree,huffman_key=,huffman_value=,id=0,ignore_in_memory_cache_size=false,internal_item_max=0,internal_key_max=0,internal_key_truncate=true,internal_page_max=4KB,key_format=S,key_gap=10,leaf_item_max=0,leaf_key_max=0,leaf_page_max=32KB,leaf_value_max=0,log=(enabled=true),memory_page_image_max=0,memory_page_max=5MB,os_cache_dirty_max=0,os_cache_max=0,prefix_compression=false,prefix_compression_min=4,readonly=false,split_deepen_min_child=0,split_deepen_per_child=0,split_pct=90,tiered_object=false,tiered_storage=(auth_token=,bucket=,bucket_prefix=,cache_directory=,local_retention=300,name=,object_target_size=0),value_format=S,verbose=[],version=(major=1,minor=1),write_timestamp_usage=none,checkpoint=(WiredTigerCheckpoint.99539=(addr="018081e4760268df8181e4e314ef2b8281e4f0cb9f65808080e301ffc0e3010fc0",order=99539,time=1674424019,size=81920,newest_start_durable_ts=0,oldest_start_ts=0,newest_txn=3110,newest_stop_durable_ts=0,newest_stop_ts=-1,newest_stop_txn=-11,prepare=0,write_gen=299042,run_write_gen=294763)),checkpoint_backup_info=,checkpoint_lsn=(38,1188480)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
src/docker-compose/mongo/data/db/index-1--6471522924120802764.wt
Normal file
BIN
src/docker-compose/mongo/data/db/index-1--6471522924120802764.wt
Normal file
Binary file not shown.
BIN
src/docker-compose/mongo/data/db/index-2--6471522924120802764.wt
Normal file
BIN
src/docker-compose/mongo/data/db/index-2--6471522924120802764.wt
Normal file
Binary file not shown.
BIN
src/docker-compose/mongo/data/db/index-4--6471522924120802764.wt
Normal file
BIN
src/docker-compose/mongo/data/db/index-4--6471522924120802764.wt
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/docker-compose/mongo/data/db/index-5--6471522924120802764.wt
Normal file
BIN
src/docker-compose/mongo/data/db/index-5--6471522924120802764.wt
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user