diff options
author | branislav.radivojevic <wafflemynxyt@gmail.com> | 2022-10-30 17:10:24 +0100 |
---|---|---|
committer | branislav.radivojevic <wafflemynxyt@gmail.com> | 2022-10-30 17:10:24 +0100 |
commit | e974abe377366b70d7214fa387d68a3a3e9e2315 (patch) | |
tree | 745969b1725dde3656b05429b9aac01731613f80 /Backend | |
parent | 2be12a8a7c77121377e9308c3bee27cbc3241231 (diff) |
registracija sa verfikacijom maila, reset pass
Diffstat (limited to 'Backend')
-rw-r--r-- | Backend/Api/Api/Api.csproj | 1 | ||||
-rw-r--r-- | Backend/Api/Api/Controllers/AuthController.cs | 26 | ||||
-rw-r--r-- | Backend/Api/Api/Interfaces/IJwtService.cs | 3 | ||||
-rw-r--r-- | Backend/Api/Api/Interfaces/IUserService.cs | 6 | ||||
-rw-r--r-- | Backend/Api/Api/Models/User.cs | 18 | ||||
-rw-r--r-- | Backend/Api/Api/Services/JwtService.cs | 34 | ||||
-rw-r--r-- | Backend/Api/Api/Services/UserService.cs | 119 |
7 files changed, 191 insertions, 16 deletions
diff --git a/Backend/Api/Api/Api.csproj b/Backend/Api/Api/Api.csproj index 10faa3e..93e31b7 100644 --- a/Backend/Api/Api/Api.csproj +++ b/Backend/Api/Api/Api.csproj @@ -12,6 +12,7 @@ <PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" /> <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.24.0" /> <PackageReference Include="BCrypt.Net-Next" Version="4.0.3" /> + <PackageReference Include="MailKit" Version="3.4.2" /> </ItemGroup> </Project> diff --git a/Backend/Api/Api/Controllers/AuthController.cs b/Backend/Api/Api/Controllers/AuthController.cs index 5973c8c..8262487 100644 --- a/Backend/Api/Api/Controllers/AuthController.cs +++ b/Backend/Api/Api/Controllers/AuthController.cs @@ -46,5 +46,31 @@ namespace Api.Controllers } return BadRequest("Pogresno uneti podaci"); } + [HttpPost("registeractual")] + public async Task<ActionResult<string>> RegisterActual([FromBody] Register creds) + { + var msg = await _userService.Register(creds); + if (msg == "Email Exists") + return Forbid(msg); + if (msg == "Username Exists") + return Forbid(msg); + return Ok(msg); + } + [HttpPost("verify")] + public async Task<ActionResult<string>> VerifyEmail([FromBody] VerifyUser creds) + { + var uspeh = await _userService.VerifyUser(creds); + if (!uspeh) + return BadRequest("Kod netacan ili istekao"); + return Ok("Uspesno verifikovan"); + } + [HttpPost("resetpass")] + public async Task<ActionResult<string>> ResetPass([FromBody] ResetPass creds) + { + var uspeh = await _userService.ResetPassword(creds); + if (!uspeh) + return BadRequest("Kod netacan ili istekao"); + return Ok("Sifra uspesno resetovana"); + } } } diff --git a/Backend/Api/Api/Interfaces/IJwtService.cs b/Backend/Api/Api/Interfaces/IJwtService.cs index f9e5d5f..6274bf9 100644 --- a/Backend/Api/Api/Interfaces/IJwtService.cs +++ b/Backend/Api/Api/Interfaces/IJwtService.cs @@ -6,7 +6,8 @@ namespace Api.Interfaces { string GenToken(User user); string TokenToId(string token); - public string GenEmailToken(string username); + public string GenEmailToken(User user); public string EmailTokenToId(string token); + public string EmailTokenToKod(string token); } }
\ No newline at end of file diff --git a/Backend/Api/Api/Interfaces/IUserService.cs b/Backend/Api/Api/Interfaces/IUserService.cs index 9e4e3b9..5205028 100644 --- a/Backend/Api/Api/Interfaces/IUserService.cs +++ b/Backend/Api/Api/Interfaces/IUserService.cs @@ -15,8 +15,12 @@ namespace Api.Interfaces Task<string> RenewToken(string existingToken); Task<string> Login(Login login); Task<string> Register(Register register); - Task<Boolean> VerifyUser(string _id); + Task<Boolean> VerifyUser(VerifyUser login); Task<string> UserIdFromJwt(); + Task<Boolean> ResendVerifyKod(Login login); + Boolean SendEmailKod(User user); + Task<Boolean> ForgotPassword(JustMail jm); + Task<Boolean> ResetPassword(ResetPass rp); } } diff --git a/Backend/Api/Api/Models/User.cs b/Backend/Api/Api/Models/User.cs index e9947a2..a1fe149 100644 --- a/Backend/Api/Api/Models/User.cs +++ b/Backend/Api/Api/Models/User.cs @@ -30,4 +30,22 @@ namespace Api.Models public String email { get; set; } public String password { get; set; } } + + public class JustMail + { + public String email { get; set; } + } + + public class ResetPass + { + public String email { get; set; } + public String newpass { get; set; } + public String kod { get; set; } + } + public class VerifyUser + { + public String email { get; set; } + public String password { get; set; } + public String kod { get; set; } + } } diff --git a/Backend/Api/Api/Services/JwtService.cs b/Backend/Api/Api/Services/JwtService.cs index e3688de..9d928f7 100644 --- a/Backend/Api/Api/Services/JwtService.cs +++ b/Backend/Api/Api/Services/JwtService.cs @@ -56,13 +56,15 @@ namespace Api.Services } } - public string GenEmailToken(string username) + public string GenEmailToken(User user) { var tokenHandler = new JwtSecurityTokenHandler(); var key = Encoding.ASCII.GetBytes(_config.GetSection("AppSettings:EmailToken").Value); + Random rand = new Random((int)DateTime.Now.Ticks); + int kod = rand.Next(100000, 999999); var tokenDescriptor = new SecurityTokenDescriptor { - Subject = new ClaimsIdentity(new[] { new Claim("username", username)}), + Subject = new ClaimsIdentity(new[] { new Claim("username", user.username), new Claim("kod",kod.ToString()), new Claim("id", user._id) }), Expires = DateTime.UtcNow.AddMinutes(30), SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature) }; @@ -96,5 +98,33 @@ namespace Api.Services return null; } } + + public string EmailTokenToKod(string token) + { + if (token == null) + return null; + var tokenHandler = new JwtSecurityTokenHandler(); + var key = Encoding.ASCII.GetBytes(_config.GetSection("AppSettings:EmailToken").Value.ToString()); + try + { + tokenHandler.ValidateToken(token, new TokenValidationParameters + { + ValidateIssuerSigningKey = true, + IssuerSigningKey = new SymmetricSecurityKey(key), + ValidateIssuer = false, + ValidateAudience = false, + ClockSkew = TimeSpan.Zero + }, + out SecurityToken validatedToken); + var jwtToken = (JwtSecurityToken)validatedToken; + var kod = (jwtToken.Claims.First(x => x.Type == "kod").Value.ToString()); + return kod; + } + catch + { + return null; + } + } + } } diff --git a/Backend/Api/Api/Services/UserService.cs b/Backend/Api/Api/Services/UserService.cs index 7c00c05..59e1965 100644 --- a/Backend/Api/Api/Services/UserService.cs +++ b/Backend/Api/Api/Services/UserService.cs @@ -3,6 +3,8 @@ using Api.Models; using MongoDB.Driver; using Microsoft.AspNetCore.Http; using System.Security.Claims; +using MimeKit; +using MailKit.Net.Smtp; namespace Api.Services { @@ -11,12 +13,14 @@ namespace Api.Services private readonly IHttpContextAccessor _httpContext; private readonly IMongoCollection<User> _users; private readonly IJwtService _jwtService; - public UserService(IDatabaseConnection settings, IMongoClient mongoClient, IJwtService jwtService, IHttpContextAccessor httpContextAccessor) + private IConfiguration _configuration; + public UserService(IDatabaseConnection settings, IMongoClient mongoClient, IJwtService jwtService, IHttpContextAccessor httpContextAccessor, IConfiguration configuration) { var database = mongoClient.GetDatabase(settings.DatabaseName); _users = database.GetCollection<User>(settings.UserCollectionName); - _jwtService=jwtService; + _jwtService = jwtService; this._httpContext = httpContextAccessor; + this._configuration = configuration; } public async Task<int> createUser(User user) @@ -122,21 +126,31 @@ namespace Api.Services user.name = register.name; user.verified = false; user.password = hashPassword(register.password); - user.emailToken = _jwtService.GenEmailToken(user.username); + user.creationDate = DateTime.Now.ToUniversalTime(); + user.emailToken = ""; await _users.InsertOneAsync(user); + user.emailToken = _jwtService.GenEmailToken(user); + await _users.ReplaceOneAsync(x => x._id == user._id, user); + SendEmailKod(user); + return "User Registered"; } - public async Task<Boolean> VerifyUser(string _id) + public async Task<Boolean> VerifyUser(VerifyUser login) { - User user = await _users.FindAsync(x => x._id==_id).Result.FirstAsync(); - if(user != null) + User user = await _users.FindAsync(x => x.email == login.email).Result.FirstOrDefaultAsync(); + if (user != null && checkPassword(login.password, user.password)) { - user.verified = true; - await _users.ReplaceOneAsync(x => x._id == _id, user); - return true; + var basekod = _jwtService.EmailTokenToKod(user.emailToken); + if (basekod != null) + if (String.Compare(login.kod,basekod) == 0) + { + user.verified = true; + await _users.ReplaceOneAsync(x => x._id == user._id, user); + return true; + } } return false; } @@ -153,24 +167,105 @@ namespace Api.Services public async Task<string> Login(Login login) { - User user = await _users.FindAsync(x => x.email == login.email).Result.FirstAsync(); // add && x.verified == true after implementing - if(user != null && checkPassword(login.password, user.password)) + User user = await _users.FindAsync(x => x.email == login.email && x.verified == true).Result.FirstOrDefaultAsync(); + if (user != null && checkPassword(login.password, user.password)) { return _jwtService.GenToken(user); } return null; } + public async Task<string> UserIdFromJwt() { string id = null; if (_httpContext.HttpContext.User.FindFirstValue("id") != null) { id = _httpContext.HttpContext.User.FindFirstValue("id").ToString(); - var _id = await _users.FindAsync(x => x._id == id).Result.FirstAsync(); + var _id = await _users.FindAsync(x => x._id == id).Result.FirstOrDefaultAsync(); if (_id == null) id = null; } return id; } + + public async Task<Boolean> ResendVerifyKod(Login login) + { + User user = await _users.FindAsync(x => x.email == login.email).Result.FirstOrDefaultAsync(); + if (user != null && checkPassword(login.password, user.password)) + { + user.emailToken = _jwtService.GenEmailToken(user); + await _users.ReplaceOneAsync(x => x._id == user._id, user); + SendEmailKod(user); + + return true; + } + return false; + } + + public Boolean SendEmailKod(User user) + { + MimeMessage message = new MimeMessage(); + message.From.Add(new MailboxAddress("Tim Oddyssey", _configuration.GetSection("EmailCfg:Email").Value)); + message.To.Add(MailboxAddress.Parse(user.email)); + message.Subject = "Vas Oddyssey verifikacioni kod"; //think of something better yeah? + + var kod = _jwtService.EmailTokenToKod(user.emailToken); + if (kod == null) + return false; + + var bodybuilder = new BodyBuilder(); + bodybuilder.HtmlBody = String.Format(@"<h3>Verfikacioni kod:</h3><h2>"+kod+"</h2><br><p>Kod traje <b>30</b> minuta</p>"); + message.Body = bodybuilder.ToMessageBody(); + + SmtpClient client = new SmtpClient(); + try + { + client.Connect(_configuration.GetSection("EmailCfg:SmtpServer").Value, 465, true); + client.Authenticate(_configuration.GetSection("EmailCfg:Email").Value, _configuration.GetSection("EmailCofg:Password").Value); + client.Send(message); + + } + catch (Exception ex) + { + return false; + } + finally + { + client.Disconnect(true); + client.Dispose(); + } + return true; + } + + public async Task<Boolean> ForgotPassword(JustMail jm) + { + User user = await _users.FindAsync(x => x.email == jm.email && x.verified == true).Result.FirstOrDefaultAsync(); + if (user != null) + { + user.emailToken = _jwtService.GenEmailToken(user); + await _users.ReplaceOneAsync(x => x._id == user._id, user); + SendEmailKod(user); + + return true; + } + return false; + } + + public async Task<Boolean> ResetPassword(ResetPass rp) + { + User user = await _users.FindAsync(x => x.email == rp.email && x.verified == true).Result.FirstOrDefaultAsync(); + if (user != null) + { + var basekod = _jwtService.EmailTokenToKod(user.emailToken); + if (basekod != null) + if (String.Compare(rp.kod, basekod) == 0) + { + user.password = hashPassword(rp.newpass); + await _users.ReplaceOneAsync(x => x._id == user._id, user); + return true; + } + } + return false; + } } } |