diff --git a/.config/identity.env b/.config/identity.env
index 8261da9..5bb4d0b 100644
--- a/.config/identity.env
+++ b/.config/identity.env
@@ -5,17 +5,12 @@ IdentityHost=https://pixel.docker.localhost/pauth
#Plugin configuration
Plugins__Collection__0__Type=EmailSender
Plugins__Collection__0__Path=Plugins/Messenger
-Plugins__Collection__0__Name=Pixel.Identity.Messenger.Email
+Plugins__Collection__0__Name=Pixel.Identity.Messenger.Console
Plugins__Collection__1__Type=DbStore
Plugins__Collection__1__Path=Plugins/DbStore
Plugins__Collection__1__Name=Pixel.Identity.Store.PostgreSQL
-#SMTP configuration for sending mails
-SMTP_Host=smtp.ethereal.email
-SMTP_Port=587
-SMTP_UserName=
-SMTP_Password=
-SMTP_From=admin@pixel.com
+IdentityOptions_SignIn_RequireConfirmedAccount=false
ConnectionStrings__PostgreServerConnection=User ID=postgresadmin;Password=postgrespass;Server=postgres;Port=5432;Database=pixel_identity_db;
diff --git a/Pixel.Identity.sln b/Pixel.Identity.sln
index a6e30e5..bf61723 100644
--- a/Pixel.Identity.sln
+++ b/Pixel.Identity.sln
@@ -23,6 +23,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Pixel.Identity.Store.Sql.Sh
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Pixel.Identity.Store.SqlServer", "src\Pixel.Identity.Store.SqlServer\Pixel.Identity.Store.SqlServer.csproj", "{E67F20E6-B228-467A-9C40-1B38EAD35367}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Pixel.Identity.Messenger.Console", "src\Pixel.Identity.Messenger.Console\Pixel.Identity.Messenger.Console.csproj", "{137631D2-6F14-43A2-885D-F61C63B7058C}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -153,6 +155,18 @@ Global
{E67F20E6-B228-467A-9C40-1B38EAD35367}.Release|x64.Build.0 = Release|Any CPU
{E67F20E6-B228-467A-9C40-1B38EAD35367}.Release|x86.ActiveCfg = Release|Any CPU
{E67F20E6-B228-467A-9C40-1B38EAD35367}.Release|x86.Build.0 = Release|Any CPU
+ {137631D2-6F14-43A2-885D-F61C63B7058C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {137631D2-6F14-43A2-885D-F61C63B7058C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {137631D2-6F14-43A2-885D-F61C63B7058C}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {137631D2-6F14-43A2-885D-F61C63B7058C}.Debug|x64.Build.0 = Debug|Any CPU
+ {137631D2-6F14-43A2-885D-F61C63B7058C}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {137631D2-6F14-43A2-885D-F61C63B7058C}.Debug|x86.Build.0 = Debug|Any CPU
+ {137631D2-6F14-43A2-885D-F61C63B7058C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {137631D2-6F14-43A2-885D-F61C63B7058C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {137631D2-6F14-43A2-885D-F61C63B7058C}.Release|x64.ActiveCfg = Release|Any CPU
+ {137631D2-6F14-43A2-885D-F61C63B7058C}.Release|x64.Build.0 = Release|Any CPU
+ {137631D2-6F14-43A2-885D-F61C63B7058C}.Release|x86.ActiveCfg = Release|Any CPU
+ {137631D2-6F14-43A2-885D-F61C63B7058C}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/src/Pixel.Identity.Messenger.Console/EmailSender.cs b/src/Pixel.Identity.Messenger.Console/EmailSender.cs
new file mode 100644
index 0000000..d03dbc1
--- /dev/null
+++ b/src/Pixel.Identity.Messenger.Console/EmailSender.cs
@@ -0,0 +1,31 @@
+using Microsoft.Extensions.Logging;
+using Pixel.Identity.Core;
+using System.Text;
+
+namespace Pixel.Identity.Messenger.Console;
+
+///
+/// implementation that prints the message as information
+/// on console and log and doesn't actually send the mail.
+///
+public class EmailSender : IEmailSender
+{
+ private readonly ILogger logger;
+
+ public EmailSender(ILogger logger)
+ {
+ this.logger = logger;
+ }
+
+ public Task SendEmailAsync(string email, string subject, string htmlMessage)
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.AppendLine($"----------------------------------------------------");
+ sb.AppendLine($"{email}:{subject}");
+ sb.AppendLine("message:[redacted]");
+ sb.AppendLine($"----------------------------------------------------");
+ this.logger.LogInformation(sb.ToString());
+ System.Console.WriteLine(sb.ToString());
+ return Task.CompletedTask;
+ }
+}
diff --git a/src/Pixel.Identity.Messenger.Console/EmailSenderPlugin.cs b/src/Pixel.Identity.Messenger.Console/EmailSenderPlugin.cs
new file mode 100644
index 0000000..4e4425e
--- /dev/null
+++ b/src/Pixel.Identity.Messenger.Console/EmailSenderPlugin.cs
@@ -0,0 +1,14 @@
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Pixel.Identity.Core;
+using Pixel.Identity.Core.Plugins;
+
+namespace Pixel.Identity.Messenger.Console;
+
+public class EmailSenderPlugin : IServicePlugin
+{
+ public void ConfigureService(IServiceCollection services, IConfiguration configuration)
+ {
+ services.AddTransient();
+ }
+}
diff --git a/src/Pixel.Identity.Messenger.Console/Pixel.Identity.Messenger.Console.csproj b/src/Pixel.Identity.Messenger.Console/Pixel.Identity.Messenger.Console.csproj
new file mode 100644
index 0000000..de945fc
--- /dev/null
+++ b/src/Pixel.Identity.Messenger.Console/Pixel.Identity.Messenger.Console.csproj
@@ -0,0 +1,13 @@
+
+
+
+ net6.0
+ enable
+ enable
+
+
+
+
+
+
+
diff --git a/src/Pixel.Identity.Provider/Dockerfile b/src/Pixel.Identity.Provider/Dockerfile
index e4f2927..251e88e 100644
--- a/src/Pixel.Identity.Provider/Dockerfile
+++ b/src/Pixel.Identity.Provider/Dockerfile
@@ -16,12 +16,14 @@ COPY ["src/Pixel.Identity.UI.Client/Pixel.Identity.UI.Client.csproj", "src/Pixel
#plugin projects
COPY ["src/Pixel.Identity.Messenger.Email/Pixel.Identity.Messenger.Email.csproj", "src/Pixel.Identity.Messenger.Email/"]
+COPY ["src/Pixel.Identity.Messenger.Console/Pixel.Identity.Messenger.Console.csproj", "src/Pixel.Identity.Messenger.Console/"]
COPY ["src/Pixel.Identity.Store.Sql.Shared/Pixel.Identity.Store.Sql.Shared.csproj", "src/Pixel.Identity.Store.Sql.Shared/"]
COPY ["src/Pixel.Identity.Store.SqlServer/Pixel.Identity.Store.SqlServer.csproj", "src/Pixel.Identity.Store.SqlServer/"]
COPY ["src/Pixel.Identity.Store.PostgreSQL/Pixel.Identity.Store.PostgreSQL.csproj", "src/Pixel.Identity.Store.PostgreSQL/"]
COPY ["src/Pixel.Identity.Store.Mongo/Pixel.Identity.Store.Mongo.csproj", "src/Pixel.Identity.Store.Mongo/"]
RUN dotnet restore "src/Pixel.Identity.Messenger.Email/Pixel.Identity.Messenger.Email.csproj"
+RUN dotnet restore "src/Pixel.Identity.Messenger.Console/Pixel.Identity.Messenger.Console.csproj"
RUN dotnet restore "src/Pixel.Identity.Provider/Pixel.Identity.Provider.csproj"
RUN dotnet restore "src/Pixel.Identity.Store.Mongo/Pixel.Identity.Store.Mongo.csproj"
RUN dotnet restore "src/Pixel.Identity.Store.SqlServer/Pixel.Identity.Store.SqlServer.csproj"
diff --git a/src/Pixel.Identity.Provider/Pixel.Identity.Provider.csproj b/src/Pixel.Identity.Provider/Pixel.Identity.Provider.csproj
index 5ae4fe4..e3f20e1 100644
--- a/src/Pixel.Identity.Provider/Pixel.Identity.Provider.csproj
+++ b/src/Pixel.Identity.Provider/Pixel.Identity.Provider.csproj
@@ -50,7 +50,8 @@
-
+
+
diff --git a/src/Pixel.Identity.Provider/appsettings.Development.json b/src/Pixel.Identity.Provider/appsettings.Development.json
index 9bda565..21766c0 100644
--- a/src/Pixel.Identity.Provider/appsettings.Development.json
+++ b/src/Pixel.Identity.Provider/appsettings.Development.json
@@ -10,16 +10,21 @@
"Collection": [
{
"Type": "EmailSender",
- "Path": "Plugins/Messenger",
- "Name": "Pixel.Identity.Messenger.Email"
+ "Path": "Plugins\\Messenger",
+ "Name": "Pixel.Identity.Messenger.Console"
},
{
"Type": "DbStore",
- "Path": "Plugins/DbStore",
- "Name": "Pixel.Identity.Store.PostgreSQL"
+ "Path": "Plugins\\DbStore",
+ "Name": "Pixel.Identity.Store.Mongo"
}
]
},
+ "IdentityOptions": {
+ "SignIn": {
+ "RequireConfirmedAccount": false
+ }
+ },
"Identity": {
"Certificates": {
"EncryptionCertificatePath": "E:\\Git\\Pixel.Identity\\.certificates\\identity-encryption.pfx",
@@ -28,13 +33,6 @@
"SigningCertificateKey": ""
}
},
- "SMTP": {
- "Host": "smtp.ethereal.email",
- "Port": 587,
- "UserName": "",
- "Password": "",
- "From": "admin@pixel.com"
- },
"ConnectionStrings": {
"SqlServerConnection": "Server=(localdb)\\mssqllocaldb;Database=pixel-identity-db;Trusted_Connection=True;MultipleActiveResultSets=true",
"PostgreServerConnection": "User ID=postgresadmin;Password=postgrespass;Server=postgres;Port=5432;Database=pixel_identity_db;"
diff --git a/src/Pixel.Identity.Store.Mongo/MongoConfigurator.cs b/src/Pixel.Identity.Store.Mongo/MongoConfigurator.cs
index 7848d09..70879b7 100644
--- a/src/Pixel.Identity.Store.Mongo/MongoConfigurator.cs
+++ b/src/Pixel.Identity.Store.Mongo/MongoConfigurator.cs
@@ -49,14 +49,33 @@ public IdentityBuilder ConfigureIdentity(IConfiguration configuration, IServiceC
cm.UnmapMember(m => m.RoleId);
});
+ var identityOptions = new IdentityOptions();
+ configuration.GetSection(nameof(IdentityOptions)).Bind(identityOptions);
+
var mongoDbSettings = configuration.GetSection(nameof(MongoDbSettings)).Get();
return services.AddIdentity(options =>
{
options.ClaimsIdentity.UserNameClaimType = OpenIddict.Abstractions.OpenIddictConstants.Claims.Name;
options.ClaimsIdentity.UserIdClaimType = OpenIddict.Abstractions.OpenIddictConstants.Claims.Subject;
options.ClaimsIdentity.RoleClaimType = OpenIddict.Abstractions.OpenIddictConstants.Claims.Role;
- options.SignIn.RequireConfirmedAccount = true;
- //options.User.RequireUniqueEmail = true;
+
+ options.SignIn.RequireConfirmedPhoneNumber = identityOptions.SignIn.RequireConfirmedPhoneNumber;
+ options.SignIn.RequireConfirmedEmail = identityOptions.SignIn.RequireConfirmedEmail;
+ options.SignIn.RequireConfirmedAccount = identityOptions.SignIn.RequireConfirmedAccount;
+
+ options.User.AllowedUserNameCharacters = identityOptions.User.AllowedUserNameCharacters;
+ options.User.RequireUniqueEmail = identityOptions.User.RequireUniqueEmail;
+
+ options.Password.RequiredLength = identityOptions.Password.RequiredLength;
+ options.Password.RequiredUniqueChars = identityOptions.Password.RequiredUniqueChars;
+ options.Password.RequireNonAlphanumeric = identityOptions.Password.RequireNonAlphanumeric;
+ options.Password.RequireLowercase = identityOptions.Password.RequireLowercase;
+ options.Password.RequireUppercase = identityOptions.Password.RequireUppercase;
+ options.Password.RequireDigit = identityOptions.Password.RequireDigit;
+
+ options.Lockout.AllowedForNewUsers = identityOptions.Lockout.AllowedForNewUsers;
+ options.Lockout.MaxFailedAccessAttempts = identityOptions.Lockout.MaxFailedAccessAttempts;
+ options.Lockout.DefaultLockoutTimeSpan = identityOptions.Lockout.DefaultLockoutTimeSpan;
})
.AddRoles()
.AddMongoDbStore
public IdentityBuilder ConfigureIdentity(IConfiguration configuration, IServiceCollection services)
{
+ var identityOptions = new IdentityOptions();
+ configuration.GetSection(nameof(IdentityOptions)).Bind(identityOptions);
+
return services.AddDbContext(options =>
{
options.UseNpgsql(configuration.GetConnectionString("PostgreServerConnection"));
@@ -44,7 +47,24 @@ public IdentityBuilder ConfigureIdentity(IConfiguration configuration, IServiceC
options.ClaimsIdentity.UserNameClaimType = Claims.Name;
options.ClaimsIdentity.UserIdClaimType = Claims.Subject;
options.ClaimsIdentity.RoleClaimType = Claims.Role;
- options.SignIn.RequireConfirmedAccount = true;
+
+ options.SignIn.RequireConfirmedPhoneNumber = identityOptions.SignIn.RequireConfirmedPhoneNumber;
+ options.SignIn.RequireConfirmedEmail = identityOptions.SignIn.RequireConfirmedEmail;
+ options.SignIn.RequireConfirmedAccount = identityOptions.SignIn.RequireConfirmedAccount;
+
+ options.User.AllowedUserNameCharacters = identityOptions.User.AllowedUserNameCharacters;
+ options.User.RequireUniqueEmail = identityOptions.User.RequireUniqueEmail;
+
+ options.Password.RequiredLength = identityOptions.Password.RequiredLength;
+ options.Password.RequiredUniqueChars = identityOptions.Password.RequiredUniqueChars;
+ options.Password.RequireNonAlphanumeric = identityOptions.Password.RequireNonAlphanumeric;
+ options.Password.RequireLowercase = identityOptions.Password.RequireLowercase;
+ options.Password.RequireUppercase = identityOptions.Password.RequireUppercase;
+ options.Password.RequireDigit = identityOptions.Password.RequireDigit;
+
+ options.Lockout.AllowedForNewUsers = identityOptions.Lockout.AllowedForNewUsers;
+ options.Lockout.MaxFailedAccessAttempts = identityOptions.Lockout.MaxFailedAccessAttempts;
+ options.Lockout.DefaultLockoutTimeSpan = identityOptions.Lockout.DefaultLockoutTimeSpan;
})
.AddRoles()
.AddRoleStore()
diff --git a/src/Pixel.Identity.Store.SqlServer/SqlConfigurator.cs b/src/Pixel.Identity.Store.SqlServer/SqlConfigurator.cs
index 51b10e3..8469878 100644
--- a/src/Pixel.Identity.Store.SqlServer/SqlConfigurator.cs
+++ b/src/Pixel.Identity.Store.SqlServer/SqlConfigurator.cs
@@ -30,6 +30,9 @@ public void ConfigureAutoMap(IServiceCollection services)
///
public IdentityBuilder ConfigureIdentity(IConfiguration configuration, IServiceCollection services)
{
+ var identityOptions = new IdentityOptions();
+ configuration.GetSection(nameof(IdentityOptions)).Bind(identityOptions);
+
return services.AddDbContext(options =>
{
options.UseSqlServer(configuration.GetConnectionString("SqlServerConnection"));
@@ -44,7 +47,24 @@ public IdentityBuilder ConfigureIdentity(IConfiguration configuration, IServiceC
options.ClaimsIdentity.UserNameClaimType = Claims.Name;
options.ClaimsIdentity.UserIdClaimType = Claims.Subject;
options.ClaimsIdentity.RoleClaimType = Claims.Role;
- options.SignIn.RequireConfirmedAccount = true;
+
+ options.SignIn.RequireConfirmedPhoneNumber = identityOptions.SignIn.RequireConfirmedPhoneNumber;
+ options.SignIn.RequireConfirmedEmail = identityOptions.SignIn.RequireConfirmedEmail;
+ options.SignIn.RequireConfirmedAccount = identityOptions.SignIn.RequireConfirmedAccount;
+
+ options.User.AllowedUserNameCharacters = identityOptions.User.AllowedUserNameCharacters;
+ options.User.RequireUniqueEmail = identityOptions.User.RequireUniqueEmail;
+
+ options.Password.RequiredLength = identityOptions.Password.RequiredLength;
+ options.Password.RequiredUniqueChars = identityOptions.Password.RequiredUniqueChars;
+ options.Password.RequireNonAlphanumeric = identityOptions.Password.RequireNonAlphanumeric;
+ options.Password.RequireLowercase = identityOptions.Password.RequireLowercase;
+ options.Password.RequireUppercase = identityOptions.Password.RequireUppercase;
+ options.Password.RequireDigit = identityOptions.Password.RequireDigit;
+
+ options.Lockout.AllowedForNewUsers = identityOptions.Lockout.AllowedForNewUsers;
+ options.Lockout.MaxFailedAccessAttempts = identityOptions.Lockout.MaxFailedAccessAttempts;
+ options.Lockout.DefaultLockoutTimeSpan = identityOptions.Lockout.DefaultLockoutTimeSpan;
})
.AddRoles()
.AddRoleStore()