feat(backend): #28 templates email validation compte (Handlebars)
- Templates .hbs parent principal, co-parent, AM + lien create-password - app_name / app_url / expéditeur via ConfigService (sendEmail) - validateUser: renouvelle token création MDP + envoi email si sans password - Dist: assets *.hbs (nest-cli) - Tests unitaires MailService (mock sendEmail) - Doc liste tickets #28 terminé Made-with: Cursor
This commit is contained in:
@@ -11,6 +11,7 @@ import { AssistantesMaternellesModule } from '../assistantes_maternelles/assista
|
||||
import { Parents } from 'src/entities/parents.entity';
|
||||
import { GestionnairesModule } from './gestionnaires/gestionnaires.module';
|
||||
import { MailModule } from 'src/modules/mail/mail.module';
|
||||
import { AppConfigModule } from 'src/modules/config/config.module';
|
||||
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature(
|
||||
@@ -24,6 +25,7 @@ import { MailModule } from 'src/modules/mail/mail.module';
|
||||
AssistantesMaternellesModule,
|
||||
GestionnairesModule,
|
||||
MailModule,
|
||||
AppConfigModule,
|
||||
],
|
||||
controllers: [UserController],
|
||||
providers: [UserService],
|
||||
|
||||
@@ -9,7 +9,8 @@ import * as bcrypt from 'bcrypt';
|
||||
import { StatutValidationType, Validation } from "src/entities/validations.entity";
|
||||
import { Parents } from "src/entities/parents.entity";
|
||||
import { AssistanteMaternelle } from "src/entities/assistantes_maternelles.entity";
|
||||
import { MailService } from "src/modules/mail/mail.service";
|
||||
import { MailService, ValidationAccountEmailKind } from "src/modules/mail/mail.service";
|
||||
import { AppConfigService } from "src/modules/config/config.service";
|
||||
import * as crypto from 'crypto';
|
||||
|
||||
@Injectable()
|
||||
@@ -30,6 +31,8 @@ export class UserService {
|
||||
private readonly assistantesRepository: Repository<AssistanteMaternelle>,
|
||||
|
||||
private readonly mailService: MailService,
|
||||
|
||||
private readonly appConfigService: AppConfigService,
|
||||
) { }
|
||||
|
||||
async createUser(dto: CreateUserDto, currentUser?: Users): Promise<Users> {
|
||||
@@ -265,6 +268,57 @@ export class UserService {
|
||||
comment,
|
||||
});
|
||||
await this.validationRepository.save(validation);
|
||||
|
||||
// Ticket #28 — email création MDP (parents / AM), Handlebars + lien app_url
|
||||
const roleCibleMdp =
|
||||
savedUser.role === RoleType.PARENT || savedUser.role === RoleType.ASSISTANTE_MATERNELLE;
|
||||
if (roleCibleMdp && !savedUser.password) {
|
||||
try {
|
||||
const joursExpiration = await this.appConfigService.get<number>(
|
||||
'password_reset_token_expiry_days',
|
||||
7,
|
||||
);
|
||||
if (!savedUser.token_creation_mdp) {
|
||||
savedUser.token_creation_mdp = crypto.randomUUID();
|
||||
}
|
||||
const exp = new Date();
|
||||
exp.setDate(exp.getDate() + joursExpiration);
|
||||
savedUser.token_creation_mdp_expire_le = exp;
|
||||
await this.usersRepository.save(savedUser);
|
||||
|
||||
let kind: ValidationAccountEmailKind = 'am';
|
||||
if (savedUser.role === RoleType.ASSISTANTE_MATERNELLE) {
|
||||
kind = 'am';
|
||||
} else if (savedUser.numero_dossier) {
|
||||
const parentsDossier = await this.usersRepository.find({
|
||||
where: { numero_dossier: savedUser.numero_dossier, role: RoleType.PARENT },
|
||||
order: { cree_le: 'ASC' },
|
||||
});
|
||||
const premier = parentsDossier[0];
|
||||
kind =
|
||||
premier && premier.id !== savedUser.id ? 'parent_coparent' : 'parent_primary';
|
||||
} else {
|
||||
kind = 'parent_primary';
|
||||
}
|
||||
|
||||
await this.mailService.sendValidatedAccountPasswordSetupEmail(
|
||||
{
|
||||
email: savedUser.email,
|
||||
prenom: savedUser.prenom ?? '',
|
||||
nom: savedUser.nom ?? '',
|
||||
token: savedUser.token_creation_mdp,
|
||||
numeroDossier: savedUser.numero_dossier,
|
||||
},
|
||||
kind,
|
||||
);
|
||||
} catch (err) {
|
||||
this.logger.warn(
|
||||
`Envoi email validation compte (#28) échoué pour ${savedUser.email}`,
|
||||
err as Error,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return savedUser;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user