@@ -10,11 +10,11 @@ import { AskTokenDto } from './dto/ask-token.dto';
1010import { ChangePasswordDto } from './dto/change-password.dto' ;
1111import { ResetPasswordDto } from './dto/reset-password.dto' ;
1212import { IdentitiesService } from '../identities/identities.service' ;
13- import { pick } from 'radash' ;
13+ import { pick , get } from 'radash' ;
1414import { Identities } from '../identities/_schemas/identities.schema' ;
15- import { PasswordPolicies } from "~/management/passwd/_schemas/PasswordPolicies " ;
16- import { Model } from "mongoose " ;
17- import { InjectModel } from "@nestjs/mongoose " ;
15+ import { MailerModule , MailerService } from "@nestjs-modules/mailer " ;
16+ import { InitAccountDto } from "~/management/passwd/dto/init-account.dto " ;
17+ import { ConfigService } from "@nestjs/config " ;
1818
1919interface TokenData {
2020 k : string ;
@@ -31,20 +31,63 @@ interface CipherData {
3131export class PasswdService extends AbstractService {
3232 public static readonly RANDOM_BYTES_K = 16 ;
3333 public static readonly RANDOM_BYTES_IV = 12 ;
34+ public static readonly RANDOM_BYTES_CODE = 5 ;
3435
3536 public static readonly TOKEN_ALGORITHM = 'aes-256-gcm' ;
3637
37- public static readonly TOKEN_EXPIRATION = 3600 ;
38+ public static readonly TOKEN_EXPIRATION = 604800 ;
39+ public static readonly CODE_EXPIRATION = 900 ;
3840
3941 public constructor (
4042 protected readonly backends : BackendsService ,
4143 protected readonly identities : IdentitiesService ,
42- @InjectRedis ( ) private readonly redis : Redis ,
43- @InjectModel ( PasswordPolicies . name ) protected passwordPolicies : Model < PasswordPolicies >
44+ protected mailer : MailerService ,
45+ protected config : ConfigService ,
46+ @InjectRedis ( ) private readonly redis : Redis
4447 ) {
4548 super ( ) ;
4649 }
50+ public async initAccount ( initDto : InitAccountDto ) :Promise < any > {
51+ //recherche de l'identity
52+ try {
53+ const identity = await this . identities . findOne ( { 'inetOrgPerson.uid' : initDto . uid } ) as Identities ;
54+ //envoi du mail
55+ const mailAttribute = this . config . get ( 'frontPwd.identityMailAttribute' )
56+ this . logger . log ( "mailer.identityMailAttribute : " + mailAttribute )
57+ if ( mailAttribute !== '' ) {
58+ const mail = < string > get ( identity . toObject ( ) , mailAttribute )
59+ //demande du token
60+ const token = await this . askToken ( { mail : mail , uid : initDto . uid } )
61+ //envoi du token
62+ this . mailer . sendMail ( {
63+ from : this . config . get ( 'mailer.sender' ) ,
64+ to : mail ,
65+ subject : 'Activation de votre compte' ,
66+ template : "initaccount" ,
67+ context :{
68+ uid : initDto . uid ,
69+ url :this . config . get ( 'frontPwd.url' ) + '/initaccount/' + token
70+ }
71+
72+ } )
73+ . then ( ( ) => {
74+ this . logger . log ( "Init compte envoyé pour uid" + initDto . uid + " à " + mail )
75+ } )
76+ . catch ( ( e ) => {
77+ this . logger . error ( "Erreur envoi mail" + e )
78+ } )
79+
80+ return true
81+ } else {
82+ this . logger . error ( "Error while initAccount identityMailAttribute nor defined" ) ;
83+ return false
84+ }
85+ } catch ( e ) {
86+ this . logger . error ( "Error while changing password. " + e + ` (uid=${ initDto ?. uid } )` ) ;
87+ return false
88+ }
4789
90+ }
4891 public async change ( passwdDto : ChangePasswordDto ) : Promise < [ Jobs , any ] > {
4992 try {
5093 const identity = await this . identities . findOne ( { 'inetOrgPerson.uid' : passwdDto . uid } ) as Identities ;
@@ -81,8 +124,40 @@ export class PasswdService extends AbstractService {
81124 } ) ;
82125 }
83126 }
127+ /*
128+ public async askCode(askCode: AdkCode):Promise<[string,string]>{
129+ try {
130+ await this.identities.findOne({'inetOrgPerson.uid': askCode.uid});
131+ const code = crypto.randomBytes(PasswdService.RANDOM_BYTES_CODE).toString('utf8')
132+ const k = crypto.randomBytes(PasswdService.RANDOM_BYTES_K).toString('hex');
133+ const iv = crypto.randomBytes(PasswdService.RANDOM_BYTES_IV).toString('base64');
134+ const cipher = crypto.createCipheriv(PasswdService.TOKEN_ALGORITHM, k, iv);
135+
136+ let ciphertext = cipher.update(
137+ JSON.stringify(<CipherData>{ code:code,uid: askToken.uid}),
138+ 'utf8',
139+ 'base64',
140+ );
141+ ciphertext += cipher.final('base64');
142+
143+ await this.redis.set(
144+ ciphertext,
145+ JSON.stringify(<TokenData>{
146+ k,
147+ iv,
148+ tag: cipher.getAuthTag().toString('base64'),
149+ }),
150+ );
151+ await this.redis.expire(ciphertext, PasswdService.TOKEN_EXPIRATION);
152+ return [k,cipherText]
153+ } catch (e) {
154+ this.logger.error("Error while ask Code. " + e + ` (uid=${askToken?.uid})`);
155+ throw new BadRequestException('Impossible de générer un token, une erreur est survenue');
156+ }
157+ }
158+ */
84159
85- public async askToken ( askToken : AskTokenDto ) : Promise < string > {
160+ public async askToken ( askToken : AskTokenDto ) : Promise < string > {
86161 try {
87162 await this . identities . findOne ( { 'inetOrgPerson.uid' : askToken . uid } ) ;
88163
@@ -106,7 +181,7 @@ export class PasswdService extends AbstractService {
106181 } ) ,
107182 ) ;
108183 await this . redis . expire ( ciphertext , PasswdService . TOKEN_EXPIRATION ) ;
109- return ciphertext ;
184+ return encodeURIComponent ( ciphertext ) ;
110185 } catch ( e ) {
111186 this . logger . error ( "Error while ask token. " + e + ` (uid=${ askToken ?. uid } )` ) ;
112187 throw new BadRequestException ( 'Impossible de générer un token, une erreur est survenue' ) ;
@@ -115,6 +190,7 @@ export class PasswdService extends AbstractService {
115190
116191 public async decryptToken ( token : string ) : Promise < CipherData > {
117192 try {
193+ token = decodeURIComponent ( token )
118194 const result = await this . redis . get ( token ) ;
119195 const cypherData : TokenData = JSON . parse ( result ) ;
120196
@@ -164,11 +240,5 @@ export class PasswdService extends AbstractService {
164240 }
165241 }
166242
167- public async getPolicies ( ) : Promise < any > {
168- const passwordPolicies = await this . passwordPolicies . findOne ( )
169- if ( passwordPolicies === null ) {
170- return new this . passwordPolicies ( )
171- }
172- return passwordPolicies
173- }
243+
174244}
0 commit comments