using Microsoft.AspNetCore.Http; namespace JobTrackerApi.Services; public static class AuthSessionOptions { public const string SessionCookieName = "jobtracker_auth"; public const string CsrfCookieName = "XSRF-TOKEN"; public const string CsrfHeaderName = "X-CSRF-TOKEN"; public const string TrustedDeviceCookieName = "jobtracker_td"; public static CookieOptions BuildSessionCookie(bool persistent, bool secure) { var options = new CookieOptions { HttpOnly = true, IsEssential = true, SameSite = SameSiteMode.Lax, Secure = secure, Path = "/", }; if (persistent) { options.Expires = DateTimeOffset.UtcNow.AddDays(30); options.MaxAge = TimeSpan.FromDays(30); } return options; } public static CookieOptions BuildCsrfCookie(bool persistent, bool secure) { var options = new CookieOptions { HttpOnly = false, IsEssential = true, SameSite = SameSiteMode.Lax, Secure = secure, Path = "/", }; if (persistent) { options.Expires = DateTimeOffset.UtcNow.AddDays(30); options.MaxAge = TimeSpan.FromDays(30); } return options; } public static CookieOptions BuildExpiredCookie(bool secure) { return new CookieOptions { HttpOnly = true, IsEssential = true, SameSite = SameSiteMode.Lax, Secure = secure, Path = "/", Expires = DateTimeOffset.UnixEpoch, MaxAge = TimeSpan.Zero, }; } public static CookieOptions BuildExpiredReadableCookie(bool secure) { return new CookieOptions { HttpOnly = false, IsEssential = true, SameSite = SameSiteMode.Lax, Secure = secure, Path = "/", Expires = DateTimeOffset.UnixEpoch, MaxAge = TimeSpan.Zero, }; } // Stricter than the session cookie (SameSite=Strict, never HttpOnly=false): this cookie's // only job is "skip the 2FA prompt", so it must never be readable by JS and should not even // be sent on cross-site navigations. public static CookieOptions BuildTrustedDeviceCookie(bool secure) { return new CookieOptions { HttpOnly = true, IsEssential = true, SameSite = SameSiteMode.Strict, Secure = secure, Path = "/", Expires = DateTimeOffset.UtcNow.AddDays(30), MaxAge = TimeSpan.FromDays(30), }; } public static CookieOptions BuildExpiredTrustedDeviceCookie(bool secure) { return new CookieOptions { HttpOnly = true, IsEssential = true, SameSite = SameSiteMode.Strict, Secure = secure, Path = "/", Expires = DateTimeOffset.UnixEpoch, MaxAge = TimeSpan.Zero, }; } }