Changeset a26f6a1 for resTools_backend


Ignore:
Timestamp:
08/09/22 16:09:32 (2 years ago)
Author:
Danilo <danilo.najkov@…>
Branches:
master
Children:
a569b7c
Parents:
899b19d
Message:

full auth flow

Location:
resTools_backend/backend
Files:
5 added
7 edited

Legend:

Unmodified
Added
Removed
  • resTools_backend/backend/Controllers/UsersController.cs

    r899b19d ra26f6a1  
    4141        }catch (Exception ex){ return null; }
    4242        User user = await _userService.GetById(userId);
    43         return new AuthenticateResponse() { Email=user.Email, Id = user.Id};
     43        return new AuthenticateResponse() { Email=user.Email, Id = user.Id, IsAdmin = user.IsAdmin, IsConfirmed = user.IsConfirmed};
     44    }
     45
     46    [HttpPost("confirm")]
     47    public async Task ConfirmEmail()
     48    {
     49        int userId = 0;
     50        try
     51        {
     52            userId = (int)this.HttpContext.Items["User"];
     53        }
     54        catch (Exception ex) { return; }
     55        User user = await _userService.GetById(userId);
     56        await _userService.SendEmailConfirmation(user.Email);
     57    }
     58
     59    [HttpPost("reset")]
     60    public async Task ResetPassword(string email)
     61    {
     62        await _userService.SendPasswordReset(email);
     63    }
     64
     65    [HttpPost("confirmed")]
     66    public async Task ConfirmedEmail(string validityString)
     67    {
     68        int userId = 0;
     69        try
     70        {
     71            userId = (int)this.HttpContext.Items["User"];
     72        }
     73        catch (Exception ex) { return; }
     74        User user = await _userService.GetById(userId);
     75        await _userService.ConfirmEmail(user, validityString);
     76    }
     77
     78    [HttpPost("reseted")]
     79    public async Task ResetedPassword(string validityString, string newPassword)
     80    {
     81        await _userService.ResetPassword(validityString, newPassword);
    4482    }
    4583
  • resTools_backend/backend/DTOs/AuthenticateResponse.cs

    r899b19d ra26f6a1  
    1515    [JsonProperty]
    1616    public bool IsAdmin { get; set; }
     17    [JsonProperty]
     18    public bool IsConfirmed { get; set; }
    1719}
  • resTools_backend/backend/Entities/User.cs

    r899b19d ra26f6a1  
    99    public string Password { get; set; }
    1010    public bool IsAdmin { get; set; }
     11    public bool IsConfirmed { get; set; }
     12    public string? ConfirmationURL { get; set; }
     13    public DateTime? ConfirmationValidTo { get; set; }
     14    public string? PasswordResetURL { get; set; }
     15    public DateTime? PasswordResetValidTo { get; set; }
    1116    public virtual Restaurant Restaurant { get; set; }
    1217}
  • resTools_backend/backend/Migrations/DataContextModelSnapshot.cs

    r899b19d ra26f6a1  
    176176                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
    177177
     178                    b.Property<string>("ConfirmationURL")
     179                        .HasColumnType("text");
     180
     181                    b.Property<DateTime?>("ConfirmationValidTo")
     182                        .HasColumnType("timestamp with time zone");
     183
    178184                    b.Property<string>("Email")
    179185                        .IsRequired()
     
    183189                        .HasColumnType("boolean");
    184190
     191                    b.Property<bool>("IsConfirmed")
     192                        .HasColumnType("boolean");
     193
    185194                    b.Property<string>("Password")
    186195                        .IsRequired()
    187196                        .HasColumnType("text");
     197
     198                    b.Property<string>("PasswordResetURL")
     199                        .HasColumnType("text");
     200
     201                    b.Property<DateTime?>("PasswordResetValidTo")
     202                        .HasColumnType("timestamp with time zone");
    188203
    189204                    b.HasKey("Id");
  • resTools_backend/backend/Program.cs

    r899b19d ra26f6a1  
    11using backend.Data;
     2using backend.Email;
    23using backend.Helpers;
    34using backend.Services;
     
    5051builder.Services.AddScoped<ISmsService, SmsService>();
    5152
     53builder.Services.AddTransient<IEmailSender, EmailSender>();
     54
    5255builder.Services.AddDbContext<DataContext>(p => p.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection")));
    5356
  • resTools_backend/backend/Services/UserService.cs

    r899b19d ra26f6a1  
    1 namespace backend.Services;
     1namespace backend.Services;
    22
    33using backend.Data;
    44using backend.DTOs;
     5using backend.Email;
    56using backend.Entities;
    67using backend.Helpers;
     
    1112using System.IdentityModel.Tokens.Jwt;
    1213using System.Security.Claims;
     14using System.Security.Cryptography;
     15using System.Text;
    1316
    1417public interface IUserService
     
    1720    Task<AuthenticateResponse> Register(CreateUserRequest req, bool isFirst);
    1821    Task<User> GetById(int id);
     22    Task SendEmailConfirmation(string email);
     23    Task SendPasswordReset(string email);
     24    Task ConfirmEmail(User user, string checkValid);
     25    Task ResetPassword(string checkValid, string password);
    1926}
    2027
     
    2330    private readonly AppSettings _appSettings;
    2431    private readonly DataContext _context = null;
     32    private readonly IEmailSender _emailSender;
    2533
    26     public UserService(IOptions<AppSettings> appSettings, DataContext context)
     34    public UserService(IOptions<AppSettings> appSettings, DataContext context, IEmailSender emailSender)
    2735    {
    2836        _appSettings = appSettings.Value;
    2937        _context = context;
     38        _emailSender = emailSender;
    3039    }
    3140
     
    4049        var token = generateJwtToken(user);
    4150
    42         return new AuthenticateResponse { Email = user.Email, Id = user.Id, Token = token, IsAdmin = user.IsAdmin};
     51        return new AuthenticateResponse { Email = user.Email, Id = user.Id, Token = token, IsAdmin = user.IsAdmin, IsConfirmed = user.IsConfirmed};
     52    }
     53
     54    public async Task ConfirmEmail(User user, string checkValid)
     55    {
     56        if(user.ConfirmationURL != checkValid)
     57        {
     58            throw new Exception("Invalid check");
     59        }
     60        if(user.ConfirmationValidTo < DateTime.UtcNow)
     61        {
     62            throw new Exception("Link expired");
     63        }
     64
     65        user.IsConfirmed = true;
     66        _context.Users.Update(user);
     67        await _context.SaveChangesAsync();
    4368    }
    4469
     
    5075    public async Task<AuthenticateResponse> Register(CreateUserRequest req, bool isFirst)
    5176    {
    52         User user = new User() { Email = req.Email, Password = req.Password, IsAdmin = isFirst };
     77        User user = new User() { Email = req.Email, Password = req.Password, IsAdmin = isFirst, IsConfirmed = false };
    5378        await _context.Users.AddAsync(user);
    5479        await _context.SaveChangesAsync();
    5580        var token = generateJwtToken(user);
    56         return new AuthenticateResponse { Email = user.Email, Id = user.Id, Token = token, IsAdmin = user.IsAdmin };
     81        return new AuthenticateResponse { Email = user.Email, Id = user.Id, Token = token, IsAdmin = user.IsAdmin, IsConfirmed = false };
     82    }
     83
     84    public async Task ResetPassword(string checkValid, string password)
     85    {
     86        var user = await _context.Users.Where(x => x.PasswordResetURL == checkValid).FirstOrDefaultAsync();
     87        if (user == null)
     88        {
     89            throw new Exception("Invalid check");
     90        }
     91        if (user.PasswordResetValidTo < DateTime.UtcNow)
     92        {
     93            throw new Exception("Link expired");
     94        }
     95
     96        user.Password = password;
     97        _context.Users.Update(user);
     98        await _context.SaveChangesAsync();
     99    }
     100
     101    public async Task SendEmailConfirmation(string email)
     102    {
     103        User user = await _context.Users.FirstOrDefaultAsync(x => x.Email == email);
     104        user.ConfirmationURL = Guid.NewGuid().ToString();
     105        user.ConfirmationValidTo = DateTime.UtcNow.AddHours(24);
     106        _context.Users.Update(user);
     107        await _context.SaveChangesAsync();
     108        await _emailSender.SendEmailAsync(
     109            "Потврдете го вашиот емаил",
     110            "Ве молиме кликнете на следниот линк за да го потврдите вашиот емаил: http://localhost:3000/confirm?id=" + user.ConfirmationURL,
     111            email);
     112    }
     113
     114    public async Task SendPasswordReset(string email)
     115    {
     116        User user = await _context.Users.FirstOrDefaultAsync(x => x.Email == email);
     117        user.PasswordResetURL = Guid.NewGuid().ToString();
     118        user.PasswordResetValidTo = DateTime.UtcNow.AddHours(24);
     119        _context.Users.Update(user);
     120        await _context.SaveChangesAsync();
     121        await _emailSender.SendEmailAsync(
     122           "Ресетирајте ја лозинката",
     123           "Ве молиме кликнете на следниот линк за да ја ресетирате лозинката: http://localhost:3000/reset?id=" + user.PasswordResetURL,
     124           email);
    57125    }
    58126
     
    71139        return tokenHandler.WriteToken(token);
    72140    }
     141   
     142    private string sha256Hash(String value)
     143    {
     144        using (SHA256 hash = SHA256.Create())
     145        {
     146            return String.Concat(hash
     147              .ComputeHash(Encoding.UTF8.GetBytes(value))
     148              .Select(item => item.ToString("x2")));
     149        }
     150    }
    73151}
  • resTools_backend/backend/backend.csproj

    r899b19d ra26f6a1  
    1 <Project Sdk="Microsoft.NET.Sdk.Web">
     1<Project Sdk="Microsoft.NET.Sdk.Web">
    22
    33  <PropertyGroup>
     
    2222    <PackageReference Include="Npgsql" Version="6.0.3" />
    2323    <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="6.0.3" />
     24    <PackageReference Include="SendGrid" Version="9.28.0" />
    2425    <PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
    2526    <PackageReference Include="Swashbuckle.Core" Version="5.6.0" />
Note: See TracChangeset for help on using the changeset viewer.