c5c33f7023
CI / backend (push) Successful in 53s
CI / frontend (push) Successful in 14s
Deploy Staging / deploy (push) Successful in 28s
Security / secrets (push) Successful in 3s
Security / dependencies (push) Successful in 59s
CI / backend (pull_request) Successful in 51s
CI / frontend (pull_request) Successful in 15s
Security / secrets (pull_request) Successful in 3s
Security / dependencies (pull_request) Successful in 56s
47 lines
1.7 KiB
C#
47 lines
1.7 KiB
C#
using System.Security.Claims;
|
|
using Asp.Versioning;
|
|
using Microsoft.AspNetCore.Authentication;
|
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
|
using Microsoft.AspNetCore.Authentication.Google;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.AspNetCore.RateLimiting;
|
|
|
|
namespace InboxIntel.Api.Controllers;
|
|
|
|
[ApiController]
|
|
[EnableRateLimiting("auth")] // AUDIT H-2: throttle login/challenge attempts per IP
|
|
[ApiVersion("1.0")]
|
|
[Route("api/v{version:apiVersion}/[controller]")]
|
|
public class AuthController : ControllerBase
|
|
{
|
|
/// <summary>Begins the Google OAuth2 login flow.</summary>
|
|
[HttpGet("login")]
|
|
[AllowAnonymous]
|
|
public IActionResult Login([FromQuery] string? returnUrl = "/")
|
|
{
|
|
// V-09: only allow local post-login redirects; reject absolute/off-host targets
|
|
// so the OAuth flow can't be abused as an open redirect for phishing.
|
|
var safe = !string.IsNullOrEmpty(returnUrl) && Url.IsLocalUrl(returnUrl) ? returnUrl : "/app";
|
|
return Challenge(new AuthenticationProperties { RedirectUri = safe }, GoogleDefaults.AuthenticationScheme);
|
|
}
|
|
|
|
[HttpPost("logout")]
|
|
[Authorize]
|
|
public async Task<IActionResult> Logout()
|
|
{
|
|
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
|
|
return NoContent();
|
|
}
|
|
|
|
/// <summary>Returns the currently signed-in user, or 401.</summary>
|
|
[HttpGet("me")]
|
|
[Authorize]
|
|
public IActionResult Me() => Ok(new
|
|
{
|
|
UserId = User.FindFirstValue("inboxintel:uid"),
|
|
Email = User.FindFirstValue(ClaimTypes.Email),
|
|
Name = User.FindFirstValue(ClaimTypes.Name)
|
|
});
|
|
}
|