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

Last change on this file since 93c368a was ce1f8d4, 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 
[fc7b4b4]1using System.IdentityModel.Tokens.Jwt;
2using System.Security.Claims;
3using System.Text;
4using BCrypt.Net;
[5eb7847]5using iknow_api.Models;
[271178d]6using iknow_api.DTOs;
7using iknow_api.Repositories;
[fc7b4b4]8using Microsoft.IdentityModel.Tokens;
[334981d]9using iknow_api.Data;
[fc7b4b4]10
[271178d]11namespace iknow_api.Services
[fc7b4b4]12{
13 public class AuthService : IAuthService
14 {
15 private readonly IUserRepository _userRepository;
[1e58098]16 private readonly IRefreshTokenRepository _refreshTokenRepository;
[4e061d8]17 private readonly IRefreshTokenService _refreshTokenService;
[fc7b4b4]18 private readonly IConfiguration _configuration;
[334981d]19 private readonly AppDbContext _context;
[fc7b4b4]20
[334981d]21 public AuthService(IUserRepository userRepository, IConfiguration configuration,
22 IRefreshTokenService refreshTokenService, IRefreshTokenRepository refreshTokenRepository,
23 AppDbContext context)
[fc7b4b4]24 {
25 _userRepository = userRepository;
26 _configuration = configuration;
[4e061d8]27 _refreshTokenService = refreshTokenService;
[1e58098]28 _refreshTokenRepository = refreshTokenRepository;
[334981d]29 _context = context;
[fc7b4b4]30 }
31
[cb8e531]32 public async Task<bool> RegisterAsync(RegisterDto registerDto)
[fc7b4b4]33 {
[f0fc386]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
[cb8e531]46 if (await _userRepository.UserExistsAsync(registerDto.Email))
[f0fc386]47 throw new InvalidOperationException("User with this email already exists");
[fc7b4b4]48
[334981d]49 // Use a transaction to ensure all entities are saved together
50 using var transaction = await _context.Database.BeginTransactionAsync();
51 try
[fc7b4b4]52 {
[334981d]53 var user = new User
54 {
55 Name = registerDto.Name,
[ab652ff]56 MiddleName = registerDto.MiddleName,
[334981d]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,
[ab652ff]64 EMBG = registerDto.EMBG,
65 Nationality = registerDto.nationality,
66 Citizenship = registerDto.citizenship,
67 Gender = registerDto.gender
[334981d]68 };
[fc7b4b4]69
[334981d]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,
[ab652ff]78 City = registerDto.city,
79 Address = registerDto.address,
80 Municipality = registerDto.municipality,
81 PhoneNumber = registerDto.phoneNumber,
82 MicrosoftEmail = registerDto.microsoftEmail
[334981d]83 };
84
85 var enrollmentInfo = new EnrollmentInfo
86 {
87 UserId = userId,
[2e17229]88 EnrollmentYear = registerDto.enrollmentYear,
89 Quota = (Models.Quota)registerDto.quotaType,
[ab652ff]90 MajorId = registerDto.majorType,
91 StudyStatus = registerDto.studyStatus,
92 StudyType = registerDto.studyType
[334981d]93 };
94
95 var highSchool = new HighSchool
96 {
97 UserId = userId,
98 GPA = registerDto.gpa,
[ab652ff]99 HighSchoolType = (Models.HighSchoolType)registerDto.tip
[334981d]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
[c0256f3]113 {
[334981d]114 await transaction.RollbackAsync();
115 throw;
116 }
[fc7b4b4]117 }
118
[4e061d8]119 public async Task<AuthResultDto?> LoginAsync(LoginDto loginDto)
[fc7b4b4]120 {
[cb8e531]121 var user = await _userRepository.GetUserByUsernameAsync(loginDto.Email);
122 if (user == null || !BCrypt.Net.BCrypt.Verify(loginDto.Password, user.PasswordHash))
[fc7b4b4]123 return null;
124
[ce1f8d4]125 var result = new AuthResultDto
[4e061d8]126 {
[ce1f8d4]127 AccessToken = CreateToken(user),
128 Role = user.Role.ToString()
[4e061d8]129 };
130
131 if (loginDto.GenerateRefreshToken)
132 {
[334981d]133 result.RefreshToken = await _refreshTokenService.GenerateRefreshToken(user.Id);
[4e061d8]134 }
135
136 return result;
[fc7b4b4]137 }
138
139 public async Task<int> GetUsersCountAsync()
140 {
141 return await _userRepository.GetUsersCountAsync();
142 }
143
[1e58098]144 public async Task<AuthResultDto> GenerateNewJWT(VerifyRefreshTokenDto token)
145 {
146 int userid = await _refreshTokenRepository.GetUserId(token.token) ?? 0;
[ce1f8d4]147 User? user = await _userRepository.GetOnlyUserByIdAsync(userid);
[1e58098]148
[ce1f8d4]149 if (user == null)
150 throw new InvalidOperationException("User not found for provided refresh token.");
151
152 return new AuthResultDto
[1e58098]153 {
[ce1f8d4]154 AccessToken = CreateToken(user),
155 Role = user.Role.ToString()
[1e58098]156 };
157 }
158
[fc7b4b4]159 private string CreateToken(User user)
160 {
161 var claims = new[]
162 {
163 new Claim("id", user.Id.ToString()),
[5eb7847]164 new Claim("email", user.Email ?? string.Empty),
[cb8e531]165 new Claim("role", user.Role.ToString())
[fc7b4b4]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
[ce1f8d4]175 var jwt = new JwtSecurityToken(
[cb8e531]176 issuer: "iknow-api",
177 audience: "iknow-api",
[fc7b4b4]178 claims: claims,
[cb8e531]179 expires: DateTime.UtcNow.AddHours(1),
[fc7b4b4]180 signingCredentials: creds
181 );
182
[ce1f8d4]183 return new JwtSecurityTokenHandler().WriteToken(jwt);
[fc7b4b4]184 }
185 }
186}
Note: See TracBrowser for help on using the repository browser.