Use InMemory db driver at testing

This commit is contained in:
Paul Schneider 2026-05-28 22:18:26 +01:00
commit 95dec3636a
24 changed files with 474 additions and 139 deletions

View file

@ -0,0 +1,65 @@
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="AsciiDocSharp" Version="0.2.0" />
<PackageVersion Include="AsciiDocSharp.Converters.Html" Version="0.2.0" />
<PackageVersion Include="bootstrap" Version="5.3.8" />
<PackageVersion Include="coverlet.collector" Version="10.0.1" />
<PackageVersion Include="Google.Apis.Calendar.v3" Version="1.74.0.4154" />
<PackageVersion Include="Google.Apis.Compute.v1" Version="1.74.0.4138" />
<PackageVersion Include="HigginsSoft.IdentityServer8" Version="8.0.5-preview-net9" />
<PackageVersion Include="HigginsSoft.IdentityServer8.AspNetIdentity" Version="8.0.5-preview-net9" />
<PackageVersion Include="HigginsSoft.IdentityServer8.EntityFramework" Version="8.0.5-preview-net9" />
<PackageVersion Include="HigginsSoft.IdentityServer8.EntityFramework.Storage" Version="8.0.5-preview-net9" />
<PackageVersion Include="HigginsSoft.IdentityServer8.Security" Version="8.0.5-preview-net9" />
<PackageVersion Include="HigginsSoft.IdentityServer8.Storage" Version="8.0.5-preview-net9" />
<PackageVersion Include="IdentityModel.AspNetCore" Version="4.3.0" />
<PackageVersion Include="IdentityModel.OidcClient" Version="6.0.0" />
<PackageVersion Include="MailKit" Version="4.17.0" />
<PackageVersion Include="Microsoft.AspNetCore.Antiforgery" Version="2.3.10" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.Google" Version="10.0.8" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="10.0.8" />
<PackageVersion Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="10.0.8" />
<PackageVersion Include="Microsoft.AspNetCore.Hosting" Version="2.3.10" />
<PackageVersion Include="Microsoft.AspNetCore.Http.Features" Version="5.0.17" />
<PackageVersion Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="10.0.8" />
<PackageVersion Include="Microsoft.AspNetCore.Identity.UI" Version="10.0.8" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="10.0.8" />
<PackageVersion Include="Microsoft.AspNetCore.Razor" Version="2.3.0" />
<PackageVersion Include="Microsoft.AspNetCore.Razor.Language" Version="6.0.36" />
<PackageVersion Include="Microsoft.AspNetCore.SignalR" Version="1.2.10" />
<PackageVersion Include="Microsoft.AspNetCore.StaticFiles" Version="2.3.10" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.8" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.InMemory" Version="10.0.8" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="10.0.8" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.CommandLineUtils" Version="1.1.1" />
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Options" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="10.0.6" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.5.1" />
<PackageVersion Include="Microsoft.Playwright" Version="1.60.0" />
<PackageVersion Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="10.0.2" />
<PackageVersion Include="MimeKit" Version="4.16.0" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.4" />
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.1" />
<PackageVersion Include="PayPalMerchantSDK" Version="2.16.250" />
<PackageVersion Include="pazof.rules" Version="1.1.3" />
<PackageVersion Include="popper.js" Version="1.16.1" />
<PackageVersion Include="RazorEngine.NetCore" Version="3.1.1" />
<PackageVersion Include="Selenium.WebDriver" Version="4.44.0" />
<PackageVersion Include="Serilog.AspNetCore" Version="10.0.0" />
<PackageVersion Include="Swashbuckle.AspNetCore" Version="10.1.7" />
<PackageVersion Include="System.Security.Cryptography.Pkcs" Version="10.0.8" />
<PackageVersion Include="xunit" Version="2.9.3" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.1.5" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.8" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.InMemory" Version="10.0.8" />
</ItemGroup>
</Project>

View file

@ -5,10 +5,16 @@
<ItemGroup> <ItemGroup>
<PackageVersion Include="AsciiDocSharp" Version="0.2.0" /> <PackageVersion Include="AsciiDocSharp" Version="0.2.0" />
<PackageVersion Include="AsciiDocSharp.Converters.Html" Version="0.2.0" /> <PackageVersion Include="AsciiDocSharp.Converters.Html" Version="0.2.0" />
<PackageVersion Include="Avalonia" Version="12.0.4" />
<PackageVersion Include="Avalonia.AvaloniaEdit" Version="12.0.0" />
<PackageVersion Include="Avalonia.Desktop" Version="12.0.4" />
<PackageVersion Include="Avalonia.Fonts.Inter" Version="12.0.4" />
<PackageVersion Include="Avalonia.Themes.Fluent" Version="12.0.4" />
<PackageVersion Include="AvaloniaUI.DiagnosticsSupport" Version="2.2.1" />
<PackageVersion Include="bootstrap" Version="5.3.8" /> <PackageVersion Include="bootstrap" Version="5.3.8" />
<PackageVersion Include="coverlet.collector" Version="10.0.0" /> <PackageVersion Include="coverlet.collector" Version="10.0.1" />
<PackageVersion Include="Google.Apis.Calendar.v3" Version="1.73.0.4073" /> <PackageVersion Include="Google.Apis.Calendar.v3" Version="1.74.0.4154" />
<PackageVersion Include="Google.Apis.Compute.v1" Version="1.73.0.4107" /> <PackageVersion Include="Google.Apis.Compute.v1" Version="1.74.0.4138" />
<PackageVersion Include="HigginsSoft.IdentityServer8" Version="8.0.5-preview-net9" /> <PackageVersion Include="HigginsSoft.IdentityServer8" Version="8.0.5-preview-net9" />
<PackageVersion Include="HigginsSoft.IdentityServer8.AspNetIdentity" Version="8.0.5-preview-net9" /> <PackageVersion Include="HigginsSoft.IdentityServer8.AspNetIdentity" Version="8.0.5-preview-net9" />
<PackageVersion Include="HigginsSoft.IdentityServer8.EntityFramework" Version="8.0.5-preview-net9" /> <PackageVersion Include="HigginsSoft.IdentityServer8.EntityFramework" Version="8.0.5-preview-net9" />
@ -17,47 +23,51 @@
<PackageVersion Include="HigginsSoft.IdentityServer8.Storage" Version="8.0.5-preview-net9" /> <PackageVersion Include="HigginsSoft.IdentityServer8.Storage" Version="8.0.5-preview-net9" />
<PackageVersion Include="IdentityModel.AspNetCore" Version="4.3.0" /> <PackageVersion Include="IdentityModel.AspNetCore" Version="4.3.0" />
<PackageVersion Include="IdentityModel.OidcClient" Version="6.0.0" /> <PackageVersion Include="IdentityModel.OidcClient" Version="6.0.0" />
<PackageVersion Include="MailKit" Version="4.16.0" /> <PackageVersion Include="Magick.NET-Q8-AnyCPU" Version="14.13.1" />
<PackageVersion Include="Microsoft.AspNetCore.Antiforgery" Version="2.3.9" /> <PackageVersion Include="MailKit" Version="4.17.0" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.Google" Version="9.0.7" /> <PackageVersion Include="Microsoft.AspNetCore.Antiforgery" Version="2.3.10" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.7" /> <PackageVersion Include="Microsoft.AspNetCore.Authentication.Google" Version="10.0.8" />
<PackageVersion Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="9.0.7" /> <PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="10.0.8" />
<PackageVersion Include="Microsoft.AspNetCore.Hosting" Version="2.3.9" /> <PackageVersion Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="10.0.8" />
<PackageVersion Include="Microsoft.AspNetCore.Hosting" Version="2.3.10" />
<PackageVersion Include="Microsoft.AspNetCore.Http.Features" Version="5.0.17" /> <PackageVersion Include="Microsoft.AspNetCore.Http.Features" Version="5.0.17" />
<PackageVersion Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="9.0.7" /> <PackageVersion Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="10.0.8" />
<PackageVersion Include="Microsoft.AspNetCore.Identity.UI" Version="10.0.6" /> <PackageVersion Include="Microsoft.AspNetCore.Identity.UI" Version="10.0.8" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="9.0.7" /> <PackageVersion Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="10.0.8" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.8" />
<PackageVersion Include="Microsoft.AspNetCore.Razor" Version="2.3.0" /> <PackageVersion Include="Microsoft.AspNetCore.Razor" Version="2.3.0" />
<PackageVersion Include="Microsoft.AspNetCore.Razor.Language" Version="6.0.36" /> <PackageVersion Include="Microsoft.AspNetCore.Razor.Language" Version="6.0.36" />
<PackageVersion Include="Microsoft.AspNetCore.SignalR" Version="1.2.9" /> <PackageVersion Include="Microsoft.AspNetCore.SignalR" Version="1.2.10" />
<PackageVersion Include="Microsoft.AspNetCore.StaticFiles" Version="2.3.9" /> <PackageVersion Include="Microsoft.AspNetCore.StaticFiles" Version="2.3.10" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.7" /> <PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.8" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.InMemory" Version="9.0.7" /> <PackageVersion Include="Microsoft.EntityFrameworkCore.InMemory" Version="10.0.8" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.7" /> <PackageVersion Include="Microsoft.EntityFrameworkCore.InMemory" Version="10.0.8" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.6" /> <PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="10.0.6" /> <PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.CommandLineUtils" Version="1.1.1" /> <PackageVersion Include="Microsoft.Extensions.CommandLineUtils" Version="1.1.1" />
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="10.0.6" /> <PackageVersion Include="Microsoft.Extensions.Configuration" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="10.0.6" /> <PackageVersion Include="Microsoft.Extensions.Hosting" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="10.0.6" /> <PackageVersion Include="Microsoft.Extensions.Logging" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Options" Version="10.0.6" /> <PackageVersion Include="Microsoft.Extensions.Options" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="10.0.6" /> <PackageVersion Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="10.0.8" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.4.0" /> <PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.6.0" />
<PackageVersion Include="Microsoft.Playwright" Version="1.59.0" /> <PackageVersion Include="Microsoft.Playwright" Version="1.60.0" />
<PackageVersion Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="9.0.0" /> <PackageVersion Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="10.0.2" />
<PackageVersion Include="MimeKit" Version="4.16.0" /> <PackageVersion Include="MimeKit" Version="4.17.0" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.4" /> <PackageVersion Include="Newtonsoft.Json" Version="13.0.4" />
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.4" /> <PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.2" />
<PackageVersion Include="PayPalMerchantSDK" Version="2.16.250" /> <PackageVersion Include="PayPalMerchantSDK" Version="2.16.250" />
<PackageVersion Include="pazof.rules" Version="1.1.3" /> <PackageVersion Include="pazof.rules" Version="1.1.3" />
<PackageVersion Include="popper.js" Version="1.16.1" /> <PackageVersion Include="popper.js" Version="1.16.1" />
<PackageVersion Include="RazorEngine.NetCore" Version="3.1.1" /> <PackageVersion Include="RazorEngine.NetCore" Version="3.1.1" />
<PackageVersion Include="Selenium.WebDriver" Version="4.43.0" /> <PackageVersion Include="Selenium.WebDriver" Version="4.44.0" />
<PackageVersion Include="Serilog.AspNetCore" Version="10.0.0" /> <PackageVersion Include="Serilog.AspNetCore" Version="10.0.0" />
<PackageVersion Include="SixLabors.ImageSharp" Version="3.1.12" /> <PackageVersion Include="SixLabors.ImageSharp" Version="4.0.0" />
<PackageVersion Include="Swashbuckle.AspNetCore" Version="10.1.7" /> <PackageVersion Include="Swashbuckle.AspNetCore" Version="10.1.7" />
<PackageVersion Include="System.Security.Cryptography.Pkcs" Version="10.0.6" /> <PackageVersion Include="System.Security.Cryptography.Pkcs" Version="10.0.8" />
<PackageVersion Include="xunit" Version="2.9.3" /> <PackageVersion Include="xunit" Version="2.9.3" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.1.5" /> <PackageVersion Include="xunit.runner.visualstudio" Version="3.1.5" />
<PackageVersion Include="Yavsc.Abstract" Version="1.0.6-rc18" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View file

