source: iknow-api/Services/Implementations/AuthService.cs@ 334981d

Last change on this file since 334981d was 334981d, checked in by Stefan-Saveski <stefan@…>, 10 months ago

Changed appdb context injection location.

  • Property mode set to 100644
File size: 6.6 KB
RevLine 
[fc7b4b4]1using System.IdentityModel.Tokens.Jwt;
2using System.Security.Claims;
3using System.Text;
4using BCrypt.Net;
[4e061d8]5using iknow_api.Services;
[5eb7847]6using iknow_api.Models;
[271178d]7using iknow_api.DTOs;
8using iknow_api.Repositories;
[fc7b4b4]9using Microsoft.IdentityModel.Tokens;
[334981d]10using iknow_api.Data;
11using Microsoft.EntityFrameworkCore;
[fc7b4b4]12
[271178d]13namespace iknow_api.Services
[fc7b4b4]14{
15 public class AuthService : IAuthService
16 {
17 private readonly IUserRepository _userRepository;
[1e58098]18 private readonly IRefreshTokenRepository _refreshTokenRepository;
[4e061d8]19 private readonly IRefreshTokenService _refreshTokenService;
[fc7b4b4]20 private readonly IConfiguration _configuration;
[334981d]21 private readonly AppDbContext _context;
[fc7b4b4]22
[334981d]23 public AuthService(IUserRepository userRepository, IConfiguration configuration,
24 IRefreshTokenService refreshTokenService, IRefreshTokenRepository refreshTokenRepository,
25 AppDbContext context)
[fc7b4b4]26 {
27 _userRepository = userRepository;
28 _configuration = configuration;
[4e061d8]29 _refreshTokenService = refreshTokenService;
[1e58098]30 _refreshTokenRepository = refreshTokenRepository;
[334981d]31 _context = context;
[fc7b4b4]32 }
33
[cb8e531]34 public async Task<bool> RegisterAsync(RegisterDto registerDto)
[fc7b4b4]35 {
[f0fc386]36 // Debug: Log all incoming DTO values
37 Console.WriteLine("=== RegisterDto Debug Info ===");
38 Console.WriteLine($"Name: {registerDto.Name}");
39 Console.WriteLine($"Email: {registerDto.Email}");
40 Console.WriteLine($"majorType: {registerDto.majorType}");
41 Console.WriteLine($"enrollmentYear: {registerDto.enrollmentYear}");
42 Console.WriteLine($"quotaType: {registerDto.quotaType}");
43 Console.WriteLine($"Role: {registerDto.Role}");
44 Console.WriteLine($"tip: {registerDto.tip}");
45 Console.WriteLine("==============================");
46
47 // Check if user already exists
[cb8e531]48 if (await _userRepository.UserExistsAsync(registerDto.Email))
[f0fc386]49 throw new InvalidOperationException("User with this email already exists");
[fc7b4b4]50
[334981d]51 // Use a transaction to ensure all entities are saved together
52 using var transaction = await _context.Database.BeginTransactionAsync();
53 try
[fc7b4b4]54 {
[334981d]55 var user = new User
56 {
57 Name = registerDto.Name,
58 Surname = registerDto.Surname,
59 Index = registerDto.Index,
60 Email = registerDto.Email,
61 PasswordHash = BCrypt.Net.BCrypt.HashPassword(registerDto.Password),
62 Bday = DateTime.SpecifyKind(registerDto.Bday, DateTimeKind.Utc),
63 CreatedAt = DateTime.UtcNow,
64 Role = (Models.UserRole)registerDto.Role,
65 EMBG = registerDto.EMBG
66 };
[fc7b4b4]67
[334981d]68 _context.User.Add(user);
69 await _context.SaveChangesAsync();
70
71 int userId = user.Id;
72
73 var contactInfo = new ContactInfo
74 {
75 UserId = userId,
76 city = registerDto.city,
77 address = registerDto.address,
78 municipality = registerDto.municipality,
79 phoneNumber = registerDto.phoneNumber,
80 microsoftEmail = registerDto.microsoftEmail
81 };
82
83 var enrollmentInfo = new EnrollmentInfo
84 {
85 UserId = userId,
86 enrollmentYear = registerDto.enrollmentYear,
87 quota = (Models.Quota)registerDto.quotaType,
88 MajorId = registerDto.majorType
89 };
90
91 var highSchool = new HighSchool
92 {
93 UserId = userId,
94 GPA = registerDto.gpa,
95 tip = (Models.type)registerDto.tip
96 };
97
98 _context.ContactInfo.Add(contactInfo);
99 _context.EnrollmentInfo.Add(enrollmentInfo);
100 _context.HighSchool.Add(highSchool);
101
102 // Save all related entities in a single transaction
103 await _context.SaveChangesAsync();
104 await transaction.CommitAsync();
105
106 return true;
107 }
108 catch
[c0256f3]109 {
[334981d]110 await transaction.RollbackAsync();
111 throw;
112 }
[fc7b4b4]113 }
114
[4e061d8]115 public async Task<AuthResultDto?> LoginAsync(LoginDto loginDto)
[fc7b4b4]116 {
[cb8e531]117 var user = await _userRepository.GetUserByUsernameAsync(loginDto.Email);
118 if (user == null || !BCrypt.Net.BCrypt.Verify(loginDto.Password, user.PasswordHash))
[fc7b4b4]119 return null;
120
[4e061d8]121 var result = new AuthResultDto
122 {
123 AccessToken = CreateToken(user)
124 };
125
126 if (loginDto.GenerateRefreshToken)
127 {
[334981d]128 result.RefreshToken = await _refreshTokenService.GenerateRefreshToken(user.Id);
[4e061d8]129 }
130
131 return result;
[fc7b4b4]132 }
133
134 public async Task<int> GetUsersCountAsync()
135 {
136 return await _userRepository.GetUsersCountAsync();
137 }
138
[1e58098]139 public async Task<AuthResultDto> GenerateNewJWT(VerifyRefreshTokenDto token)
140 {
141 int userid = await _refreshTokenRepository.GetUserId(token.token) ?? 0;
[586825e]142 User ?user = await _userRepository.GetOnlyUserByIdAsync(userid);
[1e58098]143
144 var result = new AuthResultDto
145 {
[586825e]146 AccessToken = CreateToken(user)
[1e58098]147 };
148
149 return result;
150 }
151
[fc7b4b4]152 private string CreateToken(User user)
153 {
154 var claims = new[]
155 {
156 new Claim("id", user.Id.ToString()),
[5eb7847]157 new Claim("email", user.Email ?? string.Empty),
[cb8e531]158 new Claim("role", user.Role.ToString())
[fc7b4b4]159 };
160
161 var keyString = _configuration["Jwt:Key"];
162 if (string.IsNullOrEmpty(keyString))
163 throw new Exception("JWT Key is missing in configuration!");
164
165 var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(keyString));
166 var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
167
168 var token = new JwtSecurityToken(
[cb8e531]169 issuer: "iknow-api",
170 audience: "iknow-api",
[fc7b4b4]171 claims: claims,
[cb8e531]172 expires: DateTime.UtcNow.AddHours(1),
[fc7b4b4]173 signingCredentials: creds
174 );
175
176 return new JwtSecurityTokenHandler().WriteToken(token);
177 }
178 }
179}
Note: See TracBrowser for help on using the repository browser.