Compare commits

..

No commits in common. "2e48b0067f0dec2d1f7afbbf2e83596131ba0c7b" and "332e5a013b4fc1b99f0651aa7330113710417997" have entirely different histories.

42 changed files with 175 additions and 169 deletions

View File

@ -0,0 +1,23 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace Mirea.Api.Dto.Responses;
/// <summary>
/// Provides a JWT and RT token.
/// </summary>
public class TokenResponse
{
/// <summary>
/// A JWT token for accessing protected resources.
/// </summary>
[Required]
public required string AccessToken { get; set; }
/// <summary>
/// The date and time when the JWT token expires.
/// </summary>
/// <remarks>After this date, a new JWT token must be requested.</remarks>
[Required]
public required DateTime ExpiresIn { get; set; }
}

View File

@ -1,4 +1,4 @@
using Mirea.Api.Endpoint.Configuration.Model.GeneralSettings; using Mirea.Api.Endpoint.Configuration.General.Settings;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;

View File

@ -3,7 +3,7 @@ using System.IO;
using System.Text.Json; using System.Text.Json;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace Mirea.Api.Endpoint.Configuration.Model; namespace Mirea.Api.Endpoint.Common.Settings;
public class Admin : ISaveSettings public class Admin : ISaveSettings
{ {

View File

@ -1,10 +1,10 @@
using Mirea.Api.Endpoint.Common.Services; using Mirea.Api.Endpoint.Common.Services;
using Mirea.Api.Endpoint.Configuration.Model.GeneralSettings; using Mirea.Api.Endpoint.Configuration.General.Settings;
using System.IO; using System.IO;
using System.Text.Json; using System.Text.Json;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace Mirea.Api.Endpoint.Configuration.Model; namespace Mirea.Api.Endpoint.Common.Settings;
public class GeneralConfig : ISaveSettings public class GeneralConfig : ISaveSettings
{ {

View File

@ -1,4 +1,4 @@
namespace Mirea.Api.Endpoint.Configuration; namespace Mirea.Api.Endpoint.Common.Settings;
public interface ISaveSettings public interface ISaveSettings
{ {
void SaveSetting(); void SaveSetting();

View File

@ -1,7 +1,8 @@
using Asp.Versioning; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Versioning;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
namespace Mirea.Api.Endpoint.Configuration.Core.Startup; namespace Mirea.Api.Endpoint.Configuration.ApplicationConfiguration;
public static class ApiVersioningConfiguration public static class ApiVersioningConfiguration
{ {
@ -13,10 +14,14 @@ public static class ApiVersioningConfiguration
options.AssumeDefaultVersionWhenUnspecified = true; options.AssumeDefaultVersionWhenUnspecified = true;
options.ReportApiVersions = true; options.ReportApiVersions = true;
options.ApiVersionReader = new UrlSegmentApiVersionReader(); options.ApiVersionReader = new UrlSegmentApiVersionReader();
}).AddApiExplorer(options => });
services.AddVersionedApiExplorer(options =>
{ {
options.GroupNameFormat = "'v'VVV"; options.GroupNameFormat = "'v'VVV";
options.SubstituteApiVersionInUrl = true; options.SubstituteApiVersionInUrl = true;
}); });
services.AddEndpointsApiExplorer();
} }
} }

View File

