fix: quota mensal
This commit is contained in:
parent
4570e9b70b
commit
7b78f11b72
@ -1,5 +1,6 @@
|
|||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Microsoft.AspNetCore.Localization;
|
||||||
|
|
||||||
namespace QRRapidoApp.Middleware
|
namespace QRRapidoApp.Middleware
|
||||||
{
|
{
|
||||||
@ -92,8 +93,9 @@ namespace QRRapidoApp.Middleware
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// No culture prefix or unknown segment -> Serve in Portuguese (default)
|
// No culture prefix → don't override culture cookie (CookieRequestCultureProvider
|
||||||
SetCulture(context, DefaultCulture);
|
// will pick it up). Just set thread culture from cookie if present, else pt-BR.
|
||||||
|
SetCulture(context, DefaultCulture, persistCookie: false);
|
||||||
await _next(context);
|
await _next(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,12 +153,33 @@ namespace QRRapidoApp.Middleware
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetCulture(HttpContext context, string culture)
|
private void SetCulture(HttpContext context, string culture, bool persistCookie = true)
|
||||||
{
|
{
|
||||||
var cultureInfo = new CultureInfo(culture);
|
var cultureInfo = new CultureInfo(culture);
|
||||||
CultureInfo.CurrentCulture = cultureInfo;
|
CultureInfo.CurrentCulture = cultureInfo;
|
||||||
CultureInfo.CurrentUICulture = cultureInfo;
|
CultureInfo.CurrentUICulture = cultureInfo;
|
||||||
context.Items["Culture"] = culture;
|
context.Items["Culture"] = culture;
|
||||||
|
|
||||||
|
// Persist culture cookie so CookieRequestCultureProvider works on
|
||||||
|
// routes without a culture prefix (e.g. /Pagamento/SelecaoPlano).
|
||||||
|
// Don't persist when using the default fallback — the user's stored
|
||||||
|
// preference (from a previous explicit navigation) must not be overwritten.
|
||||||
|
if (persistCookie)
|
||||||
|
{
|
||||||
|
var cookieValue = CookieRequestCultureProvider.MakeCookieValue(
|
||||||
|
new RequestCulture(culture, culture));
|
||||||
|
context.Response.Cookies.Append(
|
||||||
|
CookieRequestCultureProvider.DefaultCookieName,
|
||||||
|
cookieValue,
|
||||||
|
new CookieOptions
|
||||||
|
{
|
||||||
|
Expires = DateTimeOffset.UtcNow.AddDays(365),
|
||||||
|
IsEssential = true,
|
||||||
|
HttpOnly = false, // JS may need to read it
|
||||||
|
SameSite = SameSiteMode.Lax,
|
||||||
|
Secure = false // Must work on HTTP in dev too
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsSpecialRoute(string path)
|
private bool IsSpecialRoute(string path)
|
||||||
|
|||||||
30
Program.cs
30
Program.cs
@ -105,7 +105,16 @@ builder.Host.UseSerilog();
|
|||||||
|
|
||||||
// Add services to the container
|
// Add services to the container
|
||||||
|
|
||||||
builder.Services.AddControllersWithViews()
|
builder.Services.AddControllersWithViews(mvc =>
|
||||||
|
{
|
||||||
|
// Prevent Cloudflare/proxies from caching dynamic MVC responses.
|
||||||
|
// Static files bypass this filter and have their own cache headers.
|
||||||
|
mvc.Filters.Add(new Microsoft.AspNetCore.Mvc.ResponseCacheAttribute
|
||||||
|
{
|
||||||
|
NoStore = true,
|
||||||
|
Location = Microsoft.AspNetCore.Mvc.ResponseCacheLocation.None
|
||||||
|
});
|
||||||
|
})
|
||||||
.AddViewLocalization(Microsoft.AspNetCore.Mvc.Razor.LanguageViewLocationExpanderFormat.Suffix)
|
.AddViewLocalization(Microsoft.AspNetCore.Mvc.Razor.LanguageViewLocationExpanderFormat.Suffix)
|
||||||
.AddDataAnnotationsLocalization();
|
.AddDataAnnotationsLocalization();
|
||||||
|
|
||||||
@ -180,6 +189,22 @@ builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationSc
|
|||||||
options.LogoutPath = "/Account/Logout";
|
options.LogoutPath = "/Account/Logout";
|
||||||
options.ExpireTimeSpan = TimeSpan.FromDays(30);
|
options.ExpireTimeSpan = TimeSpan.FromDays(30);
|
||||||
options.SlidingExpiration = true;
|
options.SlidingExpiration = true;
|
||||||
|
options.Cookie.HttpOnly = true;
|
||||||
|
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
|
||||||
|
options.Cookie.SameSite = SameSiteMode.Lax;
|
||||||
|
options.Events.OnRedirectToLogin = ctx =>
|
||||||
|
{
|
||||||
|
Log.Warning("Auth challenge: {Path} → login. User authenticated: {Auth}",
|
||||||
|
ctx.Request.Path, ctx.HttpContext.User.Identity?.IsAuthenticated);
|
||||||
|
ctx.Response.Redirect(ctx.RedirectUri);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
};
|
||||||
|
options.Events.OnValidatePrincipal = ctx =>
|
||||||
|
{
|
||||||
|
if (!ctx.Principal?.Identity?.IsAuthenticated ?? false)
|
||||||
|
Log.Warning("Cookie validation failed for {Path}", ctx.Request.Path);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
};
|
||||||
})
|
})
|
||||||
.AddGoogle(options =>
|
.AddGoogle(options =>
|
||||||
{
|
{
|
||||||
@ -235,10 +260,11 @@ builder.Services.Configure<RequestLocalizationOptions>(options =>
|
|||||||
options.FallBackToParentCultures = false;
|
options.FallBackToParentCultures = false;
|
||||||
options.FallBackToParentUICultures = false;
|
options.FallBackToParentUICultures = false;
|
||||||
|
|
||||||
// Clear default providers and add custom ones in priority order
|
// Priority: Route → QueryString → Cookie → Default (pt-BR)
|
||||||
options.RequestCultureProviders.Clear();
|
options.RequestCultureProviders.Clear();
|
||||||
options.RequestCultureProviders.Add(new CustomRouteDataRequestCultureProvider());
|
options.RequestCultureProviders.Add(new CustomRouteDataRequestCultureProvider());
|
||||||
options.RequestCultureProviders.Add(new QueryStringRequestCultureProvider());
|
options.RequestCultureProviders.Add(new QueryStringRequestCultureProvider());
|
||||||
|
options.RequestCultureProviders.Add(new CookieRequestCultureProvider());
|
||||||
});
|
});
|
||||||
|
|
||||||
// Custom Services
|
// Custom Services
|
||||||
|
|||||||
@ -5,9 +5,8 @@
|
|||||||
ViewData["Title"] = "Comprar Créditos";
|
ViewData["Title"] = "Comprar Créditos";
|
||||||
Layout = "~/Views/Shared/_Layout.cshtml";
|
Layout = "~/Views/Shared/_Layout.cshtml";
|
||||||
|
|
||||||
var reqPath = Context.Request.Path.Value ?? "";
|
var currentCulture = System.Globalization.CultureInfo.CurrentCulture.Name;
|
||||||
var isBrazilian = !reqPath.StartsWith("/en", StringComparison.OrdinalIgnoreCase)
|
var isBrazilian = currentCulture.StartsWith("pt", StringComparison.OrdinalIgnoreCase);
|
||||||
&& !reqPath.StartsWith("/es", StringComparison.OrdinalIgnoreCase);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<div class="container py-5">
|
<div class="container py-5">
|
||||||
@ -46,8 +45,8 @@
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
<div class="d-flex justify-content-between align-items-center">
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
<span class="text-muted"><i class="fas fa-credit-card"></i> Cartão</span>
|
<span class="text-muted"><i class="fas fa-credit-card"></i> @(isBrazilian ? "Cartão" : "Card")</span>
|
||||||
<span class="h5 text-secondary mb-0">R$ @package.PriceCard.ToString("F2")</span>
|
<span class="h5 text-secondary mb-0">@(isBrazilian ? "R$" : "BRL") @package.PriceCard.ToString("F2")</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user