♻️ Better file upload error
This commit is contained in:
@@ -33,6 +33,8 @@ var developService = builder.AddProject<Projects.DysonNetwork_Develop>("develop"
|
|||||||
.WithReference(ringService)
|
.WithReference(ringService)
|
||||||
.WithReference(sphereService);
|
.WithReference(sphereService);
|
||||||
|
|
||||||
|
passService.WithReference(developService).WithReference(driveService);
|
||||||
|
|
||||||
List<IResourceBuilder<ProjectResource>> services =
|
List<IResourceBuilder<ProjectResource>> services =
|
||||||
[ringService, passService, driveService, sphereService, developService];
|
[ringService, passService, driveService, sphereService, developService];
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<Sdk Name="Aspire.AppHost.Sdk" Version="9.4.2"/>
|
<Sdk Name="Aspire.AppHost.Sdk" Version="9.5.0"/>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
@@ -12,10 +12,10 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Aspire.Hosting.AppHost" Version="9.4.2"/>
|
<PackageReference Include="Aspire.Hosting.AppHost" Version="9.5.0" />
|
||||||
<PackageReference Include="Aspire.Hosting.Docker" Version="9.4.2-preview.1.25428.12" />
|
<PackageReference Include="Aspire.Hosting.Docker" Version="9.4.2-preview.1.25428.12" />
|
||||||
<PackageReference Include="Aspire.Hosting.Nats" Version="9.4.2" />
|
<PackageReference Include="Aspire.Hosting.Nats" Version="9.5.0" />
|
||||||
<PackageReference Include="Aspire.Hosting.Redis" Version="9.4.2" />
|
<PackageReference Include="Aspire.Hosting.Redis" Version="9.5.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@@ -3,6 +3,7 @@ using System.Text.Json;
|
|||||||
using DysonNetwork.Drive.Billing;
|
using DysonNetwork.Drive.Billing;
|
||||||
using DysonNetwork.Drive.Storage.Model;
|
using DysonNetwork.Drive.Storage.Model;
|
||||||
using DysonNetwork.Shared.Auth;
|
using DysonNetwork.Shared.Auth;
|
||||||
|
using DysonNetwork.Shared.Http;
|
||||||
using DysonNetwork.Shared.Proto;
|
using DysonNetwork.Shared.Proto;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
@@ -31,15 +32,18 @@ public class FileUploadController(
|
|||||||
[HttpPost("create")]
|
[HttpPost("create")]
|
||||||
public async Task<IActionResult> CreateUploadTask([FromBody] CreateUploadTaskRequest request)
|
public async Task<IActionResult> CreateUploadTask([FromBody] CreateUploadTaskRequest request)
|
||||||
{
|
{
|
||||||
if (HttpContext.Items["CurrentUser"] is not Account currentUser) return Unauthorized();
|
if (HttpContext.Items["CurrentUser"] is not Account currentUser)
|
||||||
|
{
|
||||||
|
return new ObjectResult(ApiError.Unauthorized()) { StatusCode = 401 };
|
||||||
|
}
|
||||||
|
|
||||||
if (!currentUser.IsSuperuser)
|
if (!currentUser.IsSuperuser)
|
||||||
{
|
{
|
||||||
var allowed = await permission.HasPermissionAsync(new HasPermissionRequest
|
var allowed = await permission.HasPermissionAsync(new HasPermissionRequest
|
||||||
{ Actor = $"user:{currentUser.Id}", Area = "global", Key = "files.create" });
|
{ Actor = $"user:{currentUser.Id}", Area = "global", Key = "files.create" });
|
||||||
if (!allowed.HasPermission)
|
if (!allowed.HasPermission)
|
||||||
{
|
{
|
||||||
return Forbid();
|
return new ObjectResult(ApiError.Unauthorized(forbidden: true)) { StatusCode = 403 };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,23 +52,19 @@ public class FileUploadController(
|
|||||||
var pool = await fileService.GetPoolAsync(request.PoolId.Value);
|
var pool = await fileService.GetPoolAsync(request.PoolId.Value);
|
||||||
if (pool is null)
|
if (pool is null)
|
||||||
{
|
{
|
||||||
return BadRequest("Pool not found");
|
return new ObjectResult(ApiError.NotFound("Pool")) { StatusCode = 404 };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pool.PolicyConfig.RequirePrivilege > 0)
|
if (pool.PolicyConfig.RequirePrivilege is > 0)
|
||||||
{
|
{
|
||||||
if (currentUser.PerkSubscription is null)
|
|
||||||
{
|
|
||||||
return new ObjectResult("You need to have join the Stellar Program to use this pool")
|
|
||||||
{ StatusCode = 403 };
|
|
||||||
}
|
|
||||||
|
|
||||||
var privilege =
|
var privilege =
|
||||||
|
currentUser.PerkSubscription is null ? 0 :
|
||||||
PerkSubscriptionPrivilege.GetPrivilegeFromIdentifier(currentUser.PerkSubscription.Identifier);
|
PerkSubscriptionPrivilege.GetPrivilegeFromIdentifier(currentUser.PerkSubscription.Identifier);
|
||||||
if (privilege < pool.PolicyConfig.RequirePrivilege)
|
if (privilege < pool.PolicyConfig.RequirePrivilege)
|
||||||
{
|
{
|
||||||
return new ObjectResult(
|
return new ObjectResult(ApiError.Unauthorized(
|
||||||
$"You need Stellar Program tier {pool.PolicyConfig.RequirePrivilege} to use this pool, you are tier {privilege}")
|
$"You need Stellar Program tier {pool.PolicyConfig.RequirePrivilege} to use pool {pool.Name}, you are tier {privilege}",
|
||||||
|
forbidden: true))
|
||||||
{
|
{
|
||||||
StatusCode = 403
|
StatusCode = 403
|
||||||
};
|
};
|
||||||
@@ -74,14 +74,19 @@ public class FileUploadController(
|
|||||||
var policy = pool.PolicyConfig;
|
var policy = pool.PolicyConfig;
|
||||||
if (!policy.AllowEncryption && !string.IsNullOrEmpty(request.EncryptPassword))
|
if (!policy.AllowEncryption && !string.IsNullOrEmpty(request.EncryptPassword))
|
||||||
{
|
{
|
||||||
return new ObjectResult("File encryption is not allowed in this pool") { StatusCode = 403 };
|
return new ObjectResult(ApiError.Unauthorized("File encryption is not allowed in this pool", true))
|
||||||
|
{ StatusCode = 403 };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (policy.AcceptTypes is { Count: > 0 })
|
if (policy.AcceptTypes is { Count: > 0 })
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(request.ContentType))
|
if (string.IsNullOrEmpty(request.ContentType))
|
||||||
{
|
{
|
||||||
return BadRequest("Content type is required by the pool's policy");
|
return new ObjectResult(ApiError.Validation(new Dictionary<string, string[]>
|
||||||
|
{
|
||||||
|
{ "contentType", new[] { "Content type is required by the pool's policy" } }
|
||||||
|
}))
|
||||||
|
{ StatusCode = 400 };
|
||||||
}
|
}
|
||||||
|
|
||||||
var foundMatch = policy.AcceptTypes.Any(acceptType =>
|
var foundMatch = policy.AcceptTypes.Any(acceptType =>
|
||||||
@@ -97,15 +102,18 @@ public class FileUploadController(
|
|||||||
|
|
||||||
if (!foundMatch)
|
if (!foundMatch)
|
||||||
{
|
{
|
||||||
return new ObjectResult($"Content type {request.ContentType} is not allowed by the pool's policy")
|
return new ObjectResult(
|
||||||
{ StatusCode = 403 };
|
ApiError.Unauthorized($"Content type {request.ContentType} is not allowed by the pool's policy",
|
||||||
|
true))
|
||||||
|
{ StatusCode = 403 };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (policy.MaxFileSize is not null && request.FileSize > policy.MaxFileSize)
|
if (policy.MaxFileSize is not null && request.FileSize > policy.MaxFileSize)
|
||||||
{
|
{
|
||||||
return new ObjectResult(
|
return new ObjectResult(ApiError.Unauthorized(
|
||||||
$"File size {request.FileSize} is larger than the pool's maximum file size {policy.MaxFileSize}")
|
$"File size {request.FileSize} is larger than the pool's maximum file size {policy.MaxFileSize}",
|
||||||
|
true))
|
||||||
{
|
{
|
||||||
StatusCode = 403
|
StatusCode = 403
|
||||||
};
|
};
|
||||||
@@ -118,8 +126,10 @@ public class FileUploadController(
|
|||||||
);
|
);
|
||||||
if (!ok)
|
if (!ok)
|
||||||
{
|
{
|
||||||
return new ObjectResult($"File size {billableUnit} MiB is exceeded the user's quota {quota} MiB")
|
return new ObjectResult(
|
||||||
{ StatusCode = 403 };
|
ApiError.Unauthorized($"File size {billableUnit} MiB is exceeded the user's quota {quota} MiB",
|
||||||
|
true))
|
||||||
|
{ StatusCode = 403 };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Directory.Exists(_tempPath))
|
if (!Directory.Exists(_tempPath))
|
||||||
@@ -186,7 +196,7 @@ public class FileUploadController(
|
|||||||
var taskPath = Path.Combine(_tempPath, taskId);
|
var taskPath = Path.Combine(_tempPath, taskId);
|
||||||
if (!Directory.Exists(taskPath))
|
if (!Directory.Exists(taskPath))
|
||||||
{
|
{
|
||||||
return NotFound("Upload task not found.");
|
return new ObjectResult(ApiError.NotFound("Upload task")) { StatusCode = 404 };
|
||||||
}
|
}
|
||||||
|
|
||||||
var chunkPath = Path.Combine(taskPath, $"{chunkIndex}.chunk");
|
var chunkPath = Path.Combine(taskPath, $"{chunkIndex}.chunk");
|
||||||
@@ -202,19 +212,20 @@ public class FileUploadController(
|
|||||||
var taskPath = Path.Combine(_tempPath, taskId);
|
var taskPath = Path.Combine(_tempPath, taskId);
|
||||||
if (!Directory.Exists(taskPath))
|
if (!Directory.Exists(taskPath))
|
||||||
{
|
{
|
||||||
return NotFound("Upload task not found.");
|
return new ObjectResult(ApiError.NotFound("Upload task")) { StatusCode = 404 };
|
||||||
}
|
}
|
||||||
|
|
||||||
var taskJsonPath = Path.Combine(taskPath, "task.json");
|
var taskJsonPath = Path.Combine(taskPath, "task.json");
|
||||||
if (!System.IO.File.Exists(taskJsonPath))
|
if (!System.IO.File.Exists(taskJsonPath))
|
||||||
{
|
{
|
||||||
return NotFound("Upload task metadata not found.");
|
return new ObjectResult(ApiError.NotFound("Upload task metadata")) { StatusCode = 404 };
|
||||||
}
|
}
|
||||||
|
|
||||||
var task = JsonSerializer.Deserialize<UploadTask>(await System.IO.File.ReadAllTextAsync(taskJsonPath));
|
var task = JsonSerializer.Deserialize<UploadTask>(await System.IO.File.ReadAllTextAsync(taskJsonPath));
|
||||||
if (task == null)
|
if (task == null)
|
||||||
{
|
{
|
||||||
return BadRequest("Invalid task metadata.");
|
return new ObjectResult(new ApiError { Code = "BAD_REQUEST", Message = "Invalid task metadata.", Status = 400 })
|
||||||
|
{ StatusCode = 400 };
|
||||||
}
|
}
|
||||||
|
|
||||||
var mergedFilePath = Path.Combine(_tempPath, taskId + ".tmp");
|
var mergedFilePath = Path.Combine(_tempPath, taskId + ".tmp");
|
||||||
@@ -229,7 +240,9 @@ public class FileUploadController(
|
|||||||
mergedStream.Close();
|
mergedStream.Close();
|
||||||
System.IO.File.Delete(mergedFilePath);
|
System.IO.File.Delete(mergedFilePath);
|
||||||
Directory.Delete(taskPath, true);
|
Directory.Delete(taskPath, true);
|
||||||
return BadRequest($"Chunk {i} is missing.");
|
return new ObjectResult(new ApiError
|
||||||
|
{ Code = "CHUNK_MISSING", Message = $"Chunk {i} is missing.", Status = 400 })
|
||||||
|
{ StatusCode = 400 };
|
||||||
}
|
}
|
||||||
|
|
||||||
await using var chunkStream = new FileStream(chunkPath, FileMode.Open);
|
await using var chunkStream = new FileStream(chunkPath, FileMode.Open);
|
||||||
@@ -237,21 +250,24 @@ public class FileUploadController(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HttpContext.Items["CurrentUser"] is not Account currentUser) return Unauthorized();
|
if (HttpContext.Items["CurrentUser"] is not Account currentUser)
|
||||||
|
{
|
||||||
|
return new ObjectResult(ApiError.Unauthorized()) { StatusCode = 401 };
|
||||||
|
}
|
||||||
|
|
||||||
var fileId = await Nanoid.GenerateAsync();
|
var fileId = await Nanoid.GenerateAsync();
|
||||||
|
|
||||||
var cloudFile = await fileService.ProcessNewFileAsync(
|
var cloudFile = await fileService.ProcessNewFileAsync(
|
||||||
currentUser,
|
currentUser,
|
||||||
fileId,
|
fileId,
|
||||||
task.PoolId.ToString(),
|
task.PoolId.ToString(),
|
||||||
task.BundleId?.ToString(),
|
task.BundleId?.ToString(),
|
||||||
mergedFilePath,
|
mergedFilePath,
|
||||||
task.FileName,
|
task.FileName,
|
||||||
task.ContentType,
|
task.ContentType,
|
||||||
task.EncryptPassword,
|
task.EncryptPassword,
|
||||||
task.ExpiredAt
|
task.ExpiredAt
|
||||||
);
|
);
|
||||||
|
|
||||||
// Clean up
|
// Clean up
|
||||||
Directory.Delete(taskPath, true);
|
Directory.Delete(taskPath, true);
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"Debug": true,
|
"Debug": true,
|
||||||
"BaseUrl": "http://localhost:5216",
|
"BaseUrl": "http://localhost:5001",
|
||||||
"SiteUrl": "https://id.solian.app",
|
"SiteUrl": "http://localhost:3000",
|
||||||
"Logging": {
|
"Logging": {
|
||||||
"LogLevel": {
|
"LogLevel": {
|
||||||
"Default": "Information",
|
"Default": "Information",
|
||||||
@@ -15,10 +15,7 @@
|
|||||||
"Authentication": {
|
"Authentication": {
|
||||||
"Schemes": {
|
"Schemes": {
|
||||||
"Bearer": {
|
"Bearer": {
|
||||||
"ValidAudiences": [
|
"ValidAudiences": ["http://localhost:5071", "https://localhost:7099"],
|
||||||
"http://localhost:5071",
|
|
||||||
"https://localhost:7099"
|
|
||||||
],
|
|
||||||
"ValidIssuer": "solar-network"
|
"ValidIssuer": "solar-network"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -74,10 +71,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"KnownProxies": [
|
"KnownProxies": ["127.0.0.1", "::1"],
|
||||||
"127.0.0.1",
|
|
||||||
"::1"
|
|
||||||
],
|
|
||||||
"Service": {
|
"Service": {
|
||||||
"Name": "DysonNetwork.Pass",
|
"Name": "DysonNetwork.Pass",
|
||||||
"Url": "https://localhost:7058"
|
"Url": "https://localhost:7058"
|
||||||
|
@@ -316,9 +316,9 @@ public class CacheServiceRedis : ICacheService
|
|||||||
public async Task<IEnumerable<string>> GetGroupKeysAsync(string group)
|
public async Task<IEnumerable<string>> GetGroupKeysAsync(string group)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(group))
|
if (string.IsNullOrEmpty(group))
|
||||||
throw new ArgumentException(@"Group cannot be null or empty.", nameof(group));
|
throw new ArgumentException("Group cannot be null or empty.", nameof(group));
|
||||||
|
|
||||||
var groupKey = $"{GroupKeyPrefix}{group}";
|
var groupKey = string.Concat(GroupKeyPrefix, group);
|
||||||
var members = await _database.SetMembersAsync(groupKey);
|
var members = await _database.SetMembersAsync(groupKey);
|
||||||
|
|
||||||
return members.Select(m => m.ToString());
|
return members.Select(m => m.ToString());
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="BCrypt.Net-Next" Version="4.0.3" />
|
<PackageReference Include="BCrypt.Net-Next" Version="4.0.3" />
|
||||||
<PackageReference Include="Google.Api.CommonProtos" Version="2.17.0" />
|
<PackageReference Include="Google.Api.CommonProtos" Version="2.17.0" />
|
||||||
<PackageReference Include="Google.Protobuf" Version="3.31.1" />
|
<PackageReference Include="Google.Protobuf" Version="3.32.1" />
|
||||||
<PackageReference Include="Google.Protobuf.Tools" Version="3.31.1" />
|
<PackageReference Include="Google.Protobuf.Tools" Version="3.31.1" />
|
||||||
<PackageReference Include="Grpc" Version="2.46.6" />
|
<PackageReference Include="Grpc" Version="2.46.6" />
|
||||||
<PackageReference Include="Grpc.AspNetCore.Server.ClientFactory" Version="2.71.0" />
|
<PackageReference Include="Grpc.AspNetCore.Server.ClientFactory" Version="2.71.0" />
|
||||||
|
@@ -35,7 +35,7 @@ public class PolicyConfig
|
|||||||
public bool AllowAnonymous { get; set; } = true;
|
public bool AllowAnonymous { get; set; } = true;
|
||||||
public List<string>? AcceptTypes { get; set; }
|
public List<string>? AcceptTypes { get; set; }
|
||||||
public long? MaxFileSize { get; set; }
|
public long? MaxFileSize { get; set; }
|
||||||
public int RequirePrivilege { get; set; } = 0;
|
public int? RequirePrivilege { get; set; } = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class FilePool : ModelBase, IIdentifiedResource
|
public class FilePool : ModelBase, IIdentifiedResource
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
<PackageReference Include="EFCore.BulkExtensions.PostgreSql" Version="9.0.1"/>
|
<PackageReference Include="EFCore.BulkExtensions.PostgreSql" Version="9.0.1"/>
|
||||||
<PackageReference Include="EFCore.NamingConventions" Version="9.0.0"/>
|
<PackageReference Include="EFCore.NamingConventions" Version="9.0.0"/>
|
||||||
<PackageReference Include="Grpc.AspNetCore.Server" Version="2.71.0"/>
|
<PackageReference Include="Grpc.AspNetCore.Server" Version="2.71.0"/>
|
||||||
<PackageReference Include="HtmlAgilityPack" Version="1.12.1"/>
|
<PackageReference Include="HtmlAgilityPack" Version="1.12.3" />
|
||||||
<PackageReference Include="Livekit.Server.Sdk.Dotnet" Version="1.0.10" />
|
<PackageReference Include="Livekit.Server.Sdk.Dotnet" Version="1.0.10" />
|
||||||
<PackageReference Include="Markdig" Version="0.41.3"/>
|
<PackageReference Include="Markdig" Version="0.41.3"/>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.7"/>
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.7"/>
|
||||||
|
@@ -71,6 +71,7 @@
|
|||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AHttpUtility_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F95cd5fa21c574d4087dec626d8227d77be00_003F08_003Fdd41228e_003FHttpUtility_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AHttpUtility_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F95cd5fa21c574d4087dec626d8227d77be00_003F08_003Fdd41228e_003FHttpUtility_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIConfiguration_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fbb55221b2bd14b31a20b0d8bdcc7ff457328_003F19_003F707d23be_003FIConfiguration_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIConfiguration_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fbb55221b2bd14b31a20b0d8bdcc7ff457328_003F19_003F707d23be_003FIConfiguration_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIConnectionMultiplexer_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FSourcesCache_003Ffd5f2a75d480e8c786b15cfa0ac11aa9bf445a667ad13d25dc9db61f2cb1b_003FIConnectionMultiplexer_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIConnectionMultiplexer_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FSourcesCache_003Ffd5f2a75d480e8c786b15cfa0ac11aa9bf445a667ad13d25dc9db61f2cb1b_003FIConnectionMultiplexer_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIDatabaseAsync_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FSourcesCache_003F93b441a9e8201c5bdfa1b1fdc8061a77b86ccbb8566d7bae85036aba8c618f7_003FIDatabaseAsync_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIEtcdClient_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F866376757aa64634b820c41d3553727886400_003Fbb_003F0fd3f8d7_003FIEtcdClient_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIEtcdClient_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F866376757aa64634b820c41d3553727886400_003Fbb_003F0fd3f8d7_003FIEtcdClient_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIHtmlString_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F95cd5fa21c574d4087dec626d8227d77be00_003Ff1_003F3a8957fa_003FIHtmlString_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIHtmlString_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F95cd5fa21c574d4087dec626d8227d77be00_003Ff1_003F3a8957fa_003FIHtmlString_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIHttpForwarder_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fbf3f51607a3e4e76b5b91640cd7409195c430_003F29_003F7eee2eb9_003FIHttpForwarder_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIHttpForwarder_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fbf3f51607a3e4e76b5b91640cd7409195c430_003F29_003F7eee2eb9_003FIHttpForwarder_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"Debug": true,
|
"Debug": true,
|
||||||
"BaseUrl": "http://localhost:5216",
|
"BaseUrl": "http://localhost:5001",
|
||||||
"SiteUrl": "https://id.solian.app",
|
"SiteUrl": "http://localhost:3000",
|
||||||
"Logging": {
|
"Logging": {
|
||||||
"LogLevel": {
|
"LogLevel": {
|
||||||
"Default": "Information",
|
"Default": "Information",
|
||||||
|
Reference in New Issue
Block a user