@ -1,9 +1,9 @@
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Mirea.Api.Endpoint.Configuration.Model; using Mirea.Api.Endpoint.Common.Settings;
using Mirea.Api.Endpoint.Configuration.Model.GeneralSettings; using Mirea.Api.Endpoint.Configuration.General.Settings;
namespace Mirea.Api.Endpoint.Configuration.Core.Startup; namespace Mirea.Api.Endpoint.Configuration.ApplicationConfiguration;
public static class CacheConfiguration public static class CacheConfiguration
{ {

View File

@ -5,7 +5,7 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
namespace Mirea.Api.Endpoint.Configuration.Core.Startup; namespace Mirea.Api.Endpoint.Configuration.ApplicationConfiguration;
public static class EnvironmentConfiguration public static class EnvironmentConfiguration
{ {

View File

@ -7,7 +7,7 @@ using Mirea.Api.Security.Common.Interfaces;
using System; using System;
using System.Text; using System.Text;
namespace Mirea.Api.Endpoint.Configuration.Core.Startup; namespace Mirea.Api.Endpoint.Configuration.ApplicationConfiguration;
public static class JwtConfiguration public static class JwtConfiguration
{ {

View File

@ -2,14 +2,14 @@
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Mirea.Api.Endpoint.Common.Services; using Mirea.Api.Endpoint.Common.Services;
using Mirea.Api.Endpoint.Configuration.Model; using Mirea.Api.Endpoint.Common.Settings;
using Serilog; using Serilog;
using Serilog.Events; using Serilog.Events;
using Serilog.Filters; using Serilog.Filters;
using Serilog.Formatting.Compact; using Serilog.Formatting.Compact;
using System.IO; using System.IO;
namespace Mirea.Api.Endpoint.Configuration.Core.Startup; namespace Mirea.Api.Endpoint.Configuration.ApplicationConfiguration;
public static class LoggerConfiguration public static class LoggerConfiguration
{ {

View File

@ -1,12 +1,12 @@
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Mirea.Api.Endpoint.Common.Services.Security; using Mirea.Api.Endpoint.Common.Services.Security;
using Mirea.Api.Endpoint.Configuration.Model; using Mirea.Api.Endpoint.Common.Settings;
using Mirea.Api.Endpoint.Configuration.Model.GeneralSettings; using Mirea.Api.Endpoint.Configuration.General.Settings;
using Mirea.Api.Security; using Mirea.Api.Security;
using Mirea.Api.Security.Common.Interfaces; using Mirea.Api.Security.Common.Interfaces;
namespace Mirea.Api.Endpoint.Configuration.Core.Startup; namespace Mirea.Api.Endpoint.Configuration.ApplicationConfiguration;
public static class SecureConfiguration public static class SecureConfiguration
{ {

View File

@ -1,5 +1,5 @@
using Asp.Versioning.ApiExplorer; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models;
@ -9,7 +9,7 @@ using Swashbuckle.AspNetCore.SwaggerGen;
using System; using System;
using System.IO; using System.IO;
namespace Mirea.Api.Endpoint.Configuration.Core.Startup; namespace Mirea.Api.Endpoint.Configuration.ApplicationConfiguration;
public static class SwaggerConfiguration public static class SwaggerConfiguration
{ {

View File

@ -1,16 +0,0 @@
using Microsoft.AspNetCore.Http;
using System.Threading.Tasks;
namespace Mirea.Api.Endpoint.Configuration.Core.Middleware;
public class CookieAuthorizationMiddleware(RequestDelegate next)
{
public const string JwtAuthorizationName = "_ajwt";
public async Task InvokeAsync(HttpContext context)
{
if (context.Request.Cookies.ContainsKey(JwtAuthorizationName))
context.Request.Headers.Authorization = "Bearer " + context.Request.Cookies[JwtAuthorizationName];
await next(context);
}
}

View File

@ -1,6 +1,6 @@
using System; using System;
namespace Mirea.Api.Endpoint.Configuration.Validation.Attributes; namespace Mirea.Api.Endpoint.Configuration.General.Attributes;
[AttributeUsage(AttributeTargets.Class, Inherited = false)] [AttributeUsage(AttributeTargets.Class, Inherited = false)]
public class RequiredSettingsAttribute : Attribute; public class RequiredSettingsAttribute : Attribute;

View File

@ -0,0 +1,6 @@
namespace Mirea.Api.Endpoint.Configuration.General.Interfaces;
public interface IIsConfigured
{
bool IsConfigured();
}

View File

@ -1,7 +1,7 @@
using Mirea.Api.Endpoint.Configuration.Validation.Attributes; using Mirea.Api.Endpoint.Configuration.General.Attributes;
using Mirea.Api.Endpoint.Configuration.Validation.Interfaces; using Mirea.Api.Endpoint.Configuration.General.Interfaces;
namespace Mirea.Api.Endpoint.Configuration.Model.GeneralSettings; namespace Mirea.Api.Endpoint.Configuration.General.Settings;
[RequiredSettings] [RequiredSettings]
public class CacheSettings : IIsConfigured public class CacheSettings : IIsConfigured

View File

@ -1,10 +1,10 @@
using Mirea.Api.DataAccess.Persistence.Common; using Mirea.Api.DataAccess.Persistence.Common;
using Mirea.Api.Endpoint.Configuration.Validation.Attributes; using Mirea.Api.Endpoint.Configuration.General.Attributes;
using Mirea.Api.Endpoint.Configuration.Validation.Interfaces; using Mirea.Api.Endpoint.Configuration.General.Interfaces;
using System; using System;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace Mirea.Api.Endpoint.Configuration.Model.GeneralSettings; namespace Mirea.Api.Endpoint.Configuration.General.Settings;
[RequiredSettings] [RequiredSettings]
public class DbSettings : IIsConfigured public class DbSettings : IIsConfigured

View File

@ -1,6 +1,6 @@
using Mirea.Api.Endpoint.Configuration.Validation.Interfaces; using Mirea.Api.Endpoint.Configuration.General.Interfaces;
namespace Mirea.Api.Endpoint.Configuration.Model.GeneralSettings; namespace Mirea.Api.Endpoint.Configuration.General.Settings;
public class EmailSettings : IIsConfigured public class EmailSettings : IIsConfigured
{ {

View File

@ -1,7 +1,7 @@
using Mirea.Api.Endpoint.Configuration.Validation.Attributes; using Mirea.Api.Endpoint.Configuration.General.Attributes;
using Mirea.Api.Endpoint.Configuration.Validation.Interfaces; using Mirea.Api.Endpoint.Configuration.General.Interfaces;
namespace Mirea.Api.Endpoint.Configuration.Model.GeneralSettings; namespace Mirea.Api.Endpoint.Configuration.General.Settings;
[RequiredSettings] [RequiredSettings]
public class LogSettings : IIsConfigured public class LogSettings : IIsConfigured

View File

@ -1,10 +1,10 @@
using Mirea.Api.Endpoint.Configuration.Validation.Attributes; using Mirea.Api.Endpoint.Configuration.General.Attributes;
using Mirea.Api.Endpoint.Configuration.Validation.Interfaces; using Mirea.Api.Endpoint.Configuration.General.Interfaces;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
namespace Mirea.Api.Endpoint.Configuration.Model.GeneralSettings; namespace Mirea.Api.Endpoint.Configuration.General.Settings;
[RequiredSettings] [RequiredSettings]
public class ScheduleSettings : IIsConfigured public class ScheduleSettings : IIsConfigured

View File

@ -1,7 +1,7 @@
using Mirea.Api.Endpoint.Common.Interfaces; using Mirea.Api.Endpoint.Common.Interfaces;
using System; using System;
namespace Mirea.Api.Endpoint.Configuration.Validation; namespace Mirea.Api.Endpoint.Configuration.General;
public class SetupTokenService : ISetupToken public class SetupTokenService : ISetupToken
{ {

View File

@ -1,11 +1,11 @@
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Mirea.Api.Endpoint.Configuration.Model; using Mirea.Api.Endpoint.Common.Settings;
using Mirea.Api.Endpoint.Configuration.Validation.Attributes; using Mirea.Api.Endpoint.Configuration.General.Attributes;
using Mirea.Api.Endpoint.Configuration.Validation.Interfaces; using Mirea.Api.Endpoint.Configuration.General.Interfaces;
using System; using System;
using System.Reflection; using System.Reflection;
namespace Mirea.Api.Endpoint.Configuration.Validation.Validators; namespace Mirea.Api.Endpoint.Configuration.General.Validators;
public class SettingsRequiredValidator public class SettingsRequiredValidator
{ {

View File

@ -1,4 +1,4 @@
using Asp.Versioning.ApiExplorer; using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models;

View File

@ -1,6 +0,0 @@
namespace Mirea.Api.Endpoint.Configuration.Validation.Interfaces;
public interface IIsConfigured
{
bool IsConfigured();
}

View File

@ -1,5 +1,4 @@
using Asp.Versioning; using Cronos;
using Cronos;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Data.Sqlite; using Microsoft.Data.Sqlite;
@ -10,9 +9,9 @@ using Mirea.Api.Endpoint.Common.Attributes;
using Mirea.Api.Endpoint.Common.Exceptions; using Mirea.Api.Endpoint.Common.Exceptions;
using Mirea.Api.Endpoint.Common.Interfaces; using Mirea.Api.Endpoint.Common.Interfaces;
using Mirea.Api.Endpoint.Common.Services; using Mirea.Api.Endpoint.Common.Services;
using Mirea.Api.Endpoint.Configuration.Model; using Mirea.Api.Endpoint.Common.Settings;
using Mirea.Api.Endpoint.Configuration.Model.GeneralSettings; using Mirea.Api.Endpoint.Configuration.General.Settings;
using Mirea.Api.Endpoint.Configuration.Validation.Validators; using Mirea.Api.Endpoint.Configuration.General.Validators;
using Mirea.Api.Security.Services; using Mirea.Api.Security.Services;
using MySqlConnector; using MySqlConnector;
using Npgsql; using Npgsql;
@ -29,6 +28,7 @@ using System.Security.Cryptography;
namespace Mirea.Api.Endpoint.Controllers.Configuration; namespace Mirea.Api.Endpoint.Controllers.Configuration;
[ApiVersion("1.0")] [ApiVersion("1.0")]
[ApiController]
[MaintenanceModeIgnore] [MaintenanceModeIgnore]
[ApiExplorerSettings(IgnoreApi = true)] [ApiExplorerSettings(IgnoreApi = true)]
public class SetupController( public class SetupController(

View File

@ -1,16 +1,15 @@
using Asp.Versioning; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Mirea.Api.Dto.Common; using Mirea.Api.Dto.Common;
using Mirea.Api.Dto.Requests; using Mirea.Api.Dto.Requests;
using Mirea.Api.Dto.Responses;
using Mirea.Api.Endpoint.Common.Attributes; using Mirea.Api.Endpoint.Common.Attributes;
using Mirea.Api.Endpoint.Common.Exceptions; using Mirea.Api.Endpoint.Common.Exceptions;
using Mirea.Api.Endpoint.Common.Services; using Mirea.Api.Endpoint.Common.Services;
using Mirea.Api.Endpoint.Configuration.Core.Middleware; using Mirea.Api.Endpoint.Common.Settings;
using Mirea.Api.Endpoint.Configuration.Model;
using Mirea.Api.Security.Common.Dto.Requests; using Mirea.Api.Security.Common.Dto.Requests;
using Mirea.Api.Security.Services; using Mirea.Api.Security.Services;
using System; using System;
@ -46,19 +45,13 @@ public class AuthController(IOptionsSnapshot<Admin> user, AuthService auth, Pass
private void SetRefreshToken(string value, DateTimeOffset? expires = null) private void SetRefreshToken(string value, DateTimeOffset? expires = null)
{ {
SetCookie("refresh_token", value, expires); SetCookie("refresh_token", value, expires);
SetCookie("user_key", Fingerprint); SetCookie("user_key", Fingerprint, expires);
} }
private void SetFirstToken(string value, DateTimeOffset? expires = null) private void SetFirstToken(string value, DateTimeOffset? expires = null)
{ {
SetCookie("authentication_token", value, expires); SetCookie("authentication_token", value, expires);
SetCookie("user_key", Fingerprint); SetCookie("user_key", Fingerprint, expires);
}
private void SetAuthToken(string value, DateTimeOffset? expires = null)
{
SetCookie(CookieAuthorizationMiddleware.JwtAuthorizationName, value, expires);
SetCookie("user_key", Fingerprint);
} }
[ApiExplorerSettings(IgnoreApi = true)] [ApiExplorerSettings(IgnoreApi = true)]
@ -82,17 +75,17 @@ public class AuthController(IOptionsSnapshot<Admin> user, AuthService auth, Pass
/// then generating and returning an authentication token if successful. /// then generating and returning an authentication token if successful.
/// </summary> /// </summary>
/// <param name="request">The login request containing the username/email and password.</param> /// <param name="request">The login request containing the username/email and password.</param>
/// <returns>User's AuthRoles.</returns> /// <returns>A TokenResponse containing the access token and its expiry if successful, otherwise an Unauthorized response.</returns>
[HttpPost("Login")] [HttpPost("Login")]
[BadRequestResponse] [ProducesResponseType(StatusCodes.Status401Unauthorized)]
public async Task<ActionResult<AuthRoles>> Login([FromBody] LoginRequest request) public async Task<ActionResult<TokenResponse>> Login([FromBody] LoginRequest request)
{ {
var userEntity = user.Value; var userEntity = user.Value;
if (!userEntity.Username.Equals(request.Username, StringComparison.OrdinalIgnoreCase) && if (!userEntity.Username.Equals(request.Username, StringComparison.OrdinalIgnoreCase) &&
!userEntity.Email.Equals(request.Username, StringComparison.OrdinalIgnoreCase) || !userEntity.Email.Equals(request.Username, StringComparison.OrdinalIgnoreCase) ||
!passwordService.VerifyPassword(request.Password, userEntity.Salt, userEntity.PasswordHash)) !passwordService.VerifyPassword(request.Password, userEntity.Salt, userEntity.PasswordHash))
return BadRequest("Invalid username/email or password"); return Unauthorized("Invalid username/email or password");
var token = await auth.GenerateAuthTokensAsync(new TokenRequest var token = await auth.GenerateAuthTokensAsync(new TokenRequest
{ {
@ -102,19 +95,21 @@ public class AuthController(IOptionsSnapshot<Admin> user, AuthService auth, Pass
}, "1"); }, "1");
SetRefreshToken(token.RefreshToken, token.RefreshExpiresIn); SetRefreshToken(token.RefreshToken, token.RefreshExpiresIn);
SetAuthToken(token.AccessToken, token.AccessExpiresIn);
return Ok(AuthRoles.Admin); return Ok(new TokenResponse
{
AccessToken = token.AccessToken,
ExpiresIn = token.AccessExpiresIn
});
} }
/// <summary> /// <summary>
/// Refreshes the authentication token using the existing refresh token. /// Refreshes the authentication token using the existing refresh token.
/// </summary> /// </summary>
/// <returns>User's AuthRoles.</returns> /// <returns>A TokenResponse containing the new access token and its expiry if successful, otherwise an Unauthorized response.</returns>
[HttpGet("ReLogin")] [HttpGet("ReLogin")]
[ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status403Forbidden)] public async Task<ActionResult<TokenResponse>> ReLogin()
public async Task<ActionResult<AuthRoles>> ReLogin()
{ {
if (string.IsNullOrEmpty(RefreshToken)) if (string.IsNullOrEmpty(RefreshToken))
return Unauthorized(); return Unauthorized();
@ -132,13 +127,16 @@ public class AuthController(IOptionsSnapshot<Admin> user, AuthService auth, Pass
); );
SetRefreshToken(token.RefreshToken, token.RefreshExpiresIn); SetRefreshToken(token.RefreshToken, token.RefreshExpiresIn);
SetAuthToken(token.AccessToken, token.AccessExpiresIn);
return Ok(AuthRoles.Admin); return Ok(new TokenResponse
{
AccessToken = token.AccessToken,
ExpiresIn = token.AccessExpiresIn
});
} }
catch (SecurityException) catch (SecurityException)
{ {
return Forbid(); return Unauthorized();
} }
} }
@ -153,7 +151,6 @@ public class AuthController(IOptionsSnapshot<Admin> user, AuthService auth, Pass
{ {
SetRefreshToken("", DateTimeOffset.MinValue); SetRefreshToken("", DateTimeOffset.MinValue);
SetFirstToken("", DateTimeOffset.MinValue); SetFirstToken("", DateTimeOffset.MinValue);
SetAuthToken("", DateTimeOffset.MinValue);
await auth.LogoutAsync(Fingerprint); await auth.LogoutAsync(Fingerprint);
@ -167,6 +164,7 @@ public class AuthController(IOptionsSnapshot<Admin> user, AuthService auth, Pass
[HttpGet("GetRole")] [HttpGet("GetRole")]
[ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status401Unauthorized)]
[Authorize] [Authorize]
[CacheMaxAge(0, 0, 1)]
public ActionResult<AuthRoles> GetRole() => Ok(AuthRoles.Admin); public ActionResult<AuthRoles> GetRole() => Ok(AuthRoles.Admin);
[HttpPost("RenewPassword")] [HttpPost("RenewPassword")]

View File

@ -1,5 +1,5 @@
using Asp.Versioning; using MediatR;
using MediatR; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Mirea.Api.DataAccess.Application.Cqrs.Campus.Queries.GetCampusBasicInfoList; using Mirea.Api.DataAccess.Application.Cqrs.Campus.Queries.GetCampusBasicInfoList;
using Mirea.Api.DataAccess.Application.Cqrs.Campus.Queries.GetCampusDetails; using Mirea.Api.DataAccess.Application.Cqrs.Campus.Queries.GetCampusDetails;
@ -20,6 +20,7 @@ public class CampusController(IMediator mediator) : BaseController
/// </summary> /// </summary>
/// <returns>Basic information about campuses.</returns> /// <returns>Basic information about campuses.</returns>
[HttpGet] [HttpGet]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult<List<CampusBasicInfoResponse>>> Get() public async Task<ActionResult<List<CampusBasicInfoResponse>>> Get()
{ {
var result = await mediator.Send(new GetCampusBasicInfoListQuery()); var result = await mediator.Send(new GetCampusBasicInfoListQuery());
@ -40,6 +41,7 @@ public class CampusController(IMediator mediator) : BaseController
/// <param name="id">Campus ID.</param> /// <param name="id">Campus ID.</param>
/// <returns>Details of the specified campus.</returns> /// <returns>Details of the specified campus.</returns>
[HttpGet("{id:int}")] [HttpGet("{id:int}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[BadRequestResponse] [BadRequestResponse]
[NotFoundResponse] [NotFoundResponse]
public async Task<ActionResult<CampusDetailsResponse>> GetDetails(int id) public async Task<ActionResult<CampusDetailsResponse>> GetDetails(int id)

View File

@ -1,5 +1,5 @@
using Asp.Versioning; using MediatR;
using MediatR; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Mirea.Api.DataAccess.Application.Cqrs.Discipline.Queries.GetDisciplineDetails; using Mirea.Api.DataAccess.Application.Cqrs.Discipline.Queries.GetDisciplineDetails;
using Mirea.Api.DataAccess.Application.Cqrs.Discipline.Queries.GetDisciplineList; using Mirea.Api.DataAccess.Application.Cqrs.Discipline.Queries.GetDisciplineList;
@ -22,6 +22,7 @@ public class DisciplineController(IMediator mediator) : BaseController
/// <param name="pageSize">Number of items per page.</param> /// <param name="pageSize">Number of items per page.</param>
/// <returns>Paginated list of disciplines.</returns> /// <returns>Paginated list of disciplines.</returns>
[HttpGet] [HttpGet]
[ProducesResponseType(StatusCodes.Status200OK)]
[BadRequestResponse] [BadRequestResponse]
public async Task<ActionResult<List<DisciplineResponse>>> Get([FromQuery] int? page, [FromQuery] int? pageSize) public async Task<ActionResult<List<DisciplineResponse>>> Get([FromQuery] int? page, [FromQuery] int? pageSize)
{ {
@ -46,6 +47,7 @@ public class DisciplineController(IMediator mediator) : BaseController
/// <param name="id">Discipline ID.</param> /// <param name="id">Discipline ID.</param>
/// <returns>Details of the specified discipline.</returns> /// <returns>Details of the specified discipline.</returns>
[HttpGet("{id:int}")] [HttpGet("{id:int}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[BadRequestResponse] [BadRequestResponse]
[NotFoundResponse] [NotFoundResponse]
public async Task<ActionResult<DisciplineResponse>> GetDetails(int id) public async Task<ActionResult<DisciplineResponse>> GetDetails(int id)

View File

@ -1,5 +1,5 @@
using Asp.Versioning; using MediatR;
using MediatR; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Mirea.Api.DataAccess.Application.Cqrs.Faculty.Queries.GetFacultyDetails; using Mirea.Api.DataAccess.Application.Cqrs.Faculty.Queries.GetFacultyDetails;
using Mirea.Api.DataAccess.Application.Cqrs.Faculty.Queries.GetFacultyList; using Mirea.Api.DataAccess.Application.Cqrs.Faculty.Queries.GetFacultyList;
@ -22,6 +22,7 @@ public class FacultyController(IMediator mediator) : BaseController
/// <param name="pageSize">Number of items per page.</param> /// <param name="pageSize">Number of items per page.</param>
/// <returns>Paginated list of faculties.</returns> /// <returns>Paginated list of faculties.</returns>
[HttpGet] [HttpGet]
[ProducesResponseType(StatusCodes.Status200OK)]
[BadRequestResponse] [BadRequestResponse]
public async Task<ActionResult<List<FacultyResponse>>> Get([FromQuery] int? page, [FromQuery] int? pageSize) public async Task<ActionResult<List<FacultyResponse>>> Get([FromQuery] int? page, [FromQuery] int? pageSize)
{ {
@ -47,6 +48,7 @@ public class FacultyController(IMediator mediator) : BaseController
/// <param name="id">Faculty ID.</param> /// <param name="id">Faculty ID.</param>
/// <returns>Details of the specified faculty.</returns> /// <returns>Details of the specified faculty.</returns>
[HttpGet("{id:int}")] [HttpGet("{id:int}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[BadRequestResponse] [BadRequestResponse]
[NotFoundResponse] [NotFoundResponse]
public async Task<ActionResult<FacultyDetailsResponse>> GetDetails(int id) public async Task<ActionResult<FacultyDetailsResponse>> GetDetails(int id)

View File

@ -1,5 +1,5 @@
using Asp.Versioning; using MediatR;
using MediatR; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Mirea.Api.DataAccess.Application.Cqrs.Group.Queries.GetGroupDetails; using Mirea.Api.DataAccess.Application.Cqrs.Group.Queries.GetGroupDetails;
using Mirea.Api.DataAccess.Application.Cqrs.Group.Queries.GetGroupList; using Mirea.Api.DataAccess.Application.Cqrs.Group.Queries.GetGroupList;
@ -36,6 +36,7 @@ public class GroupController(IMediator mediator) : BaseController
/// <param name="pageSize">The page size for pagination (optional).</param> /// <param name="pageSize">The page size for pagination (optional).</param>
/// <returns>A list of groups.</returns> /// <returns>A list of groups.</returns>
[HttpGet] [HttpGet]
[ProducesResponseType(StatusCodes.Status200OK)]
[BadRequestResponse] [BadRequestResponse]
public async Task<ActionResult<List<GroupResponse>>> Get([FromQuery] int? page, [FromQuery] int? pageSize) public async Task<ActionResult<List<GroupResponse>>> Get([FromQuery] int? page, [FromQuery] int? pageSize)
{ {
@ -62,6 +63,7 @@ public class GroupController(IMediator mediator) : BaseController
/// <param name="id">The ID of the group to retrieve.</param> /// <param name="id">The ID of the group to retrieve.</param>
/// <returns>Detailed information about the group.</returns> /// <returns>Detailed information about the group.</returns>
[HttpGet("{id:int}")] [HttpGet("{id:int}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[BadRequestResponse] [BadRequestResponse]
[NotFoundResponse] [NotFoundResponse]
public async Task<ActionResult<GroupDetailsResponse>> GetDetails(int id) public async Task<ActionResult<GroupDetailsResponse>> GetDetails(int id)
@ -87,6 +89,7 @@ public class GroupController(IMediator mediator) : BaseController
/// <param name="id">The ID of the faculty.</param> /// <param name="id">The ID of the faculty.</param>
/// <returns>A list of groups belonging to the specified faculty.</returns> /// <returns>A list of groups belonging to the specified faculty.</returns>
[HttpGet("GetByFaculty/{id:int}")] [HttpGet("GetByFaculty/{id:int}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[BadRequestResponse] [BadRequestResponse]
[NotFoundResponse] [NotFoundResponse]
public async Task<ActionResult<List<GroupResponse>>> GetByFaculty(int id) public async Task<ActionResult<List<GroupResponse>>> GetByFaculty(int id)

View File

@ -1,5 +1,5 @@
using Asp.Versioning; using MediatR;
using MediatR; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Mirea.Api.DataAccess.Application.Cqrs.LectureHall.Queries.GetLectureHallDetails; using Mirea.Api.DataAccess.Application.Cqrs.LectureHall.Queries.GetLectureHallDetails;
using Mirea.Api.DataAccess.Application.Cqrs.LectureHall.Queries.GetLectureHallList; using Mirea.Api.DataAccess.Application.Cqrs.LectureHall.Queries.GetLectureHallList;
@ -20,6 +20,7 @@ public class LectureHallController(IMediator mediator) : BaseController
/// </summary> /// </summary>
/// <returns>A list of lecture halls.</returns> /// <returns>A list of lecture halls.</returns>
[HttpGet] [HttpGet]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult<List<LectureHallResponse>>> Get() public async Task<ActionResult<List<LectureHallResponse>>> Get()
{ {
var result = await mediator.Send(new GetLectureHallListQuery()); var result = await mediator.Send(new GetLectureHallListQuery());
@ -40,6 +41,7 @@ public class LectureHallController(IMediator mediator) : BaseController
/// <param name="id">The ID of the lecture hall to retrieve.</param> /// <param name="id">The ID of the lecture hall to retrieve.</param>
/// <returns>The details of the specified lecture hall.</returns> /// <returns>The details of the specified lecture hall.</returns>
[HttpGet("{id:int}")] [HttpGet("{id:int}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[BadRequestResponse] [BadRequestResponse]
[NotFoundResponse] [NotFoundResponse]
public async Task<ActionResult<LectureHallDetailsResponse>> GetDetails(int id) public async Task<ActionResult<LectureHallDetailsResponse>> GetDetails(int id)
@ -65,6 +67,7 @@ public class LectureHallController(IMediator mediator) : BaseController
/// <param name="id">The ID of the campus.</param> /// <param name="id">The ID of the campus.</param>
/// <returns>A list of lecture halls in the specified campus.</returns> /// <returns>A list of lecture halls in the specified campus.</returns>
[HttpGet("GetByCampus/{id:int}")] [HttpGet("GetByCampus/{id:int}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[BadRequestResponse] [BadRequestResponse]
[NotFoundResponse] [NotFoundResponse]
public async Task<ActionResult<List<LectureHallResponse>>> GetByCampus(int id) public async Task<ActionResult<List<LectureHallResponse>>> GetByCampus(int id)

View File

@ -1,5 +1,5 @@
using Asp.Versioning; using MediatR;
using MediatR; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Mirea.Api.DataAccess.Application.Cqrs.Professor.Queries.GetProfessorDetails; using Mirea.Api.DataAccess.Application.Cqrs.Professor.Queries.GetProfessorDetails;
using Mirea.Api.DataAccess.Application.Cqrs.Professor.Queries.GetProfessorList; using Mirea.Api.DataAccess.Application.Cqrs.Professor.Queries.GetProfessorList;
@ -22,6 +22,7 @@ public class ProfessorController(IMediator mediator) : BaseController
/// <param name="pageSize">The page size for pagination (optional).</param> /// <param name="pageSize">The page size for pagination (optional).</param>
/// <returns>A list of professors.</returns> /// <returns>A list of professors.</returns>
[HttpGet] [HttpGet]
[ProducesResponseType(StatusCodes.Status200OK)]
[BadRequestResponse] [BadRequestResponse]
public async Task<ActionResult<List<ProfessorResponse>>> Get([FromQuery] int? page, [FromQuery] int? pageSize) public async Task<ActionResult<List<ProfessorResponse>>> Get([FromQuery] int? page, [FromQuery] int? pageSize)
{ {
@ -47,6 +48,7 @@ public class ProfessorController(IMediator mediator) : BaseController
/// <param name="id">The ID of the professor to retrieve.</param> /// <param name="id">The ID of the professor to retrieve.</param>
/// <returns>Detailed information about the professor.</returns> /// <returns>Detailed information about the professor.</returns>
[HttpGet("{id:int}")] [HttpGet("{id:int}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[BadRequestResponse] [BadRequestResponse]
[NotFoundResponse] [NotFoundResponse]
public async Task<ActionResult<ProfessorResponse>> GetDetails(int id) public async Task<ActionResult<ProfessorResponse>> GetDetails(int id)

View File

@ -1,5 +1,4 @@
using Asp.Versioning; using MediatR;
using MediatR;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
@ -9,7 +8,7 @@ using Mirea.Api.Dto.Requests;
using Mirea.Api.Dto.Responses; using Mirea.Api.Dto.Responses;
using Mirea.Api.Endpoint.Common.Attributes; using Mirea.Api.Endpoint.Common.Attributes;
using Mirea.Api.Endpoint.Common.Services; using Mirea.Api.Endpoint.Common.Services;
using Mirea.Api.Endpoint.Configuration.Model; using Mirea.Api.Endpoint.Common.Settings;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -35,8 +34,10 @@ public class ScheduleController(IMediator mediator, IOptionsSnapshot<GeneralConf
/// <param name="request">The request object containing filter criteria.</param> /// <param name="request">The request object containing filter criteria.</param>
/// <returns>A list of schedules matching the filter criteria.</returns> /// <returns>A list of schedules matching the filter criteria.</returns>
[HttpPost] [HttpPost]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
[BadRequestResponse] [BadRequestResponse]
[NotFoundResponse]
public async Task<ActionResult<List<ScheduleResponse>>> Get([FromBody] ScheduleRequest request) public async Task<ActionResult<List<ScheduleResponse>>> Get([FromBody] ScheduleRequest request)
{ {
if ((request.Groups == null || request.Groups.Length == 0) && if ((request.Groups == null || request.Groups.Length == 0) &&
@ -63,8 +64,7 @@ public class ScheduleController(IMediator mediator, IOptionsSnapshot<GeneralConf
ProfessorIds = request.Professors ProfessorIds = request.Professors
})).Schedules; })).Schedules;
if (result.Count == 0) if (result.Count == 0) NoContent();
NoContent();
return Ok(result.Select(s => new ScheduleResponse return Ok(result.Select(s => new ScheduleResponse
{ {
@ -98,6 +98,7 @@ public class ScheduleController(IMediator mediator, IOptionsSnapshot<GeneralConf
/// <param name="lectureHalls">An array of lecture hall IDs.</param> /// <param name="lectureHalls">An array of lecture hall IDs.</param>
/// <returns>A response containing schedules for the specified group.</returns> /// <returns>A response containing schedules for the specified group.</returns>
[HttpGet("GetByGroup/{id:int}")] [HttpGet("GetByGroup/{id:int}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
[BadRequestResponse] [BadRequestResponse]
[NotFoundResponse] [NotFoundResponse]
@ -125,6 +126,7 @@ public class ScheduleController(IMediator mediator, IOptionsSnapshot<GeneralConf
/// <param name="lectureHalls">An array of lecture hall IDs.</param> /// <param name="lectureHalls">An array of lecture hall IDs.</param>
/// <returns>A response containing schedules for the specified professor.</returns> /// <returns>A response containing schedules for the specified professor.</returns>
[HttpGet("GetByProfessor/{id:int}")] [HttpGet("GetByProfessor/{id:int}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
[BadRequestResponse] [BadRequestResponse]
[NotFoundResponse] [NotFoundResponse]
@ -152,6 +154,7 @@ public class ScheduleController(IMediator mediator, IOptionsSnapshot<GeneralConf
/// <param name="groups">An array of group IDs.</param> /// <param name="groups">An array of group IDs.</param>
/// <returns>A response containing schedules for the specified lecture hall.</returns> /// <returns>A response containing schedules for the specified lecture hall.</returns>
[HttpGet("GetByLectureHall/{id:int}")] [HttpGet("GetByLectureHall/{id:int}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
[BadRequestResponse] [BadRequestResponse]
[NotFoundResponse] [NotFoundResponse]
@ -179,6 +182,7 @@ public class ScheduleController(IMediator mediator, IOptionsSnapshot<GeneralConf
/// <param name="lectureHalls">An array of lecture hall IDs.</param> /// <param name="lectureHalls">An array of lecture hall IDs.</param>
/// <returns>A response containing schedules for the specified discipline.</returns> /// <returns>A response containing schedules for the specified discipline.</returns>
[HttpGet("GetByDiscipline/{id:int}")] [HttpGet("GetByDiscipline/{id:int}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
[BadRequestResponse] [BadRequestResponse]
[NotFoundResponse] [NotFoundResponse]

View File

@ -5,9 +5,9 @@
<ImplicitUsings>disable</ImplicitUsings> <ImplicitUsings>disable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<Company>Winsomnia</Company> <Company>Winsomnia</Company>
<Version>1.0.0-rc2</Version> <Version>1.0.0-rc0</Version>
<AssemblyVersion>1.0.2.2</AssemblyVersion> <AssemblyVersion>1.0.2.0</AssemblyVersion>
<FileVersion>1.0.2.2</FileVersion> <FileVersion>1.0.2.0</FileVersion>
<AssemblyName>Mirea.Api.Endpoint</AssemblyName> <AssemblyName>Mirea.Api.Endpoint</AssemblyName>
<RootNamespace>$(AssemblyName)</RootNamespace> <RootNamespace>$(AssemblyName)</RootNamespace>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
@ -22,38 +22,22 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Asp.Versioning.Mvc" Version="8.1.0" />
<PackageReference Include="Asp.Versioning.Mvc.ApiExplorer" Version="8.1.0" />
<PackageReference Include="Cronos" Version="0.8.4" /> <PackageReference Include="Cronos" Version="0.8.4" />
<PackageReference Include="EPPlus" Version="7.4.0" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.8" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.10" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.8">
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="4.11.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.11.0" />
<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.Common" Version="4.11.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.10">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.Extensions.ApiDescription.Server" Version="8.0.10">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="8.1.2" />
<PackageReference Include="Mirea.Tools.Schedule.WebParser" Version="1.0.3" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.2" /> <PackageReference Include="Serilog.AspNetCore" Version="8.0.2" />
<PackageReference Include="Serilog.Formatting.Compact" Version="3.0.0" /> <PackageReference Include="Serilog.Formatting.Compact" Version="3.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" /> <PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
<PackageReference Include="Serilog.Sinks.Debug" Version="3.0.0" />
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" /> <PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="8.0.10" /> <PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="8.0.8" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.8.1" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.7.3" />
<PackageReference Include="System.CodeDom" Version="8.0.0" /> <PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="6.7.3" />
<PackageReference Include="System.Composition" Version="8.0.0" /> <PackageReference Include="Swashbuckle.AspNetCore.Versioning" Version="2.0.0" />
<PackageReference Include="System.Composition.TypedParts" Version="8.0.0" /> <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.0.2" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.1.2" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="6.0.0" />
<PackageReference Include="System.Threading.Channels" Version="8.0.0" />
<PackageReference Include="Z.EntityFramework.Extensions.EFCore" Version="8.103.5" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -3,12 +3,12 @@ using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Mirea.Api.Endpoint.Common.Attributes; using Mirea.Api.Endpoint.Common.Attributes;
using Mirea.Api.Endpoint.Configuration.Model; using Mirea.Api.Endpoint.Common.Settings;
using System; using System;
using System.Reflection; using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Mirea.Api.Endpoint.Configuration.Core.Middleware; namespace Mirea.Api.Endpoint.Middleware;
public class CacheMaxAgeMiddleware(RequestDelegate next, IServiceProvider serviceProvider) public class CacheMaxAgeMiddleware(RequestDelegate next, IServiceProvider serviceProvider)
{ {

View File

@ -7,7 +7,7 @@ using System;
using System.Text.Json; using System.Text.Json;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Mirea.Api.Endpoint.Configuration.Core.Middleware; namespace Mirea.Api.Endpoint.Middleware;
public class CustomExceptionHandlerMiddleware(RequestDelegate next) public class CustomExceptionHandlerMiddleware(RequestDelegate next)
{ {

View File

@ -2,7 +2,7 @@
using Mirea.Api.Security.Common.Interfaces; using Mirea.Api.Security.Common.Interfaces;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Mirea.Api.Endpoint.Configuration.Core.Middleware; namespace Mirea.Api.Endpoint.Middleware;
public class JwtRevocationMiddleware(RequestDelegate next) public class JwtRevocationMiddleware(RequestDelegate next)
{ {

View File

@ -3,7 +3,7 @@ using Mirea.Api.Endpoint.Common.Attributes;
using Mirea.Api.Endpoint.Common.Interfaces; using Mirea.Api.Endpoint.Common.Interfaces;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Mirea.Api.Endpoint.Configuration.Core.Middleware; namespace Mirea.Api.Endpoint.Middleware;
public class MaintenanceModeMiddleware(RequestDelegate next, IMaintenanceModeService maintenanceModeService, IMaintenanceModeNotConfigureService maintenanceModeNotConfigureService) public class MaintenanceModeMiddleware(RequestDelegate next, IMaintenanceModeService maintenanceModeService, IMaintenanceModeNotConfigureService maintenanceModeNotConfigureService)
{ {

View File

@ -10,11 +10,11 @@ using Mirea.Api.DataAccess.Persistence;
using Mirea.Api.DataAccess.Persistence.Common; using Mirea.Api.DataAccess.Persistence.Common;
using Mirea.Api.Endpoint.Common.Interfaces; using Mirea.Api.Endpoint.Common.Interfaces;
using Mirea.Api.Endpoint.Common.Services; using Mirea.Api.Endpoint.Common.Services;
using Mirea.Api.Endpoint.Configuration.Core.Middleware; using Mirea.Api.Endpoint.Common.Settings;
using Mirea.Api.Endpoint.Configuration.Core.Startup; using Mirea.Api.Endpoint.Configuration.ApplicationConfiguration;
using Mirea.Api.Endpoint.Configuration.Model; using Mirea.Api.Endpoint.Configuration.General;
using Mirea.Api.Endpoint.Configuration.Validation; using Mirea.Api.Endpoint.Configuration.General.Validators;
using Mirea.Api.Endpoint.Configuration.Validation.Validators; using Mirea.Api.Endpoint.Middleware;
using Mirea.Api.Security.Services; using Mirea.Api.Security.Services;
using System; using System;
using System.IO; using System.IO;
@ -64,9 +64,6 @@ public class Program
policy.AllowAnyMethod(); policy.AllowAnyMethod();
policy.AllowAnyHeader(); policy.AllowAnyHeader();
policy.AllowCredentials(); policy.AllowCredentials();
#if DEBUG
policy.WithOrigins("http://localhost:4200");
#endif
}); });
}); });
@ -84,7 +81,6 @@ public class Program
{ {
secretForward.SecretForwardToken = GeneratorKey.GenerateAlphaNumeric(16); secretForward.SecretForwardToken = GeneratorKey.GenerateAlphaNumeric(16);
secretForward.SaveSetting(); secretForward.SaveSetting();
Console.WriteLine($"For the reverse proxy server to work correctly, use the header: '{secretForward.SecretForwardToken}-X-Forwarded-For'");
} }
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
@ -128,18 +124,16 @@ public class Program
} }
app.UseCustomSwagger(app.Services); app.UseCustomSwagger(app.Services);
app.UseHttpsRedirection();
app.UseMiddleware<CustomExceptionHandlerMiddleware>(); app.UseMiddleware<CustomExceptionHandlerMiddleware>();
app.UseMiddleware<MaintenanceModeMiddleware>(); app.UseMiddleware<MaintenanceModeMiddleware>();
app.UseMiddleware<CookieAuthorizationMiddleware>();
app.UseAuthentication();
app.UseAuthorization();
app.UseMiddleware<JwtRevocationMiddleware>(); app.UseMiddleware<JwtRevocationMiddleware>();
app.UseMiddleware<CacheMaxAgeMiddleware>(); app.UseMiddleware<CacheMaxAgeMiddleware>();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers(); app.MapControllers();
app.Run(); app.Run();

View File

@ -15,7 +15,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Konscious.Security.Cryptography.Argon2" Version="1.3.1" /> <PackageReference Include="Konscious.Security.Cryptography.Argon2" Version="1.3.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.2" /> <PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.1" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -5,18 +5,18 @@
<ImplicitUsings>disable</ImplicitUsings> <ImplicitUsings>disable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<Company>Winsomnia</Company> <Company>Winsomnia</Company>
<Version>1.0.1</Version> <Version>1.0.0</Version>
<AssemblyVersion>1.0.3.1</AssemblyVersion> <AssemblyVersion>1.0.3.0</AssemblyVersion>
<FileVersion>1.0.3.1</FileVersion> <FileVersion>1.0.3.0</FileVersion>
<AssemblyName>Mirea.Api.DataAccess.Application</AssemblyName> <AssemblyName>Mirea.Api.DataAccess.Application</AssemblyName>
<RootNamespace>$(AssemblyName)</RootNamespace> <RootNamespace>$(AssemblyName)</RootNamespace>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="FluentValidation" Version="11.10.0" /> <PackageReference Include="FluentValidation" Version="11.9.2" />
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="11.10.0" /> <PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="11.9.2" />
<PackageReference Include="MediatR" Version="12.4.1" /> <PackageReference Include="MediatR" Version="12.4.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.10" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.8" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -13,9 +13,9 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.10" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.8" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.10" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.8" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.8" /> <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.4" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="8.0.2" /> <PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="8.0.2" />
</ItemGroup> </ItemGroup>