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; +        }      }  } | 
