Index: resTools_backend/backend/Services/UserService.cs
===================================================================
--- resTools_backend/backend/Services/UserService.cs	(revision 899b19da4d7326788e23e45dd1881ec1395e1d88)
+++ resTools_backend/backend/Services/UserService.cs	(revision d86edb72e90d0d42619a78d8c0d4656e39b625ae)
@@ -1,6 +1,7 @@
-namespace backend.Services;
+﻿namespace backend.Services;
 
 using backend.Data;
 using backend.DTOs;
+using backend.Email;
 using backend.Entities;
 using backend.Helpers;
@@ -11,4 +12,6 @@
 using System.IdentityModel.Tokens.Jwt;
 using System.Security.Claims;
+using System.Security.Cryptography;
+using System.Text;
 
 public interface IUserService
@@ -17,4 +20,8 @@
     Task<AuthenticateResponse> Register(CreateUserRequest req, bool isFirst);
     Task<User> GetById(int id);
+    Task SendEmailConfirmation(string email);
+    Task SendPasswordReset(string email);
+    Task ConfirmEmail(User user, string checkValid);
+    Task ResetPassword(string checkValid, string password);
 }
 
@@ -23,9 +30,11 @@
     private readonly AppSettings _appSettings;
     private readonly DataContext _context = null;
+    private readonly IEmailSender _emailSender;
 
-    public UserService(IOptions<AppSettings> appSettings, DataContext context)
+    public UserService(IOptions<AppSettings> appSettings, DataContext context, IEmailSender emailSender)
     {
         _appSettings = appSettings.Value;
         _context = context;
+        _emailSender = emailSender;
     }
 
@@ -40,5 +49,21 @@
         var token = generateJwtToken(user);
 
-        return new AuthenticateResponse { Email = user.Email, Id = user.Id, Token = token, IsAdmin = user.IsAdmin};
+        return new AuthenticateResponse { Email = user.Email, Id = user.Id, Token = token, IsAdmin = user.IsAdmin, IsConfirmed = user.IsConfirmed};
+    }
+
+    public async Task ConfirmEmail(User user, string checkValid)
+    {
+        if(user.ConfirmationURL != checkValid)
+        {
+            throw new Exception("Invalid check");
+        }
+        if(user.ConfirmationValidTo < DateTime.UtcNow)
+        {
+            throw new Exception("Link expired");
+        }
+
+        user.IsConfirmed = true;
+        _context.Users.Update(user);
+        await _context.SaveChangesAsync();
     }
 
@@ -50,9 +75,52 @@
     public async Task<AuthenticateResponse> Register(CreateUserRequest req, bool isFirst)
     {
-        User user = new User() { Email = req.Email, Password = req.Password, IsAdmin = isFirst };
+        User user = new User() { Email = req.Email, Password = req.Password, IsAdmin = isFirst, IsConfirmed = false };
         await _context.Users.AddAsync(user);
         await _context.SaveChangesAsync();
         var token = generateJwtToken(user);
-        return new AuthenticateResponse { Email = user.Email, Id = user.Id, Token = token, IsAdmin = user.IsAdmin };
+        return new AuthenticateResponse { Email = user.Email, Id = user.Id, Token = token, IsAdmin = user.IsAdmin, IsConfirmed = false };
+    }
+
+    public async Task ResetPassword(string checkValid, string password)
+    {
+        var user = await _context.Users.Where(x => x.PasswordResetURL == checkValid).FirstOrDefaultAsync();
+        if (user == null)
+        {
+            throw new Exception("Invalid check");
+        }
+        if (user.PasswordResetValidTo < DateTime.UtcNow)
+        {
+            throw new Exception("Link expired");
+        }
+
+        user.Password = password;
+        _context.Users.Update(user);
+        await _context.SaveChangesAsync();
+    }
+
+    public async Task SendEmailConfirmation(string email)
+    {
+        User user = await _context.Users.FirstOrDefaultAsync(x => x.Email == email);
+        user.ConfirmationURL = Guid.NewGuid().ToString();
+        user.ConfirmationValidTo = DateTime.UtcNow.AddHours(24);
+        _context.Users.Update(user);
+        await _context.SaveChangesAsync();
+        await _emailSender.SendEmailAsync(
+            "Потврдете го вашиот емаил",
+            "Ве молиме кликнете на следниот линк за да го потврдите вашиот емаил: http://localhost:3000/confirm?id=" + user.ConfirmationURL,
+            email);
+    }
+
+    public async Task SendPasswordReset(string email)
+    {
+        User user = await _context.Users.FirstOrDefaultAsync(x => x.Email == email);
+        user.PasswordResetURL = Guid.NewGuid().ToString();
+        user.PasswordResetValidTo = DateTime.UtcNow.AddHours(24);
+        _context.Users.Update(user);
+        await _context.SaveChangesAsync();
+        await _emailSender.SendEmailAsync(
+           "Ресетирајте ја лозинката",
+           "Ве молиме кликнете на следниот линк за да ја ресетирате лозинката: http://localhost:3000/reset?id=" + user.PasswordResetURL,
+           email);
     }
 
@@ -71,3 +139,13 @@
         return tokenHandler.WriteToken(token);
     }
+    
+    private string sha256Hash(String value)
+    {
+        using (SHA256 hash = SHA256.Create())
+        {
+            return String.Concat(hash
+              .ComputeHash(Encoding.UTF8.GetBytes(value))
+              .Select(item => item.ToString("x2")));
+        }
+    }
 }
