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

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

Refactor and enhance application structure

Enhanced error handling in AuthController with detailed exception handling for user registration. Updated UserDTO to improve JSON serialization and renamed enums for clarity. Introduced new entities (Major, PassedSubject, etc.) and seeded initial data in AppDbContext.

Replaced legacy migrations with 20251208203846_InitialCreate, reflecting the updated schema. Fixed typographical errors and improved JSON serialization in Program.cs with case-insensitive property matching and enum handling.

Refactored repository interfaces for better null safety. Improved debugging in AuthService and updated connection strings. Added the PassedSubject entity and cleaned up redundant code and unused imports for better maintainability.

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