@ -4,9 +4,10 @@
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>1c73094f-959f-4211-b1a1-6a69b236c283</UserSecretsId> <UserSecretsId>1c73094f-959f-4211-b1a1-6a69b236c283</UserSecretsId>
<RootNamespace>Yavsc.Api</RootNamespace> <RootNamespace>Yavsc.Api</RootNamespace>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" />
<ProjectReference Include="../Yavsc.Server/Yavsc.Server.csproj" /> <ProjectReference Include="../Yavsc.Server/Yavsc.Server.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View file

@ -115,7 +115,7 @@ namespace Yavsc.ApiControllers
} }
if (Request.Form.Files.Count!=1) if (Request.Form.Files.Count!=1)
return new BadRequestResult(); return new BadRequestResult();
User.ReceiveProSignature(billingCode,id,Request.Form.Files[0],"pro"); await User.ReceiveProSignatureAsync(billingCode,id,Request.Form.Files[0],"pro");
estimate.ProviderValidationDate = DateTime.Now; estimate.ProviderValidationDate = DateTime.Now;
dbContext.SaveChanges(User.GetUserId()); dbContext.SaveChanges(User.GetUserId());
// Notify the client // Notify the client
@ -160,7 +160,7 @@ namespace Yavsc.ApiControllers
} }
if (Request.Form.Files.Count!=1) if (Request.Form.Files.Count!=1)
return new BadRequestResult(); return new BadRequestResult();
User.ReceiveProSignature(billingCode,id,Request.Form.Files[0],"cli"); await User.ReceiveProSignatureAsync(billingCode,id,Request.Form.Files[0],"cli");
estimate.ClientValidationDate = DateTime.Now; estimate.ClientValidationDate = DateTime.Now;
dbContext.SaveChanges(User.GetUserId()); dbContext.SaveChanges(User.GetUserId());
return Ok (new { ClientValidationDate = estimate.ClientValidationDate }); return Ok (new { ClientValidationDate = estimate.ClientValidationDate });

View file

@ -66,12 +66,15 @@ namespace Yavsc.WebApi.Controllers
/// Updates the avatar /// Updates the avatar
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[HttpPost("~/api/setavatar")] [HttpPost("~/api/set-avatar")]
public async Task<IActionResult> SetAvatar() public async Task<IActionResult> SetAvatar()
{ {
var user = await GetUserData(User.GetUserId()); var user = await GetUserData(User.GetUserId());
if (Request.Form.Files.Count!=1) if (Request.Form.Files.Count!=1)
return new BadRequestResult(); return new BadRequestResult();
if (!Request.Form.Files[0].ContentType.StartsWith("image/png"))
return new BadRequestResult();
var info = user.ReceiveAvatar(Request.Form.Files[0]); var info = user.ReceiveAvatar(Request.Form.Files[0]);
await _dbContext.SaveChangesAsync(); await _dbContext.SaveChangesAsync();
return Ok(info); return Ok(info);

12
src/PostIt/App.axaml Normal file
View file

@ -0,0 +1,12 @@
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="PostIt.App"
RequestedThemeVariant="Default">
<!-- "Default" ThemeVariant follows system theme variant. "Dark" or "Light" are other available options. -->
<Application.Styles>
<FluentTheme />
<StyleInclude Source="avares://AvaloniaEdit/Themes/Fluent/AvaloniaEdit.xaml" />
</Application.Styles>
</Application>

23
src/PostIt/App.axaml.cs Normal file
View file

@ -0,0 +1,23 @@
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
namespace PostIt;
public partial class App : Application
{
public override void Initialize()
{
AvaloniaXamlLoader.Load(this);
}
public override void OnFrameworkInitializationCompleted()
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
desktop.MainWindow = new MainWindow();
}
base.OnFrameworkInitializationCompleted();
}
}

View file

@ -0,0 +1,27 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:AvaloniaEdit="clr-namespace:AvaloniaEdit;assembly=AvaloniaEdit"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="PostIt.MainWindow"
Title="PostIt">
<Window.Content>
<StackPanel>
<Label>Welcome to Avalonia !!!</Label>
<Label x:Name="Greeting">
Hello !
</Label>
<AvaloniaEdit:TextEditor
ShowLineNumbers="True"
FontFamily="Cascadia Code,Consolas,Menlo,Monospace"
Background="AliceBlue"
Foreground="Black"
Watermark="Hit me strong!"
/>
</StackPanel>
</Window.Content>
</Window>

View file

@ -0,0 +1,12 @@
using Avalonia.Controls;
namespace PostIt;
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.Greeting.Content="Hello Joe!";
}
}

21
src/PostIt/PostIt.csproj Normal file
View file

