56 lines
1.9 KiB
C#
56 lines
1.9 KiB
C#
namespace Application.Students.Commands;
|
|
|
|
using System.Security.Cryptography;
|
|
using Application.Auth;
|
|
using Application.Students.DTOs;
|
|
using Domain.Entities;
|
|
using Domain.Ports.Repositories;
|
|
using Domain.ValueObjects;
|
|
using MediatR;
|
|
using Microsoft.Extensions.Configuration;
|
|
|
|
public record CreateStudentCommand(string Name, string Email, string? BaseUrl = null)
|
|
: IRequest<CreateStudentResult>;
|
|
|
|
public class CreateStudentHandler(
|
|
IStudentRepository studentRepository,
|
|
IPasswordService passwordService,
|
|
IUnitOfWork unitOfWork,
|
|
IConfiguration configuration)
|
|
: IRequestHandler<CreateStudentCommand, CreateStudentResult>
|
|
{
|
|
private static readonly TimeSpan ActivationExpiration = TimeSpan.FromHours(48);
|
|
|
|
public async Task<CreateStudentResult> Handle(CreateStudentCommand request, CancellationToken ct)
|
|
{
|
|
var email = Email.Create(request.Email);
|
|
var student = new Student(request.Name, email);
|
|
|
|
// Generate activation code
|
|
var activationCode = GenerateActivationCode();
|
|
var codeHash = passwordService.HashPassword(activationCode);
|
|
student.SetActivationCode(codeHash, ActivationExpiration);
|
|
|
|
studentRepository.Add(student);
|
|
await unitOfWork.SaveChangesAsync(ct);
|
|
|
|
var baseUrl = request.BaseUrl ?? configuration["App:BaseUrl"] ?? "http://localhost:4200";
|
|
var activationUrl = $"{baseUrl}/activate?code={activationCode}";
|
|
|
|
var studentDto = new StudentDto(student.Id, student.Name, student.Email.Value, 0, []);
|
|
|
|
return new CreateStudentResult(
|
|
studentDto,
|
|
activationCode,
|
|
activationUrl,
|
|
student.ActivationExpiresAt!.Value);
|
|
}
|
|
|
|
private static string GenerateActivationCode()
|
|
{
|
|
const string chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
|
|
var bytes = RandomNumberGenerator.GetBytes(12);
|
|
return new string(bytes.Select(b => chars[b % chars.Length]).ToArray());
|
|
}
|
|
}
|