@@ -17,6 +17,10 @@ import {InitAccountDto} from "~/management/passwd/dto/init-account.dto";
1717import { ConfigService } from "@nestjs/config" ;
1818import { randomInt } from "crypto" ;
1919import { ResetByCodeDto } from "~/management/passwd/dto/reset-by-code-dto" ;
20+ import { PasswdadmService } from "~/settings/passwdadm/passwdadm.service" ;
21+ import { IdentityState } from "~/management/identities/_enums/states.enum" ;
22+ import { InitResetDto } from "~/management/passwd/dto/init-reset.dto" ;
23+ import { SmsService } from "~/management/passwd/sms-service" ;
2024
2125interface TokenData {
2226 k : string ;
@@ -43,51 +47,70 @@ export class PasswdService extends AbstractService {
4347 protected readonly identities : IdentitiesService ,
4448 protected mailer : MailerService ,
4549 protected config : ConfigService ,
50+ private passwdadmService : PasswdadmService ,
51+ private smsService : SmsService ,
4652 @InjectRedis ( ) private readonly redis : Redis
4753 ) {
4854 super ( ) ;
4955 }
50- public async initReset ( initDto : InitAccountDto ) :Promise < any > {
56+ //Initialisation du reset de mot de passe envoie un email ou par sms un code et fourni un token au front.
57+ // Le code est la clé du token
58+ public async initReset ( initDto : InitResetDto ) :Promise < any > {
5159 //envoi du mail
5260 try {
5361 const identity = await this . identities . findOne ( { 'inetOrgPerson.uid' : initDto . uid } ) as Identities ;
62+ const k = randomInt ( 100000 , 999999 ) ;
63+ //asking for padding
64+ const padd = await this . getPaddingForCode ( )
5465 const mailAttribute = this . config . get ( 'frontPwd.identityMailAttribute' )
55- this . logger . log ( "Reset passord asked for : " + initDto . uid )
56- if ( mailAttribute !== '' ) {
57- const mail = < string > get ( identity . toObject ( ) , mailAttribute )
58- const displayName = identity . inetOrgPerson . displayName
59- //const k=crypto.randomBytes(PasswdService.RANDOM_BYTES_CODE).toString('hex')
60- const k = randomInt ( 100000 , 999999 ) ;
61- //asking for padding
62- const padd = await this . getPaddingForCode ( )
63- const token = await this . askToken ( { mail : mail , uid : initDto . uid } , padd + k . toString ( 16 ) , PasswdService . CODE_EXPIRATION )
64- this . logger . log ( "Token :" + token + ' int : ' + k . toString ( 10 ) )
65- this . mailer . sendMail ( {
66- from : this . config . get ( 'mailer.sender' ) ,
67- to : mail ,
68- subject : 'Reinitialisation de votre mot de passe' ,
69- template : "resetaccount" ,
70- context :{
71- uid : identity . inetOrgPerson . uid ,
72- displayName : displayName ,
73- code : k
74- }
75-
76- } )
77- . then ( ( ) => {
78- this . logger . log ( "reset compte envoyé pour uid" + initDto . uid + " à " + mail )
79- } )
80- . catch ( ( e ) => {
81- throw new BadRequestException ( {
82- message : 'Erreur serveur lors de l envoi du mail' ,
83- error : "Bad Request" ,
84- statusCode : 400
85- } ) ;
66+ const mail = < string > get ( identity . toObject ( ) , mailAttribute )
67+ const token = await this . askToken ( { mail : mail , uid : initDto . uid } , padd + k . toString ( 16 ) , PasswdService . CODE_EXPIRATION )
68+ this . logger . log ( "Token :" + token + ' int : ' + k . toString ( 10 ) )
69+ if ( initDto . type === 0 ) {
70+ this . logger . log ( "Reset password asked by mail for : " + initDto . uid )
71+ if ( mailAttribute !== '' ) {
72+ const displayName = identity . inetOrgPerson . displayName
73+ this . mailer . sendMail ( {
74+ from : this . config . get ( 'mailer.sender' ) ,
75+ to : mail ,
76+ subject : 'Reinitialisation de votre mot de passe' ,
77+ template : "resetaccount" ,
78+ context :{
79+ uid : identity . inetOrgPerson . uid ,
80+ displayName : displayName ,
81+ code : k
82+ }
8683 } )
87- return token
84+ . then ( ( ) => {
85+ this . logger . log ( "reset compte envoyé pour uid" + initDto . uid + " à " + mail )
86+ } )
87+ . catch ( ( e ) => {
88+ throw new BadRequestException ( {
89+ message : 'Erreur serveur lors de l envoi du mail' ,
90+ error : "Bad Request" ,
91+ statusCode : 400
92+ } ) ;
93+ } )
94+ return token
95+ } else {
96+ return false
97+ }
8898 } else {
89- return false
99+ //envoi par SMS si c est possible
100+ const policies = await this . passwdadmService . getPolicies ( )
101+ if ( policies . resetBySms === true ) {
102+ this . logger . log ( "Reset password asked by SMS for : " + initDto . uid )
103+ const smsAttribute = this . config . get ( 'frontPwd.identityMobileAttribute' )
104+ if ( smsAttribute !== '' ) {
105+ const numTel = < string > get ( identity . toObject ( ) , smsAttribute )
106+ this . smsService . send ( numTel , "Votre code de reinitialisation : " + k . toString ( 10 ) )
107+ }
108+ return token
109+ } else {
110+ return false
111+ }
90112 }
113+
91114 } catch ( e ) {
92115 this . logger . error ( "Error while reseting password. " + e + ` (uid=${ initDto ?. uid } )` ) ;
93116 //on retoune un token qui ne sert à rien pour ne pas divulguer que l uid n existe pas
@@ -98,6 +121,7 @@ export class PasswdService extends AbstractService {
98121
99122
100123 }
124+ //Initialisation du compte. Envoi d' un mail avec un token pour l'init du compte
101125 public async initAccount ( initDto : InitAccountDto ) :Promise < any > {
102126 //recherche de l'identity
103127 try {
@@ -144,10 +168,19 @@ export class PasswdService extends AbstractService {
144168 }
145169
146170 }
171+ //Changement du password
147172 public async change ( passwdDto : ChangePasswordDto ) : Promise < [ Jobs , any ] > {
148173 try {
149- const identity = await this . identities . findOne ( { 'inetOrgPerson.uid' : passwdDto . uid } ) as Identities ;
150-
174+ const identity = await this . identities . findOne ( { 'inetOrgPerson.uid' : passwdDto . uid , 'state' :IdentityState . SYNCED } ) as Identities ;
175+ //verification de la police de mdp
176+ if ( await this . passwdadmService . checkPolicies ( passwdDto . newPassword ) === false ) {
177+ throw new BadRequestException ( {
178+ message : 'Une erreur est survenue : Le mot de passe ne respecte pas la politique des mots de passe' ,
179+ error : "Bad Request" ,
180+ statusCode : 400 ,
181+ } ) ;
182+ }
183+ //tout est ok en envoie au backend
151184 return await this . backends . executeJob ( ActionType . IDENTITY_PASSWORD_CHANGE , identity . _id , {
152185 ...passwdDto ,
153186 ...pick ( identity . toJSON ( ) , [ 'inetOrgPerson' ] ) ,
@@ -181,7 +214,8 @@ export class PasswdService extends AbstractService {
181214 }
182215 }
183216
184- public async askToken ( askToken : AskTokenDto , k , ttl ) : Promise < string > {
217+ // Genere un token pour les autres methodes
218+ public async askToken ( askToken : AskTokenDto , k , ttl : number ) : Promise < string > {
185219 try {
186220 /*
187221 if (ttl >0){
@@ -217,6 +251,7 @@ export class PasswdService extends AbstractService {
217251 throw new BadRequestException ( 'Impossible de générer un token, une erreur est survenue' ) ;
218252 }
219253 }
254+ // decrypte le token à l aide du code
220255 public async decryptTokenWithCode ( token : string , code : number ) : Promise < CipherData > {
221256 try {
222257 token = decodeURIComponent ( token )
@@ -238,6 +273,7 @@ export class PasswdService extends AbstractService {
238273 throw new BadRequestException ( 'Invalid token xx' ) ;
239274 }
240275 }
276+ // decrypte le token d'initialisation du compte
241277 public async decryptToken ( token : string ) : Promise < CipherData > {
242278 try {
243279 token = decodeURIComponent ( token )
@@ -258,8 +294,17 @@ export class PasswdService extends AbstractService {
258294 throw new BadRequestException ( 'Invalid token' ) ;
259295 }
260296 }
297+ // reset du password
261298 public async resetByCode ( data :ResetByCodeDto ) :Promise < [ Jobs , any ] > {
262299 this . logger . log ( 'resetByCode : ' + data . token + ' ' + data . code )
300+ //verification du passwordPolicies
301+ if ( await this . passwdadmService . checkPolicies ( data . newpassword ) === false ) {
302+ throw new BadRequestException ( {
303+ message : 'Une erreur est survenue : Le mot de passe ne respecte pas la politique de securité' ,
304+ error : "Bad Request" ,
305+ statusCode : 400 ,
306+ } ) ;
307+ }
263308 const tokenData = await this . decryptTokenWithCode ( data . token , data . code )
264309 this . logger . log ( 'dataToken :' + tokenData )
265310 try {
@@ -288,11 +333,12 @@ export class PasswdService extends AbstractService {
288333 throw new BadRequestException ( 'Une erreur est survenue : Tentative de réinitialisation de mot de passe impossible' ) ;
289334 }
290335 }
336+ // methode pour le reset par token (pour l initialisation du compte)
291337 public async reset ( data : ResetPasswordDto ) : Promise < [ Jobs , any ] > {
292338 const tokenData = await this . decryptToken ( data . token ) ;
293339
294340 try {
295- const identity = await this . identities . findOne ( { 'inetOrgPerson.uid' : tokenData . uid } ) as Identities ;
341+ const identity = await this . identities . findOne ( { 'inetOrgPerson.uid' : tokenData . uid , 'state' : IdentityState . SYNCED } ) as Identities ;
296342
297343 const [ _ , response ] = await this . backends . executeJob (
298344 ActionType . IDENTITY_PASSWORD_RESET ,
0 commit comments