@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ApplicationManifest>app.manifest</ApplicationManifest>
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Avalonia" />
<PackageReference Include="Avalonia.AvaloniaEdit" />
<PackageReference Include="Avalonia.Desktop" />
<PackageReference Include="Avalonia.Themes.Fluent" />
<PackageReference Include="Avalonia.Fonts.Inter" />
<PackageReference Include="AvaloniaUI.DiagnosticsSupport">
<IncludeAssets Condition="'$(Configuration)' != 'Debug'">None</IncludeAssets>
<PrivateAssets Condition="'$(Configuration)' != 'Debug'">All</PrivateAssets>
</PackageReference>
<PackageReference Include="Yavsc.Abstract" />
</ItemGroup>
</Project>

24
src/PostIt/Program.cs Normal file
View file

@ -0,0 +1,24 @@
using Avalonia;
using System;
namespace PostIt;
class Program
{
// Initialization code. Don't use any Avalonia, third-party APIs or any
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized
// yet and stuff might break.
[STAThread]
public static void Main(string[] args) => BuildAvaloniaApp()
.StartWithClassicDesktopLifetime(args);
// Avalonia configuration, don't remove; also used by visual designer.
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>()
.UsePlatformDetect()
#if DEBUG
.WithDeveloperTools()
#endif
.WithInterFont()
.LogToTrace();
}

18
src/PostIt/app.manifest Normal file
View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<!-- This manifest is used on Windows only.
Don't remove it as it might cause problems with window transparency and embedded controls.
For more details visit https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests -->
<assemblyIdentity version="1.0.0.0" name="PostIt.Desktop"/>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- A list of the Windows versions that this application has been tested on
and is designed to work with. Uncomment the appropriate elements
and Windows will automatically select the most compatible environment. -->
<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
</application>
</compatibility>
</assembly>

View file

@ -6,8 +6,9 @@
</Description> </Description>
<RootNamespace>Yavsc.Abstract</RootNamespace> <RootNamespace>Yavsc.Abstract</RootNamespace>
<RepositoryUrl>https://github.com/pazof/yavsc</RepositoryUrl> <RepositoryUrl>https://github.com/pazof/yavsc</RepositoryUrl>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Newtonsoft.Json" /> <PackageReference Include="Newtonsoft.Json" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View file

@ -5,9 +5,10 @@
<UserSecretsId>1c73094f-959f-4211-b1a1-6a69b236c283</UserSecretsId> <UserSecretsId>1c73094f-959f-4211-b1a1-6a69b236c283</UserSecretsId>
<RootNamespace>Yavsc.Api</RootNamespace> <RootNamespace>Yavsc.Api</RootNamespace>
<RepositoryUrl>https://github.com/pazof/yavsc</RepositoryUrl> <RepositoryUrl>https://github.com/pazof/yavsc</RepositoryUrl>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" />
<ProjectReference Include="../Yavsc.Server/Yavsc.Server.csproj" /> <ProjectReference Include="../Yavsc.Server/Yavsc.Server.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View file

