This commit is contained in:
@@ -1,284 +1,48 @@
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Security.Claims;
|
||||
using MistoxWebsite.Server.Services;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using MistoxWebsite.Server.Services.DatabaseService;
|
||||
using MistoxWebsite.Server.Entities;
|
||||
using System.Text.Json;
|
||||
using System.Text;
|
||||
|
||||
namespace MistoxWebsite.Server.Controllers {
|
||||
[ApiController]
|
||||
[Route("api/account/")]
|
||||
public class AuthenticationController : MistoxControllerBase {
|
||||
|
||||
EmailService _emailContext;
|
||||
public AuthenticationController(DatabaseService db) : base(db) { }
|
||||
|
||||
public AuthenticationController(DatabaseService db, EmailService emailContext) : base(db) {
|
||||
_emailContext = emailContext;
|
||||
[HttpPost("loginstate")]
|
||||
public ActionResult<Account> LoginState() {
|
||||
if (isLoggedIn()) {
|
||||
return Ok(getLoggedInUser());
|
||||
}
|
||||
return NotFound("Not logged in");
|
||||
}
|
||||
|
||||
[Route("login")]
|
||||
[HttpPost]
|
||||
public async Task<ActionResult<Account>> Login([FromForm] string UserName, [FromForm] string PasswordHash, [FromForm] bool StayLoggedIn) {
|
||||
try {
|
||||
Account? test = await _databaseService.GetAccount(UserName.ToLower());
|
||||
if (test != null) {
|
||||
if (test.EmailVerified == true) {
|
||||
if (test.FailedPasswordLock) {
|
||||
if (test.CurrentPasswordAttempts >= test.PasswordAttempts) {
|
||||
return new Account() { Error = "Too many failed password attempts. Please reset your password" };
|
||||
}
|
||||
}
|
||||
if (BCrypt.Net.BCrypt.Verify(PasswordHash, test.PasswordHash)) {
|
||||
test.CurrentPasswordAttempts = 0;
|
||||
await _databaseService.SetAccount(test);
|
||||
|
||||
List<Claim> claims = new List<Claim>() {
|
||||
new Claim("ID", test.ID.ToString())
|
||||
};
|
||||
|
||||
await HttpContext.SignInAsync(
|
||||
CookieAuthenticationDefaults.AuthenticationScheme,
|
||||
new ClaimsPrincipal(new ClaimsIdentity(claims, "Auth")),
|
||||
new AuthenticationProperties {
|
||||
ExpiresUtc = DateTime.UtcNow.AddYears(30), // Add 30 years with sliding on
|
||||
IsPersistent = StayLoggedIn, // Is set from the StayLoggedIn
|
||||
}
|
||||
);
|
||||
return test;
|
||||
}
|
||||
else {
|
||||
test.CurrentPasswordAttempts += 1;
|
||||
await _databaseService.SetAccount(test);
|
||||
return new Account() { Error = "Wrong password" };
|
||||
}
|
||||
}
|
||||
else {
|
||||
await SendVerify(test.UserName);
|
||||
return new Account() { Error = "A new verify email has been sent. \n Note only 1 email send every 5 mintes" };
|
||||
}
|
||||
[HttpPost("loginticket")]
|
||||
public async Task<ActionResult> LoginTicket([FromBody] string LoginToken) {
|
||||
using (HttpClient client = new HttpClient()) {
|
||||
var payload = new { ticket = LoginToken };
|
||||
StringContent jsonPayload = new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json");
|
||||
HttpResponseMessage JWTResponse = await client.PostAsync("https://auth.mistox.com/api/auth/token", jsonPayload);
|
||||
if (JWTResponse.IsSuccessStatusCode) {
|
||||
string JWT = await JWTResponse.Content.ReadAsStringAsync();
|
||||
signIn(JWT);
|
||||
return Ok();
|
||||
} else {
|
||||
string error = await JWTResponse.Content.ReadAsStringAsync();
|
||||
return NotFound(error);
|
||||
}
|
||||
return new Account() { Error = "User doesn't exist" };
|
||||
} catch (Exception ex) {
|
||||
return new Account() { Error = ex.Message };
|
||||
}
|
||||
}
|
||||
|
||||
[Route("register")]
|
||||
[HttpPost]
|
||||
public async Task<ActionResult<Account>> Register([FromForm] string Email, [FromForm] string UserName, [FromForm] string PasswordHash) {
|
||||
try {
|
||||
if (await _databaseService.GetAccount(UserName.ToLower()) == null) {
|
||||
if (await _databaseService.GetAccount(Email.ToLower()) == null) {
|
||||
Account? created = new Account() {
|
||||
UserName = UserName.ToLower(),
|
||||
Email = Email.ToLower(),
|
||||
EmailVerified = false,
|
||||
PasswordHash = BCrypt.Net.BCrypt.HashPassword(PasswordHash),
|
||||
};
|
||||
await _databaseService.SetAccount(created);
|
||||
created = await _databaseService.GetAccount(Email.ToLower());
|
||||
if (created != null) {
|
||||
await SendVerify(created.UserName);
|
||||
return created;
|
||||
}
|
||||
return new Account() { Error = "Unknown Error" };
|
||||
}
|
||||
else {
|
||||
return new Account() { Error = "Email is already in use" };
|
||||
}
|
||||
}
|
||||
else {
|
||||
return new Account() { Error = "UserName is taken" };
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Console.WriteLine("Error: " + ex.Message);
|
||||
return new Account() { Error = ex.Message };
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[Route("changepassword")]
|
||||
[HttpPost]
|
||||
public async Task<ActionResult<bool>> ChangePassword([FromForm] string OldPassword, [FromForm] string NewPassword) {
|
||||
try {
|
||||
if (isLoggedIn()) {
|
||||
Account user = await getLoggedInUser();
|
||||
if (BCrypt.Net.BCrypt.Verify(OldPassword, user.PasswordHash)) {
|
||||
user.PasswordHash = BCrypt.Net.BCrypt.HashPassword(NewPassword);
|
||||
user.CurrentPasswordAttempts = 0;
|
||||
await _databaseService.SetAccount(user);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[Route("toggleaccountlock")]
|
||||
[HttpPost]
|
||||
public async Task<ActionResult<string>> ToggleAccountLock([FromForm] bool AccountLock) {
|
||||
try {
|
||||
if (isLoggedIn()) {
|
||||
Account user = await getLoggedInUser();
|
||||
user.FailedPasswordLock = AccountLock;
|
||||
user.CurrentPasswordAttempts = 0;
|
||||
await _databaseService.SetAccount(user);
|
||||
return "Account Lock Status Updated";
|
||||
}
|
||||
return "Unknown Error Occurred";
|
||||
} catch (Exception ex) {
|
||||
return ex.Message;
|
||||
}
|
||||
}
|
||||
|
||||
[Route("get")]
|
||||
[HttpPost]
|
||||
public async Task<ActionResult<Account?>> Get() {
|
||||
try {
|
||||
if (isLoggedIn()) {
|
||||
return await getLoggedInUser();
|
||||
}
|
||||
return Ok();
|
||||
} catch {
|
||||
return Ok();
|
||||
}
|
||||
}
|
||||
|
||||
[Route("logout")]
|
||||
[HttpPost]
|
||||
public async Task Logout() {
|
||||
await HttpContext.SignOutAsync();
|
||||
}
|
||||
|
||||
[Route("sendverifyemail")]
|
||||
[HttpPost]
|
||||
public async Task<ActionResult<string>> SendVerify([FromForm] string UserName) {
|
||||
try {
|
||||
string key = "v" + UserName;
|
||||
// Stop from sending multiple emails quickly
|
||||
if (_emailContext._SentEmails.ContainsKey(key)) {
|
||||
DateTime PreviousSentTime = _emailContext._SentEmails.GetValueOrDefault(key);
|
||||
if (PreviousSentTime.AddMinutes(5) > DateTime.Now) {
|
||||
return "Cannot sent another verify email until 5 minutes has elapsed ";
|
||||
}
|
||||
else {
|
||||
_emailContext._SentEmails.Remove(key);
|
||||
}
|
||||
}
|
||||
Account? test = await _databaseService.GetAccount(UserName.ToLower());
|
||||
if (test != null) {
|
||||
test.EmailToken = Guid.NewGuid().ToString();
|
||||
await _databaseService.SetAccount(test);
|
||||
|
||||
string EmailContents = EmailService.VerifyEmailEmail;
|
||||
EmailContents = Substitue(EmailContents, "@UserName", UserName);
|
||||
EmailContents = Substitue(EmailContents, "@UserName", UserName);
|
||||
EmailContents = Substitue(EmailContents, "@VerifyPassword", test.EmailToken);
|
||||
|
||||
string result = _emailContext.Send(test.Email, EmailService.VerifyEmailSubject, EmailContents);
|
||||
_emailContext._SentEmails.Add(key, DateTime.Now);
|
||||
return result;
|
||||
}
|
||||
return "Account not found";
|
||||
} catch (Exception) {
|
||||
return "The connection couldn't be established to the email server";
|
||||
}
|
||||
}
|
||||
|
||||
[Route("verifyemail")]
|
||||
[HttpPost]
|
||||
public async Task<ActionResult<bool>> VerifyEmail([FromForm] string UserName, [FromForm] string EmailToken) {
|
||||
try {
|
||||
Account? test = await _databaseService.GetAccount(UserName.ToLower());
|
||||
if (test != null) {
|
||||
if (!string.IsNullOrEmpty(test.EmailToken) && test.EmailToken == EmailToken) {
|
||||
test.EmailToken = "";
|
||||
test.EmailVerified = true;
|
||||
await _databaseService.SetAccount(test);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[Route("sendresetpassword")]
|
||||
[HttpPost]
|
||||
public async Task<ActionResult<string>> ResetPassword([FromForm] string Email) {
|
||||
try {
|
||||
string key = "p" + Email.ToLower();
|
||||
// Stop from sending multiple emails quickly
|
||||
if (_emailContext._SentEmails.ContainsKey(key)) {
|
||||
DateTime PreviousSentTime = _emailContext._SentEmails.GetValueOrDefault(key);
|
||||
if (PreviousSentTime.AddMinutes(5) > DateTime.Now) {
|
||||
return "Cannot sent another reset requests until 5 minutes has elapsed";
|
||||
}
|
||||
else {
|
||||
_emailContext._SentEmails.Remove(key);
|
||||
}
|
||||
}
|
||||
Account? test = await _databaseService.GetAccount(Email.ToLower());
|
||||
if (test != null) {
|
||||
test.EmailToken = Guid.NewGuid().ToString();
|
||||
await _databaseService.SetAccount(test);
|
||||
|
||||
string EmailContents = EmailService.ResetPasswordEmail;
|
||||
EmailContents = Substitue(EmailContents, "@UserName", test.UserName);
|
||||
EmailContents = Substitue(EmailContents, "@UserName", test.UserName);
|
||||
EmailContents = Substitue(EmailContents, "@ResetPassWord", test.EmailToken);
|
||||
|
||||
string result = _emailContext.Send(test.Email, EmailService.VerifyEmailSubject, EmailContents);
|
||||
_emailContext._SentEmails.Add(key, DateTime.Now);
|
||||
return result;
|
||||
}
|
||||
return "Account Not Found";
|
||||
} catch (Exception e) {
|
||||
Console.WriteLine("EmailService Error: " + e.ToString());
|
||||
return "The connection couldn't be established to the email server";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[Route("resetpassword")]
|
||||
[HttpPost]
|
||||
public async Task<ActionResult<bool>> ResetPwdVerify([FromForm] string UserName, [FromForm] string NewPassword, [FromForm] string ResetToken) {
|
||||
try {
|
||||
Account? test = await _databaseService.GetAccount(UserName.ToLower());
|
||||
if (test != null && !string.IsNullOrEmpty(test.EmailToken)) {
|
||||
if (!string.IsNullOrEmpty(test.EmailToken) && test.EmailToken == ResetToken) {
|
||||
test.CurrentPasswordAttempts = 0;
|
||||
test.EmailToken = "";
|
||||
test.PasswordHash = BCrypt.Net.BCrypt.HashPassword(NewPassword);
|
||||
await _databaseService.SetAccount(test);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[Route("delete")]
|
||||
[HttpPost]
|
||||
public async Task<ActionResult<bool>> delete([FromForm] string Password) {
|
||||
try {
|
||||
if (isLoggedIn()) {
|
||||
Account user = await getLoggedInUser();
|
||||
if (BCrypt.Net.BCrypt.Verify(Password, user.PasswordHash)) {
|
||||
await _databaseService.DeleteAccount(user.ID);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} catch {
|
||||
return false;
|
||||
[HttpGet("logout")]
|
||||
public ActionResult Logout() {
|
||||
if (isLoggedIn()) {
|
||||
signOut();
|
||||
return Redirect("/");
|
||||
}
|
||||
return NotFound("Not logged in");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Security.Claims;
|
||||
using MistoxWebsite.Server.Entities;
|
||||
using MistoxWebsite.Server.Services.DatabaseService;
|
||||
|
||||
@@ -12,6 +13,19 @@ namespace MistoxWebsite.Server.Controllers {
|
||||
_databaseService = databaseService;
|
||||
}
|
||||
|
||||
public void signIn(string JWT) {
|
||||
Response.Cookies.Append("mistox_session", JWT, new CookieOptions {
|
||||
Secure = true,
|
||||
HttpOnly = true,
|
||||
SameSite = SameSiteMode.Strict,
|
||||
Expires = DateTime.UtcNow.AddDays(7)
|
||||
});
|
||||
}
|
||||
|
||||
public void signOut() {
|
||||
Response.Cookies.Delete("mistox_session");
|
||||
}
|
||||
|
||||
public bool isLoggedIn() {
|
||||
if (User.Identity != null && User.Identity.IsAuthenticated) {
|
||||
return true;
|
||||
@@ -20,16 +34,19 @@ namespace MistoxWebsite.Server.Controllers {
|
||||
}
|
||||
|
||||
public int getLoggedInUserID() {
|
||||
return Convert.ToInt32(User.FindFirst("ID")?.Value);
|
||||
return Convert.ToInt32(User.FindFirstValue(ClaimTypes.NameIdentifier));
|
||||
}
|
||||
|
||||
public async Task<Account> getLoggedInUser() {
|
||||
public Account getLoggedInUser() {
|
||||
try {
|
||||
Account? test = await _databaseService.GetAccount(getLoggedInUserID());
|
||||
if (test != null) {
|
||||
return test;
|
||||
}
|
||||
return new Account();
|
||||
Account building = new Account {
|
||||
ID = Convert.ToInt32(User.FindFirstValue(ClaimTypes.NameIdentifier)),
|
||||
UserName = User.FindFirstValue(ClaimTypes.Name)!.ToString(),
|
||||
Email = User.FindFirstValue(ClaimTypes.Email)!.ToString(),
|
||||
Role = User.FindFirstValue(ClaimTypes.Role)!.ToString(),
|
||||
DataServer = User.FindFirstValue(ClaimTypes.UserData)!.ToString()
|
||||
};
|
||||
return building;
|
||||
} catch {
|
||||
return new Account();
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace MistoxWebsite.Server.Controllers {
|
||||
public async Task<ActionResult<bool>> CreateProduct([FromForm] Product obj, [FromForm] IFormFile[] images) {
|
||||
try {
|
||||
if (isLoggedIn()) {
|
||||
Account user = await getLoggedInUser();
|
||||
Account user = getLoggedInUser();
|
||||
if (user.Role == "Admin") {
|
||||
List<ProductImage> building = new List<ProductImage>();
|
||||
foreach (var file in images) {
|
||||
@@ -70,7 +70,7 @@ namespace MistoxWebsite.Server.Controllers {
|
||||
public async Task<ActionResult<bool>> DeleteProduct([FromForm] int productID) {
|
||||
try {
|
||||
if (isLoggedIn()) {
|
||||
Account user = await getLoggedInUser();
|
||||
Account user = getLoggedInUser();
|
||||
if (user.Role == "Admin") {
|
||||
await _databaseService.DeleteProduct(productID);
|
||||
return true;
|
||||
|
||||
@@ -3,17 +3,11 @@
|
||||
namespace MistoxWebsite.Server.Entities {
|
||||
|
||||
public class Account {
|
||||
public int ID { get; set; } // PK
|
||||
public int? ID { get; set; } // PK
|
||||
public string UserName { get; set; } = "";
|
||||
public string Email { get; set; } = "";
|
||||
public bool EmailVerified { get; set; } = false;
|
||||
public string PasswordHash { get; set; } = "";
|
||||
public bool FailedPasswordLock { get; set; } = false;
|
||||
public int PasswordAttempts { get; set; } = 5;
|
||||
public int CurrentPasswordAttempts { get; set; } = 0;
|
||||
public string Role { get; set; } = "Generic";
|
||||
public string EmailToken { get; set; } = "";
|
||||
public string Error { get; set; } = "";
|
||||
public string DataServer { get; set; } = "";
|
||||
}
|
||||
|
||||
public class Product {
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
<PackageReference Include="BCrypt.Net-Next" Version="4.0.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="9.0.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="9.0.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.WebApiCompatShim" Version="2.3.0" />
|
||||
<PackageReference Include="MySql.Data" Version="9.2.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Security.Claims;
|
||||
using System.Security.Cryptography;
|
||||
using System.Threading.RateLimiting;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using MistoxWebsite.Server.Controllers.Payment;
|
||||
using MistoxWebsite.Server.Services;
|
||||
using MistoxWebsite.Server.Services.DatabaseService;
|
||||
@@ -78,25 +84,97 @@ if (IPayment._PaymentType == PaymentType.StripeIntent) {
|
||||
IPayment._EndpointSecret = string.IsNullOrEmpty(StripeEndpointKey) ? "" : StripeEndpointKey;
|
||||
}
|
||||
|
||||
// Authentication Service
|
||||
builder.Services.AddAuthentication( options => {
|
||||
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
|
||||
} ).AddCookie(options => {
|
||||
options.Cookie.HttpOnly = true;
|
||||
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
|
||||
options.Cookie.SameSite = SameSiteMode.Strict;
|
||||
options.LoginPath = "/account/login";
|
||||
options.LogoutPath = "/account/logout";
|
||||
options.SlidingExpiration = true;
|
||||
////////////////////////////////
|
||||
/////// Auth Service ////////
|
||||
////////////////////////////////
|
||||
|
||||
RsaSecurityKey? PublicKey = null;
|
||||
using (HttpClient client = new HttpClient()) {
|
||||
while (PublicKey == null) {
|
||||
HttpResponseMessage PublicKeyResponse = await client.GetAsync("https://auth.mistox.com/api/auth/publickey");
|
||||
if (PublicKeyResponse.IsSuccessStatusCode) {
|
||||
string publicKey = await PublicKeyResponse.Content.ReadAsStringAsync();
|
||||
RSA rsa = RSA.Create();
|
||||
rsa.ImportFromPem(publicKey);
|
||||
PublicKey = new RsaSecurityKey(rsa);
|
||||
} else {
|
||||
await Task.Delay(2000); // sleep the main thread for 2 seconds before sending another request. Prevent DDOS of my own equiptment
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
builder.Services.AddAuthentication(options => {
|
||||
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||
}).AddJwtBearer(options => {
|
||||
options.TokenValidationParameters = new TokenValidationParameters {
|
||||
ValidateIssuer = true,
|
||||
ValidateAudience = true,
|
||||
ValidateLifetime = true,
|
||||
ValidateIssuerSigningKey = true,
|
||||
ValidIssuer = "https://auth.mistox.com",
|
||||
ValidAudience = "mistox-llc-auth-token",
|
||||
IssuerSigningKey = PublicKey,
|
||||
ClockSkew = TimeSpan.FromMinutes(1)
|
||||
};
|
||||
options.Events = new JwtBearerEvents {
|
||||
OnMessageReceived = context => {
|
||||
context.Token = context.Request.Cookies["mistox_session"];
|
||||
return Task.CompletedTask;
|
||||
},
|
||||
OnTokenValidated = context => {
|
||||
var jwtToken = context.SecurityToken as JwtSecurityToken;
|
||||
if (jwtToken != null) {
|
||||
var exp = jwtToken.ValidTo;
|
||||
var now = DateTime.UtcNow;
|
||||
if ((exp - now) < TimeSpan.FromDays(3)) {
|
||||
// Impliment token refresh
|
||||
}
|
||||
}
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
builder.Services.AddCors( o => o.AddDefaultPolicy( builder => {
|
||||
builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader(); // No CORS
|
||||
} ) );
|
||||
////////////////////////////////
|
||||
/// Rate Limiting Service ////
|
||||
////////////////////////////////
|
||||
|
||||
List<string> allowedOrigins = new List<string>{ "https://mistox.com", "https://www.mistox.com" };
|
||||
if (builder.Environment.IsDevelopment()) {
|
||||
allowedOrigins.Add("http://localhost:5000");
|
||||
}
|
||||
|
||||
builder.Services.AddCors(options => {
|
||||
options.AddDefaultPolicy(policy => {
|
||||
policy.WithOrigins(allowedOrigins.ToArray())
|
||||
.AllowAnyHeader()
|
||||
.AllowAnyMethod()
|
||||
.AllowCredentials();
|
||||
});
|
||||
});
|
||||
|
||||
builder.Services.AddRateLimiter(options => {
|
||||
options.AddPolicy("PerUserPolicy", httpContext => {
|
||||
var userId = httpContext.User.FindFirst(ClaimTypes.NameIdentifier)?.Value
|
||||
?? $"ip:{httpContext.Connection.RemoteIpAddress}";
|
||||
|
||||
return RateLimitPartition.GetTokenBucketLimiter(userId, key => new TokenBucketRateLimiterOptions {
|
||||
TokenLimit = 10, // max 10 requests
|
||||
QueueProcessingOrder = QueueProcessingOrder.OldestFirst,
|
||||
QueueLimit = 0,
|
||||
ReplenishmentPeriod = TimeSpan.FromSeconds(15),
|
||||
TokensPerPeriod = 2,
|
||||
AutoReplenishment = true
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
////////////////////////////////
|
||||
///// ASPNET Core Function /////
|
||||
////////////////////////////////
|
||||
|
||||
// Pages Service
|
||||
builder.Services.AddControllers();
|
||||
builder.Services.AddRazorPages();
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
@@ -108,6 +186,8 @@ if( !app.Environment.IsDevelopment() ) {
|
||||
app.UseDefaultFiles();
|
||||
app.UseStaticFiles();
|
||||
|
||||
app.UseRateLimiter();
|
||||
|
||||
app.UseCors();
|
||||
|
||||
app.UseRouting();
|
||||
|
||||
@@ -1,160 +0,0 @@
|
||||
using MistoxWebsite.Server.Entities;
|
||||
using MySql.Data.MySqlClient;
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
|
||||
namespace MistoxWebsite.Server.Services.DatabaseService {
|
||||
public partial class DatabaseService {
|
||||
|
||||
public async Task<Account?> GetAccount( string UserNameOrEmail ) {
|
||||
Account? account = null;
|
||||
using( MySqlConnection connection = GetConnection() ) {
|
||||
connection.Open();
|
||||
string command = @"
|
||||
SELECT *
|
||||
FROM Account
|
||||
WHERE UserName = @UorE OR Email = @UorE;
|
||||
";
|
||||
|
||||
MySqlCommand cmd = new MySqlCommand(command, connection);
|
||||
cmd.Parameters.AddWithValue("@UorE", UserNameOrEmail);
|
||||
|
||||
using( DbDataReader reader = await cmd.ExecuteReaderAsync() ) {
|
||||
while( await reader.ReadAsync() ) {
|
||||
if( reader == null ) {
|
||||
break;
|
||||
}
|
||||
|
||||
int _id = reader.GetInt32("ID");
|
||||
string _username = reader.GetString("UserName");
|
||||
string _email = reader.GetString("Email");
|
||||
bool _emailVerified = reader.GetBoolean("EmailVerified");
|
||||
string _passwordhash = reader.GetString("PasswordHash");
|
||||
bool _failedpasswordlock = reader.GetBoolean( "FailedPasswordLock" );
|
||||
int _passwordattempts = reader.GetInt32( "PasswordAttempts" );
|
||||
int _curpasswordattempts = reader.GetInt32( "CurrentPasswordAttempts" );
|
||||
string _role = reader.GetString( "Role" );
|
||||
string _emailtoken = reader.GetString( "EmailToken" );
|
||||
|
||||
account = new Account() {
|
||||
ID = _id,
|
||||
UserName = _username,
|
||||
Email = _email,
|
||||
EmailVerified = _emailVerified,
|
||||
PasswordHash = _passwordhash,
|
||||
CurrentPasswordAttempts = _curpasswordattempts,
|
||||
PasswordAttempts = _passwordattempts,
|
||||
EmailToken = _emailtoken,
|
||||
FailedPasswordLock = _failedpasswordlock,
|
||||
Role = _role,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
return account;
|
||||
}
|
||||
|
||||
public async Task<Account?> GetAccount( int ID ) {
|
||||
Account? account = null;
|
||||
using( MySqlConnection connection = GetConnection() ) {
|
||||
connection.Open();
|
||||
string command = @"
|
||||
SELECT *
|
||||
FROM Account
|
||||
WHERE ID = @ID;
|
||||
";
|
||||
|
||||
MySqlCommand cmd = new MySqlCommand(command, connection);
|
||||
cmd.Parameters.AddWithValue("@ID", ID);
|
||||
|
||||
using( DbDataReader reader = await cmd.ExecuteReaderAsync() ) {
|
||||
while( await reader.ReadAsync() ) {
|
||||
if( reader == null ) {
|
||||
break;
|
||||
}
|
||||
int _id = reader.GetInt32("ID");
|
||||
string _username = reader.GetString("UserName");
|
||||
string _email = reader.GetString("Email");
|
||||
bool _emailVerified = reader.GetBoolean("EmailVerified");
|
||||
string _passwordhash = reader.GetString("PasswordHash");
|
||||
bool _failedpasswordlock = reader.GetBoolean( "FailedPasswordLock" );
|
||||
int _passwordattempts = reader.GetInt32( "PasswordAttempts" );
|
||||
int _curpasswordattempts = reader.GetInt32( "CurrentPasswordAttempts" );
|
||||
string _role = reader.GetString( "Role" );
|
||||
string _emailtoken = reader.GetString( "EmailToken" );
|
||||
|
||||
account = new Account() {
|
||||
ID = _id,
|
||||
UserName = _username,
|
||||
Email = _email,
|
||||
EmailVerified = _emailVerified,
|
||||
PasswordHash = _passwordhash,
|
||||
CurrentPasswordAttempts = _passwordattempts,
|
||||
PasswordAttempts = _passwordattempts,
|
||||
EmailToken = _emailtoken,
|
||||
FailedPasswordLock = _failedpasswordlock,
|
||||
Role = _role,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
return account;
|
||||
}
|
||||
|
||||
public async Task SetAccount( Account Profile ) {
|
||||
using( MySqlConnection connection = GetConnection() ) {
|
||||
connection.Open();
|
||||
|
||||
string command = @"
|
||||
INSERT INTO Account
|
||||
(ID,UserName,Email,EmailVerified,PasswordHash,FailedPasswordLock,PasswordAttempts,CurrentPasswordAttempts,Role,EmailToken)
|
||||
VALUES
|
||||
(@ID,@UserName,@Email,@EmailVerified,@PasswordHash,@FailedPasswordLock,@PasswordAttempts,@CurrentPasswordAttempts,@Role,@EmailToken)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
UserName = @UserName,
|
||||
Email = @Email,
|
||||
EmailVerified = @EmailVerified,
|
||||
PasswordHash = @PasswordHash,
|
||||
FailedPasswordLock = @FailedPasswordLock,
|
||||
PasswordAttempts = @PasswordAttempts,
|
||||
CurrentPasswordAttempts = @CurrentPasswordAttempts,
|
||||
Role = @Role,
|
||||
EmailToken = @EmailToken;
|
||||
";
|
||||
|
||||
MySqlCommand cmd = new MySqlCommand( command , connection);
|
||||
cmd.Parameters.AddWithValue("@ID", Profile.ID);
|
||||
cmd.Parameters.AddWithValue("@UserName", Profile.UserName);
|
||||
cmd.Parameters.AddWithValue("@Email", Profile.Email);
|
||||
cmd.Parameters.AddWithValue("@EmailVerified", Profile.EmailVerified);
|
||||
cmd.Parameters.AddWithValue("@PasswordHash", Profile.PasswordHash);
|
||||
cmd.Parameters.AddWithValue("@FailedPasswordLock", Profile.FailedPasswordLock);
|
||||
cmd.Parameters.AddWithValue("@PasswordAttempts", Profile.PasswordAttempts);
|
||||
cmd.Parameters.AddWithValue("@CurrentPasswordAttempts", Profile.CurrentPasswordAttempts);
|
||||
cmd.Parameters.AddWithValue("@Role", Profile.Role);
|
||||
cmd.Parameters.AddWithValue("@EmailToken", Profile.EmailToken);
|
||||
|
||||
await cmd.ExecuteNonQueryAsync();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task DeleteAccount( int ID ) {
|
||||
using( MySqlConnection connection = GetConnection() ) {
|
||||
MySqlCommand cmd;
|
||||
connection.Open();
|
||||
|
||||
string command = @"
|
||||
DELETE FROM Account WHERE ID = @ID;
|
||||
DELETE FROM AccountInventory WHERE AccountID = @ID;
|
||||
DELETE FROM ProjectMistData WHERE AccountID = @ID;
|
||||
DELETE FROM Cart WHERE AccountID = @ID;
|
||||
";
|
||||
cmd = new MySqlCommand( command, connection );
|
||||
cmd.Parameters.AddWithValue("@ID", ID);
|
||||
|
||||
await cmd.ExecuteNonQueryAsync();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user