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

Last change on this file since 4b35197 was 4b35197, checked in by Stefan-Saveski <stefansaveski19@…>, 8 months ago

Added role to sign in.

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