@ -37,6 +37,7 @@ namespace Yavsc.Extensions;
public static class HostingExtensions public static class HostingExtensions
{ {
private const string InMemoryProviderName = "InMemory";
public static WebApplication ConfigureWebAppServices(this WebApplicationBuilder builder) public static WebApplication ConfigureWebAppServices(this WebApplicationBuilder builder)
{ {
@ -140,11 +141,19 @@ public static class HostingExtensions
public static IdentityBuilder AddIdentityDBAndStores(this WebApplicationBuilder builder) public static IdentityBuilder AddIdentityDBAndStores(this WebApplicationBuilder builder)
{ {
IServiceCollection services = builder.Services; IServiceCollection services = builder.Services;
var connectionString = builder.Configuration.GetConnectionString(Constants.YavscConnectionStringName);
services.AddDbContext<ApplicationDbContext>(options => services.AddDbContext<ApplicationDbContext>(options =>
{ {
options.UseNpgsql(builder.Configuration.GetConnectionString(Constants.YavscConnectionStringName), if (UsesInMemoryProvider(connectionString))
options => options.MigrationsAssembly(typeof(Program).Assembly)); {
options.UseInMemoryDatabase(connectionString);
}
else
{
options.UseNpgsql(connectionString,
options => options.MigrationsAssembly(typeof(Program).Assembly));
}
}); });
var identityBuilder = services.AddIdentity<ApplicationUser, IdentityRole>( var identityBuilder = services.AddIdentity<ApplicationUser, IdentityRole>(
@ -285,14 +294,35 @@ public static class HostingExtensions
.AddResourceStore<ResourceStore>() .AddResourceStore<ResourceStore>()
.AddConfigurationStore(options => .AddConfigurationStore(options =>
{ {
options.ConfigureDbContext = b => b.UseNpgsql(connectionString, options.ConfigureDbContext = b =>
sql => sql.MigrationsAssembly(migrationsAssembly)) {
.UseSeeding(EnsureDefaultApplicationScopes()); if (UsesInMemoryProvider(connectionString))
{
b.UseInMemoryDatabase(connectionString);
}
else
{
b.UseNpgsql(connectionString,
sql => sql.MigrationsAssembly(migrationsAssembly));
}
b.UseSeeding(EnsureDefaultApplicationScopes());
};
}) })
.AddOperationalStore(options => .AddOperationalStore(options =>
{ {
options.ConfigureDbContext = b => b.UseNpgsql(connectionString, options.ConfigureDbContext = b =>
sql => sql.MigrationsAssembly(migrationsAssembly)); {
if (UsesInMemoryProvider(connectionString))
{
b.UseInMemoryDatabase(connectionString);
}
else
{
b.UseNpgsql(connectionString,
sql => sql.MigrationsAssembly(migrationsAssembly));
}
};
}); });
@ -303,6 +333,11 @@ public static class HostingExtensions
return identityServerBuilder; return identityServerBuilder;
} }
private static bool UsesInMemoryProvider(string connectionString)
{
return string.Equals(connectionString, InMemoryProviderName, StringComparison.OrdinalIgnoreCase);
}
private static Action<DbContext, bool> EnsureDefaultApplicationScopes() private static Action<DbContext, bool> EnsureDefaultApplicationScopes()
{ {
return (context, _) => return (context, _) =>

View file

@ -5,7 +5,7 @@
<PackageLicenseExpression>WTFPL</PackageLicenseExpression> <PackageLicenseExpression>WTFPL</PackageLicenseExpression>
<UserSecretsId>76e56fc2-1619-40d8-8393-365258b7a21d</UserSecretsId> <UserSecretsId>76e56fc2-1619-40d8-8393-365258b7a21d</UserSecretsId>
<RootNamespace>Yavsc</RootNamespace> <RootNamespace>Yavsc</RootNamespace>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<RepositoryUrl>https://github.com/pazof/yavsc</RepositoryUrl> <RepositoryUrl>https://github.com/pazof/yavsc</RepositoryUrl>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@ -21,7 +21,6 @@
<PackageReference Include="HigginsSoft.IdentityServer8.EntityFramework.Storage" /> <PackageReference Include="HigginsSoft.IdentityServer8.EntityFramework.Storage" />
<PackageReference Include="HigginsSoft.IdentityServer8.Security" /> <PackageReference Include="HigginsSoft.IdentityServer8.Security" />
<PackageReference Include="HigginsSoft.IdentityServer8.Storage" /> <PackageReference Include="HigginsSoft.IdentityServer8.Storage" />
<PackageReference Include="Serilog.AspNetCore" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" /> <PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" /> <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" />
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" /> <PackageReference Include="Microsoft.AspNetCore.Identity.UI" />
@ -33,6 +32,7 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" />
<PackageReference Include="Google.Apis.Compute.v1" /> <PackageReference Include="Google.Apis.Compute.v1" />
@ -44,7 +44,6 @@
<PackageReference Include="Swashbuckle.AspNetCore" /> <PackageReference Include="Swashbuckle.AspNetCore" />
<PackageReference Include="AsciiDocSharp" /> <PackageReference Include="AsciiDocSharp" />
<PackageReference Include="AsciiDocSharp.Converters.Html" /> <PackageReference Include="AsciiDocSharp.Converters.Html" />
<PackageReference Include="SixLabors.ImageSharp" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.Google" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.Google" />
<PackageReference Include="Microsoft.Extensions.Logging" /> <PackageReference Include="Microsoft.Extensions.Logging" />
</ItemGroup> </ItemGroup>

View file

@ -7,38 +7,34 @@ using Yavsc.Models;
using Yavsc.Models.FileSystem; using Yavsc.Models.FileSystem;
using Yavsc.Models.Streaming; using Yavsc.Models.Streaming;
using Yavsc.ViewModels; using Yavsc.ViewModels;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Processing;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Yavsc.Exceptions; using Yavsc.Exceptions;
using Yavsc.Helpers; using Yavsc.Helpers;
using Yavsc.Abstract.Helpers; using Yavsc.Abstract.Helpers;
using ImageMagick;
namespace Yavsc.Server.Helpers namespace Yavsc.Server.Helpers
{ {
public static class FileSystemHelpers public static class FileSystemHelpers
{ {
public static async Task SaveAsAsync(this IFormFile formFile, string path) public static async Task SaveAsAsync(this IFormFile formFile, string path)
{ {
if (formFile.Length > 0) { if (formFile.Length > 0)
using (Stream fileStream = new FileStream(path, FileMode.Create)) { {
using (Stream fileStream = new FileStream(path, FileMode.Create))
{
await formFile.CopyToAsync(fileStream); await formFile.CopyToAsync(fileStream);
} }
} }
} }
public static FileReceivedInfo ReceiveProSignature(this ClaimsPrincipal user, string billingCode, long estimateId, IFormFile formFile, string signType) public static async Task<FileReceivedInfo> ReceiveProSignatureAsync(this ClaimsPrincipal user, string billingCode, long estimateId, IFormFile formFile, string signType)
{ {
var item = new FileReceivedInfo( var item = new FileReceivedInfo(
Config.SiteSetup.Bills, Config.SiteSetup.Bills,
AbstractFileSystemHelpers.SignFileNameFormat("pro", billingCode, estimateId)); AbstractFileSystemHelpers.SignFileNameFormat("pro", billingCode, estimateId));
var fi = new FileInfo(item.FullName); var fi = new FileInfo(item.FullName);
if (fi.Exists) item.Overridden = true; if (fi.Exists) item.Overridden = true;
await formFile.SaveAsAsync(fi.FullName);
using (var org = formFile.OpenReadStream())
{
using Image image = Image.Load(org);
image.Save(fi.FullName);
}
return item; return item;
} }
@ -76,67 +72,70 @@ namespace Yavsc.Server.Helpers
{ {
var root = Path.Combine(AbstractFileSystemHelpers.UserFilesDirName, user.UserName); var root = Path.Combine(AbstractFileSystemHelpers.UserFilesDirName, user.UserName);
var fi = new FileInfo(Path.Combine(root, fileName)); var fi = new FileInfo(Path.Combine(root, fileName));
if (!fi.Exists) return ; if (!fi.Exists) return;
fi.Delete(); fi.Delete();
user.DiskUsage -= fi.Length; user.DiskUsage -= fi.Length;
} }
public static FsOperationInfo DeleteUserDirOrFile(this ApplicationUser user, string dirName) public static FsOperationInfo DeleteUserDirOrFile(this ApplicationUser user, string dirName)
{ {
var root = Path.Combine(AbstractFileSystemHelpers.UserFilesDirName, user.UserName); var root = Path.Combine(AbstractFileSystemHelpers.UserFilesDirName, user.UserName);
if (string.IsNullOrEmpty(dirName)) if (string.IsNullOrEmpty(dirName))
return new FsOperationInfo { Done = false, ErrorCode = ErrorCode.InvalidRequest, ErrorMessage = "specify a directory or file name"} ; return new FsOperationInfo { Done = false, ErrorCode = ErrorCode.InvalidRequest, ErrorMessage = "specify a directory or file name" };
var di = new DirectoryInfo(Path.Combine(root, dirName)); var di = new DirectoryInfo(Path.Combine(root, dirName));
if (!di.Exists) { if (!di.Exists)
{
var fi = new FileInfo(Path.Combine(root, dirName)); var fi = new FileInfo(Path.Combine(root, dirName));
if (!fi.Exists) return new FsOperationInfo { Done = false, ErrorCode = ErrorCode.NotFound, ErrorMessage = "non existent"} ; if (!fi.Exists) return new FsOperationInfo { Done = false, ErrorCode = ErrorCode.NotFound, ErrorMessage = "non existent" };
fi.Delete(); fi.Delete();
user.DiskUsage -= fi.Length; user.DiskUsage -= fi.Length;
} }
else { else
if (di.GetDirectories().Length>0 || di.GetFiles().Length>0) {
return new FsOperationInfo { Done = false, ErrorCode = ErrorCode.InvalidRequest, ErrorMessage = "dir is not empty, refusing to remove it"} ; if (di.GetDirectories().Length > 0 || di.GetFiles().Length > 0)
return new FsOperationInfo { Done = false, ErrorCode = ErrorCode.InvalidRequest, ErrorMessage = "dir is not empty, refusing to remove it" };
di.Delete(); di.Delete();
} }
return new FsOperationInfo { Done = true }; return new FsOperationInfo { Done = true };
} }
public static FsOperationInfo MoveUserDir(this ApplicationUser user, string fromDirName, string toDirName) public static FsOperationInfo MoveUserDir(this ApplicationUser user, string fromDirName, string toDirName)
{ {
var root = Path.Combine(AbstractFileSystemHelpers.UserFilesDirName, user.UserName); var root = Path.Combine(AbstractFileSystemHelpers.UserFilesDirName, user.UserName);
if (string.IsNullOrEmpty(fromDirName)) if (string.IsNullOrEmpty(fromDirName))
return new FsOperationInfo { Done = false, ErrorCode = ErrorCode.InvalidRequest , ErrorMessage = "specify a dir name "} ; return new FsOperationInfo { Done = false, ErrorCode = ErrorCode.InvalidRequest, ErrorMessage = "specify a dir name " };
var di = new DirectoryInfo(Path.Combine(root, fromDirName)); var di = new DirectoryInfo(Path.Combine(root, fromDirName));
if (!di.Exists) return new FsOperationInfo { Done = false, ErrorCode = ErrorCode.NotFound, ErrorMessage = "fromDirName: non existent"} ; if (!di.Exists) return new FsOperationInfo { Done = false, ErrorCode = ErrorCode.NotFound, ErrorMessage = "fromDirName: non existent" };
if (string.IsNullOrEmpty(toDirName)) toDirName = "."; if (string.IsNullOrEmpty(toDirName)) toDirName = ".";
var destPath = Path.Combine(root, toDirName); var destPath = Path.Combine(root, toDirName);
var fout = new FileInfo(destPath); var fout = new FileInfo(destPath);
if (fout.Exists) return new FsOperationInfo { Done = false, ErrorCode = ErrorCode.InvalidRequest, ErrorMessage = "destination is a regular file" } ; if (fout.Exists) return new FsOperationInfo { Done = false, ErrorCode = ErrorCode.InvalidRequest, ErrorMessage = "destination is a regular file" };
var dout = new DirectoryInfo(destPath); var dOut = new DirectoryInfo(destPath);
if (dout.Exists) { if (dOut.Exists)
destPath = Path.Combine(destPath, dout.Name); {
destPath = Path.Combine(destPath, dOut.Name);
} }
di.MoveTo(destPath); di.MoveTo(destPath);
return new FsOperationInfo { Done = true }; return new FsOperationInfo { Done = true };
} }
public static FsOperationInfo MoveUserFileToDir(this ApplicationUser user, string fileNameFrom, string fileNameDest) public static FsOperationInfo MoveUserFileToDir(this ApplicationUser user, string fileNameFrom, string fileNameDest)
{ {
var root = Path.Combine(AbstractFileSystemHelpers.UserFilesDirName, user.UserName); var root = Path.Combine(AbstractFileSystemHelpers.UserFilesDirName, user.UserName);
var fi = new FileInfo(Path.Combine(root, fileNameFrom)); var fi = new FileInfo(Path.Combine(root, fileNameFrom));
if (!fi.Exists) return new FsOperationInfo { ErrorCode = ErrorCode.NotFound, ErrorMessage = "no file to move" } ; if (!fi.Exists) return new FsOperationInfo { ErrorCode = ErrorCode.NotFound, ErrorMessage = "no file to move" };
string dest; string dest;
if (!string.IsNullOrEmpty(fileNameDest)) dest = Path.Combine(root, fileNameDest); if (!string.IsNullOrEmpty(fileNameDest)) dest = Path.Combine(root, fileNameDest);
else dest = root; else dest = root;
var fo = new FileInfo(dest); var fo = new FileInfo(dest);
if (fo.Exists) return new FsOperationInfo { ErrorCode = ErrorCode.DestExists , ErrorMessage = "destination file name is an existing file" } ; if (fo.Exists) return new FsOperationInfo { ErrorCode = ErrorCode.DestExists, ErrorMessage = "destination file name is an existing file" };
var dout = new DirectoryInfo(dest); var dout = new DirectoryInfo(dest);
if (!dout.Exists) dout.Create(); if (!dout.Exists) dout.Create();
fi.MoveTo(Path.Combine(dout.FullName, fi.Name)); fi.MoveTo(Path.Combine(dout.FullName, fi.Name));
@ -146,9 +145,9 @@ namespace Yavsc.Server.Helpers
{ {
var root = Path.Combine(AbstractFileSystemHelpers.UserFilesDirName, user.UserName); var root = Path.Combine(AbstractFileSystemHelpers.UserFilesDirName, user.UserName);
var fi = new FileInfo(Path.Combine(root, fileNameFrom)); var fi = new FileInfo(Path.Combine(root, fileNameFrom));
if (!fi.Exists) return new FsOperationInfo { ErrorCode = ErrorCode.NotFound, ErrorMessage = "no file to move" } ; if (!fi.Exists) return new FsOperationInfo { ErrorCode = ErrorCode.NotFound, ErrorMessage = "no file to move" };
var fo = new FileInfo(Path.Combine(root, fileNameDest)); var fo = new FileInfo(Path.Combine(root, fileNameDest));
if (fo.Exists) return new FsOperationInfo { ErrorCode = ErrorCode.DestExists , ErrorMessage = "destination file name is an existing file" } ; if (fo.Exists) return new FsOperationInfo { ErrorCode = ErrorCode.DestExists, ErrorMessage = "destination file name is an existing file" };
fi.MoveTo(fo.FullName); fi.MoveTo(fo.FullName);
return new FsOperationInfo { Done = true }; return new FsOperationInfo { Done = true };
} }
@ -158,7 +157,7 @@ namespace Yavsc.Server.Helpers
// form-data_ name=_file__ filename=_Constants.Private.cs_ // form-data_ name=_file__ filename=_Constants.Private.cs_
var parts = disposition.Split(' '); var parts = disposition.Split(' ');
var filename = parts[2].Split('=')[1]; var filename = parts[2].Split('=')[1];
filename = filename.Substring(1,filename.Length-2); filename = filename.Substring(1, filename.Length - 2);
return filename; return filename;
} }
@ -170,7 +169,7 @@ namespace Yavsc.Server.Helpers
{ {
return ReceiveUserFile(user, root, f.OpenReadStream(), destFileName ?? ParseFileNameFromDisposition(f.ContentDisposition), f.ContentType, CancellationToken.None); return ReceiveUserFile(user, root, f.OpenReadStream(), destFileName ?? ParseFileNameFromDisposition(f.ContentDisposition), f.ContentType, CancellationToken.None);
} }
/// <summary> /// <summary>
/// Modifies the user's disk usage /// Modifies the user's disk usage
/// </summary> /// </summary>
@ -203,7 +202,7 @@ namespace Yavsc.Server.Helpers
{ {
item.Overridden = true; item.Overridden = true;
usage -= fi.Length; usage -= fi.Length;
} }
using (var dest = fi.OpenWrite()) using (var dest = fi.OpenWrite())
{ {
using (inputStream) using (inputStream)
@ -211,7 +210,7 @@ namespace Yavsc.Server.Helpers
const int blen = 1024; const int blen = 1024;
byte[] buffer = new byte[blen]; byte[] buffer = new byte[blen];
int len = 0; int len = 0;
while (!token.IsCancellationRequested && (len=inputStream.Read(buffer, 0, blen))>0) while (!token.IsCancellationRequested && (len = inputStream.Read(buffer, 0, blen)) > 0)
{ {
dest.Write(buffer, 0, len); dest.Write(buffer, 0, len);
usage += len; usage += len;
@ -222,7 +221,8 @@ namespace Yavsc.Server.Helpers
inputStream.Close(); inputStream.Close();
} }
} }
if (usage >= user.DiskQuota) { if (usage >= user.DiskQuota)
{
item.QuotaOffense = true; item.QuotaOffense = true;
} }
user.DiskUsage = usage; user.DiskUsage = usage;
@ -231,15 +231,15 @@ namespace Yavsc.Server.Helpers
public static HtmlString FileLink(this RemoteFileInfo info, string username, string subpath) public static HtmlString FileLink(this RemoteFileInfo info, string username, string subpath)
{ {
return new HtmlString( return new HtmlString(
$"{Config.UserFilesOptions.RequestPath}/{username}/{subpath}/{info.Name}" ); $"{Config.UserFilesOptions.RequestPath}/{username}/{subpath}/{info.Name}");
} }
public static RemoteFileInfo FileInfo(this ApplicationUser user, string path) public static RemoteFileInfo FileInfo(this ApplicationUser user, string path)
{ {
IFileInfo info = Config.UserFilesOptions.FileProvider.GetFileInfo($"{user.UserName}/{path}"); IFileInfo info = Config.UserFilesOptions.FileProvider.GetFileInfo($"{user.UserName}/{path}");
if (!info.Exists) return null; if (!info.Exists) return null;
return new RemoteFileInfo{ Name = info.Name, Size = info.Length, LastModified = info.LastModified.UtcDateTime }; return new RemoteFileInfo { Name = info.Name, Size = info.Length, LastModified = info.LastModified.UtcDateTime };
} }
@ -248,32 +248,43 @@ namespace Yavsc.Server.Helpers
var item = new FileReceivedInfo var item = new FileReceivedInfo
(Config.AvatarsOptions.RequestPath.ToUriComponent(), (Config.AvatarsOptions.RequestPath.ToUriComponent(),
user.UserName + ".png"); user.UserName + ".png");
using (var org = formFile.OpenReadStream()) using (var org = formFile.OpenReadStream())
{ {
using Image image = Image.Load(org);
image.Mutate(x=>x.Resize(128,128)); var size = new MagickGeometry(128, 128);
image.Save(Path.Combine(Config.SiteSetup.Avatars,item.FileName)); size.IgnoreAspectRatio = false;
image.Mutate(x=>x.Resize(64,64)); using var image = new MagickImage(org);
image.Save(Path.Combine(Config.SiteSetup.Avatars,user.UserName + ".s.png"));
image.Mutate(x=>x.Resize(32,32)); image.Resize(size);
image.Save(Path.Combine(Config.SiteSetup.Avatars,user.UserName + ".xs.png")); image.Write(Path.Combine(Config.SiteSetup.Avatars, item.FileName));
size.X = 64;
size.Y = 64;
image.Resize(size);
image.Write(Path.Combine(Config.SiteSetup.Avatars, user.UserName + ".s.png"));
size.X = 32;
size.Y = 32;
image.Resize(size);
image.Write(Path.Combine(Config.SiteSetup.Avatars, user.UserName + ".xs.png"));
} }
user.Avatar = $"{item.DestDir}/{item.FileName}"; user.Avatar = $"{item.DestDir}/{item.FileName}";
return item; return item;
} }
public static string GetFileUrl (this LiveFlow flow) public static string GetFileUrl(this LiveFlow flow)
{ {
// no server-side backup for this stream // no server-side backup for this stream
return $"{Config.UserFilesOptions.RequestPath}/{flow.Owner.UserName}/live/"+GetFileName(flow); return $"{Config.UserFilesOptions.RequestPath}/{flow.Owner.UserName}/live/" + GetFileName(flow);
} }
public static string GetFileName (this LiveFlow flow) public static string GetFileName(this LiveFlow flow)
{ {
var fileInfo = new FileInfo(flow.DifferedFileName); var fileInfo = new FileInfo(flow.DifferedFileName);
var ext = fileInfo.Extension; var ext = fileInfo.Extension;
var namelen = flow.DifferedFileName.Length - ext.Length; var namelen = flow.DifferedFileName.Length - ext.Length;
var basename = flow.DifferedFileName.Substring(0,namelen); var basename = flow.DifferedFileName.Substring(0, namelen);
return $"{basename}-{flow.SequenceNumber}{ext}"; return $"{basename}-{flow.SequenceNumber}{ext}";
} }

View file

@ -4,10 +4,12 @@
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>53bd70e8-ff81-497a-847f-a15fd8ea7a09</UserSecretsId> <UserSecretsId>53bd70e8-ff81-497a-847f-a15fd8ea7a09</UserSecretsId>
<RootNamespace>Yavsc.Server</RootNamespace> <RootNamespace>Yavsc.Server</RootNamespace>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<RepositoryUrl>https://github.com/pazof/yavsc</RepositoryUrl> <RepositoryUrl>https://github.com/pazof/yavsc</RepositoryUrl>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="HigginsSoft.IdentityServer8.EntityFramework" /> <PackageReference Include="HigginsSoft.IdentityServer8.EntityFramework" />
<PackageReference Include="Magick.NET-Q8-AnyCPU" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" /> <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" />
<PackageReference Include="HigginsSoft.IdentityServer8" /> <PackageReference Include="HigginsSoft.IdentityServer8" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" /> <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" />
@ -22,7 +24,6 @@
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" /> <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" />
<PackageReference Include="Google.Apis.Calendar.v3" /> <PackageReference Include="Google.Apis.Calendar.v3" />
<PackageReference Include="PayPalMerchantSDK" /> <PackageReference Include="PayPalMerchantSDK" />
<PackageReference Include="SixLabors.ImageSharp" />
<PackageReference Include="RazorEngine.NetCore" /> <PackageReference Include="RazorEngine.NetCore" />
<PackageReference Include="MailKit" /> <PackageReference Include="MailKit" />
<PackageReference Include="MimeKit" /> <PackageReference Include="MimeKit" />
@ -31,4 +32,4 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="../Yavsc.Abstract/Yavsc.Abstract.csproj" /> <ProjectReference Include="../Yavsc.Abstract/Yavsc.Abstract.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View file

@ -15,4 +15,4 @@
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory> <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content> </Content>
</ItemGroup> </ItemGroup>
</Project> </Project>

View file

@ -4,6 +4,7 @@
<TargetFramework>net10.0</TargetFramework> <TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>Yavsc.cli</RootNamespace> <RootNamespace>Yavsc.cli</RootNamespace>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Razor" /> <PackageReference Include="Microsoft.AspNetCore.Razor" />
@ -18,4 +19,4 @@
<ProjectReference Include="..\Yavsc.Abstract\Yavsc.Abstract.csproj" /> <ProjectReference Include="..\Yavsc.Abstract\Yavsc.Abstract.csproj" />
<ProjectReference Include="..\Yavsc.Server\Yavsc.Server.csproj" /> <ProjectReference Include="..\Yavsc.Server\Yavsc.Server.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View file

@ -12,9 +12,6 @@ using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Serilog;
using Serilog.Events;
using Serilog.Sinks.SystemConsole.Themes;
using System.Net; using System.Net;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
@ -116,22 +113,7 @@ namespace isnd.tests
TestingUserPassword = _sharedTestingUserPassword; TestingUserPassword = _sharedTestingUserPassword;
TestingUserEmail = _sharedTestingUserEmail; TestingUserEmail = _sharedTestingUserEmail;
} }
void ConfigureLogger() => Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
.MinimumLevel.Override("Microsoft.Hosting.Lifetime", LogEventLevel.Information)
.MinimumLevel.Override("System", LogEventLevel.Warning)
.MinimumLevel.Override("Microsoft.AspNetCore.Authentication", LogEventLevel.Information)
.Enrich.FromLogContext()
// uncomment to write to Azure diagnostics stream
//.WriteTo.File(
// @"D:\home\LogFiles\Application\identityserver.txt",
// fileSizeLimitBytes: 1_000_000,
// rollOnFileSizeLimit: true,
// shared: true,
// flushToDiskInterval: TimeSpan.FromSeconds(1))
.WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}", theme: AnsiConsoleTheme.Code)
.CreateLogger();
public async Task SetupHost() public async Task SetupHost()
{ {
@ -142,11 +124,14 @@ namespace isnd.tests
var yavscOrgPath = Path.GetFullPath(Path.Combine(testAssemblyLocation, "../../src/Yavsc.Org")); var yavscOrgPath = Path.GetFullPath(Path.Combine(testAssemblyLocation, "../../src/Yavsc.Org"));
builder.Environment.ContentRootPath = yavscOrgPath; builder.Environment.ContentRootPath = yavscOrgPath;
ConfigureLogger(); builder.Configuration
var config = builder.Configuration
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: false) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: false)
.AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json", optional: false, reloadOnChange: false) .AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json", optional: false, reloadOnChange: false)
.AddEnvironmentVariables().Build(); .AddEnvironmentVariables()
.AddInMemoryCollection(new Dictionary<string, string?>
{
[$"ConnectionStrings:{Constants.YavscConnectionStringName}"] = "InMemory"
});
// Configure Kestrel for HTTPS with self-signed certificate on a dynamic port // Configure Kestrel for HTTPS with self-signed certificate on a dynamic port
builder.WebHost.ConfigureKestrel(options => builder.WebHost.ConfigureKestrel(options =>
@ -162,7 +147,6 @@ namespace isnd.tests
_app = builder.ConfigureWebAppServices(); _app = builder.ConfigureWebAppServices();
Services = _app.Services; Services = _app.Services;
SiteSettings = _app.Services.GetRequiredService<IOptions<SiteSettings>>().Value; SiteSettings = _app.Services.GetRequiredService<IOptions<SiteSettings>>().Value;
String cxStr = config.GetConnectionString(Constants.YavscConnectionStringName) ?? throw new InvalidOperationException("DefaultConnection string is not configured.");
using (var migrationScope = _app.Services.CreateScope()) using (var migrationScope = _app.Services.CreateScope())
{ {

View file

@ -39,7 +39,7 @@
} }
}, },
"ConnectionStrings": { "ConnectionStrings": {
"YavscConnection": "Server=localhost;Port=5432;Database=testingYavsc;Username=lame-Username;Password=lame-dbPassword;" "YavscConnection": "InMemory"
}, },
"DataProtection": { "DataProtection": {
"Keys": { "Keys": {
@ -64,4 +64,4 @@
"Password": "f/\\kePassw0rd" "Password": "f/\\kePassw0rd"
} }
} }
} }

View file

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net10.0</TargetFramework> <TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
@ -6,6 +6,7 @@
<IsPackable>false</IsPackable> <IsPackable>false</IsPackable>
<RootNamespace>Yavsc.Tests</RootNamespace> <RootNamespace>Yavsc.Tests</RootNamespace>
<UserSecretsId>78a4efec-68dc-4745-ba06-d8545ef9ee91</UserSecretsId> <UserSecretsId>78a4efec-68dc-4745-ba06-d8545ef9ee91</UserSecretsId>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="coverlet.collector" /> <PackageReference Include="coverlet.collector" />
@ -43,5 +44,7 @@
<ItemGroup> <ItemGroup>
<Using Include="Xunit" /> <Using Include="Xunit" />
</ItemGroup> </ItemGroup>
<ItemGroup>
</Project> <PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" />
</ItemGroup>
</Project>

View file

@ -23,47 +23,129 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "yavscTests", "test\yavscTes
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yavsc.Blogs", "src\Yavsc.Blogs\Yavsc.Blogs.csproj", "{5D9E161F-3CB3-4854-9D07-3DF6882EA66C}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yavsc.Blogs", "src\Yavsc.Blogs\Yavsc.Blogs.csproj", "{5D9E161F-3CB3-4854-9D07-3DF6882EA66C}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PostIt", "src\PostIt\PostIt.csproj", "{342F9C7A-C72A-47F6-A2A7-442A524D10CE}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU Release|Any CPU = Release|Any CPU
EndGlobalSection Release|x64 = Release|x64
GlobalSection(SolutionProperties) = preSolution Release|x86 = Release|x86
HideSolutionNode = FALSE
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{8AD551DA-AFB7-4C2A-BB33-9418E38659BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8AD551DA-AFB7-4C2A-BB33-9418E38659BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8AD551DA-AFB7-4C2A-BB33-9418E38659BC}.Debug|Any CPU.Build.0 = Debug|Any CPU {8AD551DA-AFB7-4C2A-BB33-9418E38659BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8AD551DA-AFB7-4C2A-BB33-9418E38659BC}.Debug|x64.ActiveCfg = Debug|Any CPU
{8AD551DA-AFB7-4C2A-BB33-9418E38659BC}.Debug|x64.Build.0 = Debug|Any CPU
{8AD551DA-AFB7-4C2A-BB33-9418E38659BC}.Debug|x86.ActiveCfg = Debug|Any CPU
{8AD551DA-AFB7-4C2A-BB33-9418E38659BC}.Debug|x86.Build.0 = Debug|Any CPU
{8AD551DA-AFB7-4C2A-BB33-9418E38659BC}.Release|Any CPU.ActiveCfg = Release|Any CPU {8AD551DA-AFB7-4C2A-BB33-9418E38659BC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8AD551DA-AFB7-4C2A-BB33-9418E38659BC}.Release|Any CPU.Build.0 = Release|Any CPU {8AD551DA-AFB7-4C2A-BB33-9418E38659BC}.Release|Any CPU.Build.0 = Release|Any CPU
{8AD551DA-AFB7-4C2A-BB33-9418E38659BC}.Release|x64.ActiveCfg = Release|Any CPU
{8AD551DA-AFB7-4C2A-BB33-9418E38659BC}.Release|x64.Build.0 = Release|Any CPU
{8AD551DA-AFB7-4C2A-BB33-9418E38659BC}.Release|x86.ActiveCfg = Release|Any CPU
{8AD551DA-AFB7-4C2A-BB33-9418E38659BC}.Release|x86.Build.0 = Release|Any CPU
{4F852616-39EE-4075-B6F9-BE1E2DDB877B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {4F852616-39EE-4075-B6F9-BE1E2DDB877B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4F852616-39EE-4075-B6F9-BE1E2DDB877B}.Debug|Any CPU.Build.0 = Debug|Any CPU {4F852616-39EE-4075-B6F9-BE1E2DDB877B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4F852616-39EE-4075-B6F9-BE1E2DDB877B}.Debug|x64.ActiveCfg = Debug|Any CPU
{4F852616-39EE-4075-B6F9-BE1E2DDB877B}.Debug|x64.Build.0 = Debug|Any CPU
{4F852616-39EE-4075-B6F9-BE1E2DDB877B}.Debug|x86.ActiveCfg = Debug|Any CPU
{4F852616-39EE-4075-B6F9-BE1E2DDB877B}.Debug|x86.Build.0 = Debug|Any CPU
{4F852616-39EE-4075-B6F9-BE1E2DDB877B}.Release|Any CPU.ActiveCfg = Release|Any CPU {4F852616-39EE-4075-B6F9-BE1E2DDB877B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4F852616-39EE-4075-B6F9-BE1E2DDB877B}.Release|Any CPU.Build.0 = Release|Any CPU {4F852616-39EE-4075-B6F9-BE1E2DDB877B}.Release|Any CPU.Build.0 = Release|Any CPU
{4F852616-39EE-4075-B6F9-BE1E2DDB877B}.Release|x64.ActiveCfg = Release|Any CPU
{4F852616-39EE-4075-B6F9-BE1E2DDB877B}.Release|x64.Build.0 = Release|Any CPU
{4F852616-39EE-4075-B6F9-BE1E2DDB877B}.Release|x86.ActiveCfg = Release|Any CPU
{4F852616-39EE-4075-B6F9-BE1E2DDB877B}.Release|x86.Build.0 = Release|Any CPU
{88142EC2-FEB2-4D69-AD3A-74F3364360F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {88142EC2-FEB2-4D69-AD3A-74F3364360F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{88142EC2-FEB2-4D69-AD3A-74F3364360F0}.Debug|Any CPU.Build.0 = Debug|Any CPU {88142EC2-FEB2-4D69-AD3A-74F3364360F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{88142EC2-FEB2-4D69-AD3A-74F3364360F0}.Debug|x64.ActiveCfg = Debug|Any CPU
{88142EC2-FEB2-4D69-AD3A-74F3364360F0}.Debug|x64.Build.0 = Debug|Any CPU
{88142EC2-FEB2-4D69-AD3A-74F3364360F0}.Debug|x86.ActiveCfg = Debug|Any CPU
{88142EC2-FEB2-4D69-AD3A-74F3364360F0}.Debug|x86.Build.0 = Debug|Any CPU
{88142EC2-FEB2-4D69-AD3A-74F3364360F0}.Release|Any CPU.ActiveCfg = Release|Any CPU {88142EC2-FEB2-4D69-AD3A-74F3364360F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{88142EC2-FEB2-4D69-AD3A-74F3364360F0}.Release|Any CPU.Build.0 = Release|Any CPU {88142EC2-FEB2-4D69-AD3A-74F3364360F0}.Release|Any CPU.Build.0 = Release|Any CPU
{88142EC2-FEB2-4D69-AD3A-74F3364360F0}.Release|x64.ActiveCfg = Release|Any CPU
{88142EC2-FEB2-4D69-AD3A-74F3364360F0}.Release|x64.Build.0 = Release|Any CPU
{88142EC2-FEB2-4D69-AD3A-74F3364360F0}.Release|x86.ActiveCfg = Release|Any CPU
{88142EC2-FEB2-4D69-AD3A-74F3364360F0}.Release|x86.Build.0 = Release|Any CPU
{1F594222-C5CB-4D4A-94A1-C5AEB4990B59}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1F594222-C5CB-4D4A-94A1-C5AEB4990B59}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1F594222-C5CB-4D4A-94A1-C5AEB4990B59}.Debug|Any CPU.Build.0 = Debug|Any CPU {1F594222-C5CB-4D4A-94A1-C5AEB4990B59}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1F594222-C5CB-4D4A-94A1-C5AEB4990B59}.Debug|x64.ActiveCfg = Debug|Any CPU
{1F594222-C5CB-4D4A-94A1-C5AEB4990B59}.Debug|x64.Build.0 = Debug|Any CPU
{1F594222-C5CB-4D4A-94A1-C5AEB4990B59}.Debug|x86.ActiveCfg = Debug|Any CPU
{1F594222-C5CB-4D4A-94A1-C5AEB4990B59}.Debug|x86.Build.0 = Debug|Any CPU
{1F594222-C5CB-4D4A-94A1-C5AEB4990B59}.Release|Any CPU.ActiveCfg = Release|Any CPU {1F594222-C5CB-4D4A-94A1-C5AEB4990B59}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1F594222-C5CB-4D4A-94A1-C5AEB4990B59}.Release|Any CPU.Build.0 = Release|Any CPU {1F594222-C5CB-4D4A-94A1-C5AEB4990B59}.Release|Any CPU.Build.0 = Release|Any CPU
{1F594222-C5CB-4D4A-94A1-C5AEB4990B59}.Release|x64.ActiveCfg = Release|Any CPU
{1F594222-C5CB-4D4A-94A1-C5AEB4990B59}.Release|x64.Build.0 = Release|Any CPU
{1F594222-C5CB-4D4A-94A1-C5AEB4990B59}.Release|x86.ActiveCfg = Release|Any CPU
{1F594222-C5CB-4D4A-94A1-C5AEB4990B59}.Release|x86.Build.0 = Release|Any CPU
{95DAD2B5-4324-4E89-A337-5703E45CFBE8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {95DAD2B5-4324-4E89-A337-5703E45CFBE8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{95DAD2B5-4324-4E89-A337-5703E45CFBE8}.Debug|Any CPU.Build.0 = Debug|Any CPU {95DAD2B5-4324-4E89-A337-5703E45CFBE8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{95DAD2B5-4324-4E89-A337-5703E45CFBE8}.Debug|x64.ActiveCfg = Debug|Any CPU
{95DAD2B5-4324-4E89-A337-5703E45CFBE8}.Debug|x64.Build.0 = Debug|Any CPU
{95DAD2B5-4324-4E89-A337-5703E45CFBE8}.Debug|x86.ActiveCfg = Debug|Any CPU
{95DAD2B5-4324-4E89-A337-5703E45CFBE8}.Debug|x86.Build.0 = Debug|Any CPU
{95DAD2B5-4324-4E89-A337-5703E45CFBE8}.Release|Any CPU.ActiveCfg = Release|Any CPU {95DAD2B5-4324-4E89-A337-5703E45CFBE8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{95DAD2B5-4324-4E89-A337-5703E45CFBE8}.Release|Any CPU.Build.0 = Release|Any CPU {95DAD2B5-4324-4E89-A337-5703E45CFBE8}.Release|Any CPU.Build.0 = Release|Any CPU
{95DAD2B5-4324-4E89-A337-5703E45CFBE8}.Release|x64.ActiveCfg = Release|Any CPU
{95DAD2B5-4324-4E89-A337-5703E45CFBE8}.Release|x64.Build.0 = Release|Any CPU
{95DAD2B5-4324-4E89-A337-5703E45CFBE8}.Release|x86.ActiveCfg = Release|Any CPU
{95DAD2B5-4324-4E89-A337-5703E45CFBE8}.Release|x86.Build.0 = Release|Any CPU
{27DA6CEC-4266-4F78-BB32-8388F9A401D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {27DA6CEC-4266-4F78-BB32-8388F9A401D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{27DA6CEC-4266-4F78-BB32-8388F9A401D0}.Debug|Any CPU.Build.0 = Debug|Any CPU {27DA6CEC-4266-4F78-BB32-8388F9A401D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{27DA6CEC-4266-4F78-BB32-8388F9A401D0}.Debug|x64.ActiveCfg = Debug|Any CPU
{27DA6CEC-4266-4F78-BB32-8388F9A401D0}.Debug|x64.Build.0 = Debug|Any CPU
{27DA6CEC-4266-4F78-BB32-8388F9A401D0}.Debug|x86.ActiveCfg = Debug|Any CPU
{27DA6CEC-4266-4F78-BB32-8388F9A401D0}.Debug|x86.Build.0 = Debug|Any CPU
{27DA6CEC-4266-4F78-BB32-8388F9A401D0}.Release|Any CPU.ActiveCfg = Release|Any CPU {27DA6CEC-4266-4F78-BB32-8388F9A401D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{27DA6CEC-4266-4F78-BB32-8388F9A401D0}.Release|Any CPU.Build.0 = Release|Any CPU {27DA6CEC-4266-4F78-BB32-8388F9A401D0}.Release|Any CPU.Build.0 = Release|Any CPU
{27DA6CEC-4266-4F78-BB32-8388F9A401D0}.Release|x64.ActiveCfg = Release|Any CPU
{27DA6CEC-4266-4F78-BB32-8388F9A401D0}.Release|x64.Build.0 = Release|Any CPU
{27DA6CEC-4266-4F78-BB32-8388F9A401D0}.Release|x86.ActiveCfg = Release|Any CPU
{27DA6CEC-4266-4F78-BB32-8388F9A401D0}.Release|x86.Build.0 = Release|Any CPU
{CDCF676A-2037-472E-8C8B-67C5E4FDFEA1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {CDCF676A-2037-472E-8C8B-67C5E4FDFEA1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CDCF676A-2037-472E-8C8B-67C5E4FDFEA1}.Debug|Any CPU.Build.0 = Debug|Any CPU {CDCF676A-2037-472E-8C8B-67C5E4FDFEA1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CDCF676A-2037-472E-8C8B-67C5E4FDFEA1}.Debug|x64.ActiveCfg = Debug|Any CPU
{CDCF676A-2037-472E-8C8B-67C5E4FDFEA1}.Debug|x64.Build.0 = Debug|Any CPU
{CDCF676A-2037-472E-8C8B-67C5E4FDFEA1}.Debug|x86.ActiveCfg = Debug|Any CPU
{CDCF676A-2037-472E-8C8B-67C5E4FDFEA1}.Debug|x86.Build.0 = Debug|Any CPU
{CDCF676A-2037-472E-8C8B-67C5E4FDFEA1}.Release|Any CPU.ActiveCfg = Release|Any CPU {CDCF676A-2037-472E-8C8B-67C5E4FDFEA1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CDCF676A-2037-472E-8C8B-67C5E4FDFEA1}.Release|Any CPU.Build.0 = Release|Any CPU {CDCF676A-2037-472E-8C8B-67C5E4FDFEA1}.Release|Any CPU.Build.0 = Release|Any CPU
{CDCF676A-2037-472E-8C8B-67C5E4FDFEA1}.Release|x64.ActiveCfg = Release|Any CPU
{CDCF676A-2037-472E-8C8B-67C5E4FDFEA1}.Release|x64.Build.0 = Release|Any CPU
{CDCF676A-2037-472E-8C8B-67C5E4FDFEA1}.Release|x86.ActiveCfg = Release|Any CPU
{CDCF676A-2037-472E-8C8B-67C5E4FDFEA1}.Release|x86.Build.0 = Release|Any CPU
{5D9E161F-3CB3-4854-9D07-3DF6882EA66C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {5D9E161F-3CB3-4854-9D07-3DF6882EA66C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5D9E161F-3CB3-4854-9D07-3DF6882EA66C}.Debug|Any CPU.Build.0 = Debug|Any CPU {5D9E161F-3CB3-4854-9D07-3DF6882EA66C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5D9E161F-3CB3-4854-9D07-3DF6882EA66C}.Debug|x64.ActiveCfg = Debug|Any CPU
{5D9E161F-3CB3-4854-9D07-3DF6882EA66C}.Debug|x64.Build.0 = Debug|Any CPU
{5D9E161F-3CB3-4854-9D07-3DF6882EA66C}.Debug|x86.ActiveCfg = Debug|Any CPU
{5D9E161F-3CB3-4854-9D07-3DF6882EA66C}.Debug|x86.Build.0 = Debug|Any CPU
{5D9E161F-3CB3-4854-9D07-3DF6882EA66C}.Release|Any CPU.ActiveCfg = Release|Any CPU {5D9E161F-3CB3-4854-9D07-3DF6882EA66C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5D9E161F-3CB3-4854-9D07-3DF6882EA66C}.Release|Any CPU.Build.0 = Release|Any CPU {5D9E161F-3CB3-4854-9D07-3DF6882EA66C}.Release|Any CPU.Build.0 = Release|Any CPU
{5D9E161F-3CB3-4854-9D07-3DF6882EA66C}.Release|x64.ActiveCfg = Release|Any CPU
{5D9E161F-3CB3-4854-9D07-3DF6882EA66C}.Release|x64.Build.0 = Release|Any CPU
{5D9E161F-3CB3-4854-9D07-3DF6882EA66C}.Release|x86.ActiveCfg = Release|Any CPU
{5D9E161F-3CB3-4854-9D07-3DF6882EA66C}.Release|x86.Build.0 = Release|Any CPU
{342F9C7A-C72A-47F6-A2A7-442A524D10CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{342F9C7A-C72A-47F6-A2A7-442A524D10CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{342F9C7A-C72A-47F6-A2A7-442A524D10CE}.Debug|x64.ActiveCfg = Debug|Any CPU
{342F9C7A-C72A-47F6-A2A7-442A524D10CE}.Debug|x64.Build.0 = Debug|Any CPU
{342F9C7A-C72A-47F6-A2A7-442A524D10CE}.Debug|x86.ActiveCfg = Debug|Any CPU
{342F9C7A-C72A-47F6-A2A7-442A524D10CE}.Debug|x86.Build.0 = Debug|Any CPU
{342F9C7A-C72A-47F6-A2A7-442A524D10CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{342F9C7A-C72A-47F6-A2A7-442A524D10CE}.Release|Any CPU.Build.0 = Release|Any CPU
{342F9C7A-C72A-47F6-A2A7-442A524D10CE}.Release|x64.ActiveCfg = Release|Any CPU
{342F9C7A-C72A-47F6-A2A7-442A524D10CE}.Release|x64.Build.0 = Release|Any CPU
{342F9C7A-C72A-47F6-A2A7-442A524D10CE}.Release|x86.ActiveCfg = Release|Any CPU
{342F9C7A-C72A-47F6-A2A7-442A524D10CE}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection EndGlobalSection
GlobalSection(NestedProjects) = preSolution GlobalSection(NestedProjects) = preSolution
{8AD551DA-AFB7-4C2A-BB33-9418E38659BC} = {CDB1BDB5-53F9-4B43-864F-60F2E74F44E2} {8AD551DA-AFB7-4C2A-BB33-9418E38659BC} = {CDB1BDB5-53F9-4B43-864F-60F2E74F44E2}
@ -74,5 +156,6 @@ Global
{27DA6CEC-4266-4F78-BB32-8388F9A401D0} = {CDB1BDB5-53F9-4B43-864F-60F2E74F44E2} {27DA6CEC-4266-4F78-BB32-8388F9A401D0} = {CDB1BDB5-53F9-4B43-864F-60F2E74F44E2}
{CDCF676A-2037-472E-8C8B-67C5E4FDFEA1} = {76A7FBA6-B7EC-4864-85C0-1F470794BA0F} {CDCF676A-2037-472E-8C8B-67C5E4FDFEA1} = {76A7FBA6-B7EC-4864-85C0-1F470794BA0F}
{5D9E161F-3CB3-4854-9D07-3DF6882EA66C} = {CDB1BDB5-53F9-4B43-864F-60F2E74F44E2} {5D9E161F-3CB3-4854-9D07-3DF6882EA66C} = {CDB1BDB5-53F9-4B43-864F-60F2E74F44E2}
{342F9C7A-C72A-47F6-A2A7-442A524D10CE} = {CDB1BDB5-53F9-4B43-864F-60F2E74F44E2}
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal