diff --git a/Directory.Build.props b/Directory.Build.props
new file mode 100644
index 00000000..051dba7a
--- /dev/null
+++ b/Directory.Build.props
@@ -0,0 +1,5 @@
+
+
+ Yavsc
+
+
diff --git a/Directory.Packages.props b/Directory.Packages.props
index 076da407..151e6135 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -59,4 +59,4 @@
-
\ No newline at end of file
+
diff --git a/src/Abstract/Constants.cs b/src/Abstract/Constants.cs
index caa0398c..fad2d621 100644
--- a/src/Abstract/Constants.cs
+++ b/src/Abstract/Constants.cs
@@ -23,6 +23,8 @@ namespace Yavsc
public const string LoginPath = "/signin";
public const string LogoutPath = "/signout";
+ public const string AccessDeniedPath = "/Account/AccessDenied";
+
public const string UserFilesPath = "/files";
public const string AvatarsPath = "/avatars";
public const string GitPath = "/sources";
@@ -38,6 +40,7 @@ namespace Yavsc
public const string DefaultAvatar = "/images/Users/icon_user.png";
public const string AnonAvatar = "/images/Users/icon_anon_user.png";
public const string YavscConnectionStringEnvName = "YAVSC_CONNECTION_STRING";
+ public const string YavscConnectionStringName = "YavscConnection";
// at the end, let 4*4 bytes in peace
public const int WebSocketsMaxBufLen = 4096;
diff --git a/src/Org/Controllers/Accounting/AccountController.cs b/src/Org/Controllers/Accounting/AccountController.cs
index 156c8010..1b61d9cf 100644
--- a/src/Org/Controllers/Accounting/AccountController.cs
+++ b/src/Org/Controllers/Accounting/AccountController.cs
@@ -29,6 +29,7 @@ using System.Text.Unicode;
using System.Text;
using Yavsc.Server.Helpers;
using System.Reflection;
+using Microsoft.AspNetCore.Authentication.Cookies;
namespace Yavsc.Controllers
{
@@ -485,7 +486,8 @@ namespace Yavsc.Controllers
if (result.Succeeded)
{
- return Redirect(model.ReturnUrl ?? "/");
+ // Redirect to returnUrl (ensure it's local to prevent open redirects)
+ return LocalRedirect(model.ReturnUrl);
}
if (result.RequiresTwoFactor)
@@ -503,8 +505,6 @@ namespace Yavsc.Controllers
return this.ViewOk(model);
}
}
-
-
// If we got this far, something failed, redisplay form
ModelState.AddModelError(string.Empty, "Unexpected behavior: something failed ... you could try again, or contact me ...");
}
diff --git a/src/Org/Extensions/HostingExtensions.cs b/src/Org/Extensions/HostingExtensions.cs
index 6883bf1f..8946ea6f 100644
--- a/src/Org/Extensions/HostingExtensions.cs
+++ b/src/Org/Extensions/HostingExtensions.cs
@@ -41,6 +41,7 @@ using System.IdentityModel.Tokens.Jwt;
using IdentityServer8.EntityFramework.Stores;
using IdentityServer8.EntityFramework.Services;
using IdentityServer8.EntityFramework.Interfaces;
+using Microsoft.AspNetCore.Authentication.Cookies;
namespace Yavsc.Extensions;
@@ -135,16 +136,15 @@ public static class HostingExtensions
IServiceCollection services = builder.Services;
services.AddDbContext(options =>
{
- options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection"),
- options => options.MigrationsAssembly("Yavsc")
- );
- }
- );
+ options.UseNpgsql(builder.Configuration.GetConnectionString(Constants.YavscConnectionStringName ),
+ options => options.MigrationsAssembly(typeof(Program).Assembly));
+ });
return services.AddIdentity(
options =>
{
- options.SignIn.RequireConfirmedAccount = true;
+ options.SignIn.RequireConfirmedAccount = builder.Environment.IsEnvironment(
+ builder.Environment.EnvironmentName);
options.ClaimsIdentity.UserNameClaimType = JwtClaimTypes.PreferredUserName;
options.ClaimsIdentity.RoleClaimType = Constants.RoleClaimType;
}
@@ -204,7 +204,7 @@ public static class HostingExtensions
// OAuth2AppSettings
var googleAuthSettings = builder.Configuration.GetSection("Authentication:Google");
- //LoadGoogleConfig(builder.Configuration);
+ LoadGoogleConfig(builder.Configuration);
var services = builder.Services;
@@ -245,7 +245,7 @@ public static class HostingExtensions
private static IIdentityServerBuilder AddIdentityServer(WebApplicationBuilder builder)
{
var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;
- var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
+ var connectionString = builder.Configuration.GetConnectionString(Constants.YavscConnectionStringName);
var identityServerBuilder = builder.Services.AddIdentityServer(options =>
{
@@ -276,6 +276,20 @@ public static class HostingExtensions
sql => sql.MigrationsAssembly(migrationsAssembly));
});
+ builder.Services.AddAuthentication(
+ CookieAuthenticationDefaults.AuthenticationScheme)
+.AddCookie(options =>
+{
+ options.LoginPath = Constants.LoginPath; // Redirect here if unauthenticated
+ options.AccessDeniedPath = Constants.AccessDeniedPath;
+ options.Cookie.SecurePolicy = builder.Environment.IsDevelopment()
+ ? CookieSecurePolicy.None
+ : CookieSecurePolicy.Always; // Use HTTPS in production
+ options.Cookie.SameSite = Microsoft.AspNetCore.Http.SameSiteMode.Lax; // Allows cross-site top-level navigation
+ options.ExpireTimeSpan = TimeSpan.FromMinutes(30); // Cookie expires in 30 mins
+ options.SlidingExpiration = true; // Renew cookie if user is active
+});
+
builder.Services.Configure(options =>
{
options.ClaimsIdentity.UserIdClaimType = JwtClaimTypes.Subject;
@@ -290,7 +304,6 @@ public static class HostingExtensions
else
{
var path = builder.Configuration["SigningCert:Path"];
- var pass = builder.Configuration["SigningCert:Password"];
if (path == null)
throw new InvalidConfigurationException("No signing cert path");
FileInfo certFileInfo = new FileInfo(path);
@@ -312,16 +325,16 @@ public static class HostingExtensions
{
CultureInfo[] supportedCultures = new[]
{
- new CultureInfo("en"),
- new CultureInfo("fr"),
- new CultureInfo("pt")
+ new CultureInfo("en"),
+ new CultureInfo("fr"),
+ new CultureInfo("pt")
};
CultureInfo[] supportedUICultures = new[]
{
- new CultureInfo("fr"),
- new CultureInfo("en"),
- new CultureInfo("pt")
+ new CultureInfo("fr"),
+ new CultureInfo("en"),
+ new CultureInfo("pt")
};
// You must explicitly state which cultures your application supports.
@@ -332,11 +345,11 @@ public static class HostingExtensions
options.SupportedUICultures = supportedUICultures;
options.RequestCultureProviders = new List
- {
- new QueryStringRequestCultureProvider { Options = options },
- new CookieRequestCultureProvider { Options = options, CookieName="ASPNET_CULTURE" },
- new AcceptLanguageHeaderRequestCultureProvider { Options = options }
- };
+ {
+ new QueryStringRequestCultureProvider { Options = options },
+ new CookieRequestCultureProvider { Options = options, CookieName="ASPNET_CULTURE" },
+ new AcceptLanguageHeaderRequestCultureProvider { Options = options }
+ };
});
}
diff --git a/src/Org/Org.csproj b/src/Org/Org.csproj
index 383367b0..0fef8617 100644
--- a/src/Org/Org.csproj
+++ b/src/Org/Org.csproj
@@ -50,4 +50,4 @@
-
\ No newline at end of file
+
diff --git a/src/Org/appsettings.json b/src/Org/appsettings.json
index fd7cdb1f..6d07e28e 100644
--- a/src/Org/appsettings.json
+++ b/src/Org/appsettings.json
@@ -9,7 +9,7 @@
},
"AllowedHosts": "*",
"ConnectionStrings": {
- "DefaultConnection": "Server=[YOURSERVERNAME];Port=5432;Database=[YOURDBNAME];Username=[YOURDBUSERNAME];Password=[YOURDBPASSW];"
+ "YavscConnection": "Server=[YOURSERVERNAME];Port=5432;Database=[YOURDBNAME];Username=[YOURDBUSERNAME];Password=[YOURDBPASSW];"
},
"Site": {
"Title": "Yavsc",
diff --git a/src/Server/Models/ApplicationDbContext.cs b/src/Server/Models/ApplicationDbContext.cs
index 74163c52..66043647 100644
--- a/src/Server/Models/ApplicationDbContext.cs
+++ b/src/Server/Models/ApplicationDbContext.cs
@@ -86,13 +86,6 @@ namespace Yavsc.Models
builder.Entity().Property(a => a.ParentCode).IsRequired(false);
// builder.Entity>().HasKey(i=> new { i.LoginProvider, i.UserId, i.ProviderKey });
}
- protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
- {
- string? envCxStr = Environment.GetEnvironmentVariable(Constants.YavscConnectionStringEnvName);
- if (envCxStr != null)
- optionsBuilder.UseNpgsql(envCxStr);
- base.OnConfiguring(optionsBuilder);
- }
///
/// Activities referenced on this site
diff --git a/test/yavscTests/appsettings.json b/test/yavscTests/appsettings.json
index 383712b6..e0b05b6e 100644
--- a/test/yavscTests/appsettings.json
+++ b/test/yavscTests/appsettings.json
@@ -41,7 +41,7 @@
}
},
"ConnectionStrings": {
- "DefaultConnection": "Server=lame-NpgsqlHostName;Port=5432;Database=lame-DataBase;Username=lame-Username;Password=lame-dbPassword;",
+ "YavscConnection": "Server=lame-NpgsqlHostName;Port=5432;Database=lame-DataBase;Username=lame-Username;Password=lame-dbPassword;",
},
"DataProtection": {
"Keys": {