refactoring email verification
This commit is contained in:
parent
0aed11e71c
commit
ee682516c3
|
@ -50,15 +50,24 @@
|
|||
public string Password = "";
|
||||
public bool Remember = false;
|
||||
|
||||
protected override void OnInitialized()
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
if (PageState.QueryString.ContainsKey("returnurl"))
|
||||
{
|
||||
ReturnUrl = PageState.QueryString["returnurl"];
|
||||
}
|
||||
if (PageState.QueryString.ContainsKey("verified"))
|
||||
if (PageState.QueryString.ContainsKey("name"))
|
||||
{
|
||||
if (PageState.QueryString["verified"] == "1")
|
||||
Username = PageState.QueryString["name"];
|
||||
}
|
||||
if (PageState.QueryString.ContainsKey("token"))
|
||||
{
|
||||
User user = new User();
|
||||
user.SiteId = PageState.Site.SiteId;
|
||||
user.Username = Username;
|
||||
user = await UserService.VerifyEmailAsync(user, PageState.QueryString["token"]);
|
||||
|
||||
if (user != null)
|
||||
{
|
||||
Message = "User Account Verified Successfully. You Can Now Login With Your Username And Password Below.";
|
||||
}
|
||||
|
@ -141,8 +150,8 @@
|
|||
}
|
||||
else
|
||||
{
|
||||
Message = "Please Enter The Username Related To Your Account And Then Click The Forgot Password Option";
|
||||
Message = "Please Enter The Username Related To Your Account And Then Select The Forgot Password Option Again";
|
||||
}
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,6 @@
|
|||
User user = new User();
|
||||
user.SiteId = PageState.Site.SiteId;
|
||||
user.Username = Username;
|
||||
user.DisplayName = Username;
|
||||
user.Password = Password;
|
||||
user = await UserService.ResetPasswordAsync(user, PageState.QueryString["token"]);
|
||||
|
||||
|
|
|
@ -78,8 +78,7 @@ else
|
|||
string modifiedby;
|
||||
DateTime modifiedon;
|
||||
|
||||
protected override async Task
|
||||
OnAfterRenderAsync(bool firstRender)
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "An Error Occurred Loading Html/Text Content. " + ex.Message);
|
||||
AddModuleMessage(ex.Message, MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,8 @@ namespace Oqtane.Services
|
|||
|
||||
Task LogoutUserAsync(User User);
|
||||
|
||||
Task<User> VerifyEmailAsync(User User, string Token);
|
||||
|
||||
Task ForgotPasswordAsync(User User);
|
||||
|
||||
Task<User> ResetPasswordAsync(User User, string Token);
|
||||
|
|
|
@ -87,6 +87,11 @@ namespace Oqtane.Services
|
|||
await http.PostJsonAsync(apiurl + "/logout", User);
|
||||
}
|
||||
|
||||
public async Task<User> VerifyEmailAsync(User User, string Token)
|
||||
{
|
||||
return await http.PostJsonAsync<User>(apiurl + "/verify?token=" + Token, User);
|
||||
}
|
||||
|
||||
public async Task ForgotPasswordAsync(User User)
|
||||
{
|
||||
await http.PostJsonAsync(apiurl + "/forgot", User);
|
||||
|
|
|
@ -38,7 +38,7 @@ namespace Oqtane.Controllers
|
|||
}
|
||||
}
|
||||
|
||||
// GET api/<controller>/5?userid=x
|
||||
// GET api/<controller>/5
|
||||
[HttpGet("{id}")]
|
||||
public Folder Get(int id)
|
||||
{
|
||||
|
|
|
@ -108,8 +108,7 @@ namespace Oqtane.Controllers
|
|||
notification.ToEmail = "";
|
||||
notification.Subject = "User Account Verification";
|
||||
string token = await IdentityUserManager.GenerateEmailConfirmationTokenAsync(identityuser);
|
||||
string alias = Tenants.GetAlias().Path;
|
||||
string url = HttpContext.Request.Scheme + "://" + HttpContext.Request.Host + "/pages/verify?name=" + User.Username + "&token=" + WebUtility.UrlEncode(token) + "&returnurl=" + (alias == "" ? "/" : alias);
|
||||
string url = HttpContext.Request.Scheme + "://" + Tenants.GetAlias().Name + "/login?name=" + User.Username + "&token=" + WebUtility.UrlEncode(token);
|
||||
notification.Body = "Dear " + User.DisplayName + ",\n\nIn Order To Complete The Registration Of Your User Account Please Click The Link Displayed Below:\n\n" + url + "\n\nThank You!";
|
||||
notification.ParentId = null;
|
||||
notification.CreatedOn = DateTime.Now;
|
||||
|
@ -254,6 +253,35 @@ namespace Oqtane.Controllers
|
|||
logger.Log(LogLevel.Information, this, LogFunction.Security, "User Logout {Username}", User.Username);
|
||||
}
|
||||
|
||||
// POST api/<controller>/verify
|
||||
[HttpPost("verify")]
|
||||
public async Task<User> Verify([FromBody] User User, string token)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
IdentityUser identityuser = await IdentityUserManager.FindByNameAsync(User.Username);
|
||||
if (identityuser != null)
|
||||
{
|
||||
var result = await IdentityUserManager.ConfirmEmailAsync(identityuser, token);
|
||||
if (result.Succeeded)
|
||||
{
|
||||
logger.Log(LogLevel.Information, this, LogFunction.Security, "Email Verified For {Username}", User.Username);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Log(LogLevel.Error, this, LogFunction.Security, "Email Verification Failed For {Username}", User.Username);
|
||||
User = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Log(LogLevel.Error, this, LogFunction.Security, "Email Verification Failed For {Username}", User.Username);
|
||||
User = null;
|
||||
}
|
||||
}
|
||||
return User;
|
||||
}
|
||||
|
||||
// POST api/<controller>/forgot
|
||||
[HttpPost("forgot")]
|
||||
public async Task Forgot([FromBody] User User)
|
||||
|
@ -290,7 +318,6 @@ namespace Oqtane.Controllers
|
|||
[HttpPost("reset")]
|
||||
public async Task<User> Reset([FromBody] User User, string token)
|
||||
{
|
||||
User user = null;
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
IdentityUser identityuser = await IdentityUserManager.FindByNameAsync(User.Username);
|
||||
|
@ -299,21 +326,22 @@ namespace Oqtane.Controllers
|
|||
var result = await IdentityUserManager.ResetPasswordAsync(identityuser, token, User.Password);
|
||||
if (result.Succeeded)
|
||||
{
|
||||
user = User;
|
||||
user.Password = "";
|
||||
logger.Log(LogLevel.Information, this, LogFunction.Security, "Password Reset For {Username}", User.Username);
|
||||
User.Password = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Log(LogLevel.Error, this, LogFunction.Security, "Password Reset Failed For {Username}", User.Username);
|
||||
User = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Log(LogLevel.Error, this, LogFunction.Security, "Password Reset Failed For {Username}", User.Username);
|
||||
User = null;
|
||||
}
|
||||
}
|
||||
return user;
|
||||
return User;
|
||||
}
|
||||
|
||||
// GET api/<controller>/current
|
||||
|
|
|
@ -37,6 +37,10 @@ namespace Oqtane.Pages
|
|||
await IdentitySignInManager.SignInAsync(identityuser, remember);
|
||||
}
|
||||
|
||||
if (returnurl == null)
|
||||
{
|
||||
returnurl = "";
|
||||
}
|
||||
if (!returnurl.StartsWith("/"))
|
||||
{
|
||||
returnurl = "/" + returnurl;
|
||||
|
|
|
@ -14,6 +14,10 @@ namespace Oqtane.Pages
|
|||
{
|
||||
await HttpContext.SignOutAsync(IdentityConstants.ApplicationScheme);
|
||||
|
||||
if (returnurl == null)
|
||||
{
|
||||
returnurl = "";
|
||||
}
|
||||
if (!returnurl.StartsWith("/"))
|
||||
{
|
||||
returnurl = "/" + returnurl;
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
@page "/pages/verify"
|
||||
@namespace Oqtane.Pages
|
||||
@model Oqtane.Pages.VerifyModel
|
|
@ -1,42 +0,0 @@
|
|||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
using Oqtane.Models;
|
||||
using Oqtane.Repository;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Oqtane.Pages
|
||||
{
|
||||
[AllowAnonymous]
|
||||
public class VerifyModel : PageModel
|
||||
{
|
||||
private readonly IUserRepository Users;
|
||||
private readonly UserManager<IdentityUser> IdentityUserManager;
|
||||
|
||||
public VerifyModel(IUserRepository Users, UserManager<IdentityUser> IdentityUserManager)
|
||||
{
|
||||
this.Users = Users;
|
||||
this.IdentityUserManager = IdentityUserManager;
|
||||
}
|
||||
|
||||
public async Task<IActionResult> OnGet(string name, string token, string returnurl)
|
||||
{
|
||||
int verified = 0;
|
||||
IdentityUser identityuser = await IdentityUserManager.FindByNameAsync(name);
|
||||
if (identityuser != null)
|
||||
{
|
||||
var result = await IdentityUserManager.ConfirmEmailAsync(identityuser, token);
|
||||
if (result.Succeeded)
|
||||
{
|
||||
verified = 1;
|
||||
}
|
||||
}
|
||||
if (!returnurl.StartsWith("/"))
|
||||
{
|
||||
returnurl += "/" + returnurl;
|
||||
}
|
||||
return Redirect(HttpContext.Request.Scheme + "://" + HttpContext.Request.Host + returnurl + "login?verified=" + verified.ToString());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,6 +19,7 @@ namespace Oqtane.Repository
|
|||
public virtual DbSet<Log> Log { get; set; }
|
||||
public virtual DbSet<Notification> Notification { get; set; }
|
||||
public virtual DbSet<Folder> Folder { get; set; }
|
||||
public virtual DbSet<File> File { get; set; }
|
||||
|
||||
public TenantDBContext(ITenantResolver TenantResolver, IHttpContextAccessor accessor) : base(TenantResolver, accessor)
|
||||
{
|
||||
|
|
62
Oqtane.Server/Repository/FileRepository.cs
Normal file
62
Oqtane.Server/Repository/FileRepository.cs
Normal file
|
@ -0,0 +1,62 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Oqtane.Models;
|
||||
|
||||
namespace Oqtane.Repository
|
||||
{
|
||||
public class FileRepository : IFileRepository
|
||||
{
|
||||
private TenantDBContext db;
|
||||
private readonly IPermissionRepository Permissions;
|
||||
|
||||
public FileRepository(TenantDBContext context, IPermissionRepository Permissions)
|
||||
{
|
||||
db = context;
|
||||
this.Permissions = Permissions;
|
||||
}
|
||||
|
||||
public IEnumerable<File> GetFiles(int FolderId)
|
||||
{
|
||||
IEnumerable<Permission> permissions = Permissions.GetPermissions("Folder", FolderId);
|
||||
IEnumerable<File> files = db.File.Where(item => item.FolderId == FolderId);
|
||||
foreach (File file in files)
|
||||
{
|
||||
file.Folder.Permissions = Permissions.EncodePermissions(FolderId, permissions);
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
public File AddFile(File File)
|
||||
{
|
||||
db.File.Add(File);
|
||||
db.SaveChanges();
|
||||
return File;
|
||||
}
|
||||
|
||||
public File UpdateFile(File File)
|
||||
{
|
||||
db.Entry(File).State = EntityState.Modified;
|
||||
db.SaveChanges();
|
||||
return File;
|
||||
}
|
||||
|
||||
public File GetFile(int FileId)
|
||||
{
|
||||
File file = db.File.Find(FileId);
|
||||
if (file != null)
|
||||
{
|
||||
IEnumerable<Permission> permissions = Permissions.GetPermissions("Folder", file.FolderId);
|
||||
file.Folder.Permissions = Permissions.EncodePermissions(file.FolderId, permissions);
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
public void DeleteFile(int FileId)
|
||||
{
|
||||
File File = db.File.Find(FileId);
|
||||
db.File.Remove(File);
|
||||
db.SaveChanges();
|
||||
}
|
||||
}
|
||||
}
|
14
Oqtane.Server/Repository/Interfaces/IFileRepository.cs
Normal file
14
Oqtane.Server/Repository/Interfaces/IFileRepository.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using System.Collections.Generic;
|
||||
using Oqtane.Models;
|
||||
|
||||
namespace Oqtane.Repository
|
||||
{
|
||||
public interface IFileRepository
|
||||
{
|
||||
IEnumerable<File> GetFiles(int FolderId);
|
||||
File AddFile(File File);
|
||||
File UpdateFile(File File);
|
||||
File GetFile(int FileId);
|
||||
void DeleteFile(int FileId);
|
||||
}
|
||||
}
|
|
@ -275,6 +275,24 @@ CREATE TABLE [dbo].[Folder](
|
|||
)
|
||||
GO
|
||||
|
||||
CREATE TABLE [dbo].[File](
|
||||
[FileId] [int] IDENTITY(1,1) NOT NULL,
|
||||
[FolderId] [int] NOT NULL,
|
||||
[Name] [nvarchar](50) NOT NULL,
|
||||
[CreatedBy] [nvarchar](256) NOT NULL,
|
||||
[CreatedOn] [datetime] NOT NULL,
|
||||
[ModifiedBy] [nvarchar](256) NOT NULL,
|
||||
[ModifiedOn] [datetime] NOT NULL,
|
||||
[DeletedBy] [nvarchar](256) NULL,
|
||||
[DeletedOn] [datetime] NULL,
|
||||
[IsDeleted][bit] NOT NULL,
|
||||
CONSTRAINT [PK_File] PRIMARY KEY CLUSTERED
|
||||
(
|
||||
[FileId] ASC
|
||||
)
|
||||
)
|
||||
GO
|
||||
|
||||
CREATE TABLE [dbo].[HtmlText](
|
||||
[HtmlTextId] [int] IDENTITY(1,1) NOT NULL,
|
||||
[ModuleId] [int] NOT NULL,
|
||||
|
@ -361,6 +379,11 @@ REFERENCES [dbo].[Site] ([SiteId])
|
|||
ON DELETE CASCADE
|
||||
GO
|
||||
|
||||
ALTER TABLE [dbo].[File] WITH CHECK ADD CONSTRAINT [FK_File_Folder] FOREIGN KEY([FolderId])
|
||||
REFERENCES [dbo].[Folder] ([FolderId])
|
||||
ON DELETE CASCADE
|
||||
GO
|
||||
|
||||
ALTER TABLE [dbo].[HtmlText] WITH CHECK ADD CONSTRAINT [FK_HtmlText_Module] FOREIGN KEY([ModuleId])
|
||||
REFERENCES [dbo].[Module] ([ModuleId])
|
||||
ON DELETE CASCADE
|
||||
|
|
21
Oqtane.Shared/Models/File.cs
Normal file
21
Oqtane.Shared/Models/File.cs
Normal file
|
@ -0,0 +1,21 @@
|
|||
using System;
|
||||
|
||||
namespace Oqtane.Models
|
||||
{
|
||||
public class File : IAuditable
|
||||
{
|
||||
public int FileId { get; set; }
|
||||
public int FolderId { get; set; }
|
||||
public string Name { get; set; }
|
||||
|
||||
public string CreatedBy { get; set; }
|
||||
public DateTime CreatedOn { get; set; }
|
||||
public string ModifiedBy { get; set; }
|
||||
public DateTime ModifiedOn { get; set; }
|
||||
public string DeletedBy { get; set; }
|
||||
public DateTime? DeletedOn { get; set; }
|
||||
public bool IsDeleted { get; set; }
|
||||
|
||||
public Folder Folder { get; set; }
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user