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

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

Changed appdb context injection location.

  • Property mode set to 100644
File size: 6.6 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;
10using iknow_api.Data;
11using Microsoft.EntityFrameworkCore;
12
13namespace iknow_api.Services
14{
15 public class AuthService : IAuthService
16 {
17 private readonly IUserRepository _userRepository;
18 private readonly IRefreshTokenRepository _refreshTokenRepository;
19 private readonly IRefreshTokenService _refreshTokenService;
20 private readonly IConfiguration _configuration;
21 private readonly AppDbContext _context;
22
23 public AuthService(IUserRepository userRepository, IConfiguration configuration,
24 IRefreshTokenService refreshTokenService, IRefreshTokenRepository refreshTokenRepository,
25 AppDbContext context)
26 {
27 _userRepository = userRepository;
28 _configuration = configuration;
29 _refreshTokenService = refreshTokenService;
30 _refreshTokenRepository = refreshTokenRepository;
31 _context = context;
32 }
33
34 public async Task<bool> RegisterAsync(RegisterDto registerDto)
35 {
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
48 if (await _userRepository.UserExistsAsync(registerDto.Email))
49 throw new InvalidOperationException("User with this email already exists");
50
51 // Use a transaction to ensure all entities are saved together
52 using var transaction = await _context.Database.BeginTransactionAsync();
53 try
54 {
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 };
67
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
109 {
110 await transaction.RollbackAsync();
111 throw;
112 }
113 }
114
115 public async Task<AuthResultDto?> LoginAsync(LoginDto loginDto)
116 {
117 var user = await _userRepository.GetUserByUsernameAsync(loginDto.Email);
118 if (user == null || !BCrypt.Net.BCrypt.Verify(loginDto.Password, user.PasswordHash))
119 return null;
120
121 var result = new AuthResultDto
122 {
123 AccessToken = CreateToken(user)
124 };
125
126 if (loginDto.GenerateRefreshToken)
127 {
128 result.RefreshToken = await _refreshTokenService.GenerateRefreshToken(user.Id);
129 }
130
131 return result;
132 }
133
134 public async Task<int> GetUsersCountAsync()
135 {
136 return await _userRepository.GetUsersCountAsync();
137 }
138
139 public async Task<AuthResultDto> GenerateNewJWT(VerifyRefreshTokenDto token)
140 {
141 int userid = await _refreshTokenRepository.GetUserId(token.token) ?? 0;
142 User ?user = await _userRepository.GetOnlyUserByIdAsync(userid);
143
144 var result = new AuthResultDto
145 {
146 AccessToken = CreateToken(user)
147 };
148
149 return result;
150 }
151
152 private string CreateToken(User user)
153 {
154 var claims = new[]
155 {
156 new Claim("id", user.Id.ToString()),
157 new Claim("email", user.Email ?? string.Empty),
158 new Claim("role", user.Role.ToString())
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(
169 issuer: "iknow-api",
170 audience: "iknow-api",
171 claims: claims,
172 expires: DateTime.UtcNow.AddHours(1),
173 signingCredentials: creds
174 );
175
176 return new JwtSecurityTokenHandler().WriteToken(token);
177 }
178 }
179}
Note: See TracBrowser for help on using the repository browser.