Skip to content

Commit c6ea226

Browse files
committed
Refactor PasswdController and PasswdService for improved readability and error handling
1 parent 0c04340 commit c6ea226

File tree

2 files changed

+109
-102
lines changed

2 files changed

+109
-102
lines changed

src/management/passwd/passwd.controller.ts

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export class PasswdController {
4848
public async resetbycode(@Body() body: ResetByCodeDto, @Res() res: Response): Promise<Response> {
4949
const debug = {};
5050
this.logger.log('Reset by code : ' + body.token + ' code : ' + body.code);
51-
try{
51+
try {
5252
const [_, data] = await this.passwdService.resetByCode(body);
5353
if (process.env.NODE_ENV === 'development') {
5454
debug['_debug'] = data;
@@ -97,30 +97,24 @@ export class PasswdController {
9797
@ApiOperation({ summary: "Initialise le compte envoi un jeton par mail à l'identité" })
9898
@ApiResponse({ status: HttpStatus.OK })
9999
public async init(@Body() body: InitAccountDto, @Res() res: Response): Promise<Response> {
100-
const debug = {};
101-
const ok = await this.passwdService.initAccount(body);
102-
if (ok){
103-
return res.status(HttpStatus.OK).json({
104-
message: 'Email envoyé verifiez votre boite mail alternative et vos spam',
105-
...debug,
106-
});
107-
}else{
108-
return res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({
109-
message: 'Erreur serveur impossible d\'envoyer le mail',
110-
...debug,
111-
});
112-
}
113-
100+
const data = await this.passwdService.initAccount(body);
101+
return res.status(HttpStatus.OK).json({
102+
message: 'Email envoyé verifiez votre boite mail alternative et vos spam',
103+
data,
104+
});
114105
}
106+
115107
@Post('initmany')
116108
@ApiOperation({ summary: "Initialise plusieurs identités. envoi un jeton par mail à l'identité" })
117109
@ApiResponse({ status: HttpStatus.OK })
118110
public async initMany(@Body() body: InitManyDto, @Res() res: Response): Promise<Response> {
119-
const result = await this.passwdService.initMany(body);
111+
const data = await this.passwdService.initMany(body);
120112
return res.status(HttpStatus.OK).json({
121113
message: 'identités initialisées',
114+
data,
122115
});
123116
}
117+
124118
@Post('initreset')
125119
@ApiOperation({ summary: 'Demande l envoi de mail pour le reset' })
126120
@ApiResponse({ status: HttpStatus.OK })
@@ -134,6 +128,7 @@ export class PasswdController {
134128
...debug,
135129
});
136130
}
131+
137132
@Get('ioutdated')
138133
@ApiOperation({ summary: 'Compte donc l invitation d init n a pas été repondue dans les temps' })
139134
public async search(@Res() res: Response): Promise<

src/management/passwd/passwd.service.ts

Lines changed: 98 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {InjectRedis} from '@nestjs-modules/ioredis';
1+
import { InjectRedis } from '@nestjs-modules/ioredis';
22
import {
33
BadRequestException,
44
HttpException,
@@ -8,30 +8,31 @@ import {
88
NotFoundException,
99
} from '@nestjs/common';
1010
import * as crypto from 'crypto';
11-
import {randomInt} from 'crypto';
11+
import { randomInt } from 'crypto';
1212
import Redis from 'ioredis';
13-
import {AbstractService} from '~/_common/abstracts/abstract.service';
14-
import {ActionType} from '~/core/backends/_enum/action-type.enum';
15-
import {BackendsService} from '~/core/backends/backends.service';
16-
import {Jobs} from '~/core/jobs/_schemas/jobs.schema';
17-
import {AskTokenDto} from './_dto/ask-token.dto';
18-
import {ChangePasswordDto} from './_dto/change-password.dto';
19-
import {ResetPasswordDto} from './_dto/reset-password.dto';
20-
import {IdentitiesCrudService} from '../identities/identities-crud.service';
21-
import {get} from 'radash';
22-
import {Identities} from '../identities/_schemas/identities.schema';
23-
import {MailerService} from '@nestjs-modules/mailer';
24-
import {InitAccountDto} from '~/management/passwd/_dto/init-account.dto';
25-
import {ConfigService} from '@nestjs/config';
26-
import {ResetByCodeDto} from '~/management/passwd/_dto/reset-by-code.dto';
27-
import {PasswdadmService} from '~/settings/passwdadm.service';
28-
import {IdentityState} from '~/management/identities/_enums/states.enum';
29-
import {InitResetDto} from '~/management/passwd/_dto/init-reset.dto';
30-
import {SmsadmService} from '~/settings/smsadm.service';
31-
import {InitManyDto} from '~/management/passwd/_dto/init-many.dto';
32-
import {InitStatesEnum} from '~/management/identities/_enums/init-state.enum';
33-
import {MailadmService} from '~/settings/mailadm.service';
34-
import {DataStatusEnum} from "~/management/identities/_enums/data-status";
13+
import { AbstractService } from '~/_common/abstracts/abstract.service';
14+
import { ActionType } from '~/core/backends/_enum/action-type.enum';
15+
import { BackendsService } from '~/core/backends/backends.service';
16+
import { Jobs } from '~/core/jobs/_schemas/jobs.schema';
17+
import { AskTokenDto } from './_dto/ask-token.dto';
18+
import { ChangePasswordDto } from './_dto/change-password.dto';
19+
import { ResetPasswordDto } from './_dto/reset-password.dto';
20+
import { IdentitiesCrudService } from '../identities/identities-crud.service';
21+
import { get } from 'radash';
22+
import { Identities } from '../identities/_schemas/identities.schema';
23+
import { MailerService } from '@nestjs-modules/mailer';
24+
import { InitAccountDto } from '~/management/passwd/_dto/init-account.dto';
25+
import { ConfigService } from '@nestjs/config';
26+
import { ResetByCodeDto } from '~/management/passwd/_dto/reset-by-code.dto';
27+
import { PasswdadmService } from '~/settings/passwdadm.service';
28+
import { IdentityState } from '~/management/identities/_enums/states.enum';
29+
import { InitResetDto } from '~/management/passwd/_dto/init-reset.dto';
30+
import { SmsadmService } from '~/settings/smsadm.service';
31+
import { InitManyDto } from '~/management/passwd/_dto/init-many.dto';
32+
import { InitStatesEnum } from '~/management/identities/_enums/init-state.enum';
33+
import { MailadmService } from '~/settings/mailadm.service';
34+
import { DataStatusEnum } from "~/management/identities/_enums/data-status";
35+
import { SentMessageInfo } from 'nodemailer';
3536

3637
interface TokenData {
3738
k: string;
@@ -63,14 +64,15 @@ export class PasswdService extends AbstractService {
6364
) {
6465
super();
6566
}
67+
6668
//Initialisation du reset de mot de passe envoie un email ou par sms un code et fourni un token au front.
6769
// Le code est la clé du token
6870
public async initReset(initDto: InitResetDto): Promise<any> {
6971
//envoi du mail
7072
try {
7173
const identity = (await this.identities.findOne({ 'inetOrgPerson.uid': initDto.uid })) as Identities;
7274
//test si on peu reninitialiser le compte
73-
if ( identity.dataStatus === DataStatusEnum.INACTIVE || identity.dataStatus === DataStatusEnum.DELETED){
75+
if (identity.dataStatus === DataStatusEnum.INACTIVE || identity.dataStatus === DataStatusEnum.DELETED) {
7476
throw new BadRequestException(
7577
'Une erreur est survenue : Tentative de réinitialisation de mot de passe impossible',
7678
);
@@ -143,67 +145,70 @@ export class PasswdService extends AbstractService {
143145
return falseToken;
144146
}
145147
}
148+
146149
//Initialisation du compte. Envoi d' un mail avec un token pour l'init du compte
147-
public async initAccount(initDto: InitAccountDto): Promise<any> {
148-
//recherche de l'identity
150+
public async initAccount(initDto: InitAccountDto): Promise<SentMessageInfo> {
151+
const identity = (await this.identities.findOne({ 'inetOrgPerson.uid': initDto.uid })) as Identities;
152+
//test si on peu reninitialiser le compte
153+
if (identity.dataStatus === DataStatusEnum.INACTIVE || identity.dataStatus === DataStatusEnum.DELETED) {
154+
throw new BadRequestException(
155+
'Une erreur est survenue : Tentative de réinitialisation de mot de passe impossible',
156+
);
157+
}
158+
//envoi du mail
159+
const params = await this.passwdadmService.getPolicies();
160+
const mailAttribute = params.emailAttribute;
161+
this.logger.log('mailer.identityMailAttribute : ' + mailAttribute);
162+
163+
if (!mailAttribute) {
164+
this.logger.error('Error while initAccount identityMailAttribute Empty');
165+
throw new BadRequestException({
166+
message: "Une erreur est survenue : l'attribut de l'adresse mail n'est pas défini",
167+
error: 'Bad Request',
168+
statusCode: 400,
169+
});
170+
}
171+
172+
const mail = <string>get(identity.toObject(), mailAttribute);
173+
if (!mail) {
174+
this.logger.error('Error while initAccount identityMailAttribute not defined');
175+
throw new BadRequestException({
176+
message: "Une erreur est survenue : L'identité <" + (identity.inetOrgPerson?.cn || identity._id) + "> n'a pas d'adresse mail",
177+
error: 'Bad Request',
178+
statusCode: 400,
179+
});
180+
}
181+
182+
const smtpParams = await this.mailadmService.getParams();
183+
//demande du token
184+
const k = crypto.randomBytes(PasswdService.RANDOM_BYTES_K).toString('hex');
185+
const token = await this.askToken({ mail: mail, uid: initDto.uid }, k, params.initTokenTTL);
186+
//envoi du token
187+
149188
try {
150-
const identity = (await this.identities.findOne({ 'inetOrgPerson.uid': initDto.uid })) as Identities;
151-
//test si on peu reninitialiser le compte
152-
if ( identity.dataStatus === DataStatusEnum.INACTIVE || identity.dataStatus === DataStatusEnum.DELETED){
153-
throw new BadRequestException(
154-
'Une erreur est survenue : Tentative de réinitialisation de mot de passe impossible',
155-
);
156-
}
157-
//envoi du mail
158-
const params = await this.passwdadmService.getPolicies();
159-
const mailAttribute = params.emailAttribute;
160-
this.logger.log('mailer.identityMailAttribute : ' + mailAttribute);
161-
if (mailAttribute !== '') {
162-
const mail = <string>get(identity.toObject(), mailAttribute);
163-
if (mail) {
164-
const smtpParams = await this.mailadmService.getParams();
165-
//demande du token
166-
const k = crypto.randomBytes(PasswdService.RANDOM_BYTES_K).toString('hex');
167-
const token = await this.askToken({ mail: mail, uid: initDto.uid }, k, params.initTokenTTL);
168-
//envoi du token
169-
this.mailer
170-
.sendMail({
171-
from: smtpParams.sender,
172-
to: mail,
173-
subject: 'Activation de votre compte',
174-
template: 'initaccount',
175-
context: {
176-
displayName: identity.inetOrgPerson.displayName,
177-
uid: initDto.uid,
178-
url: this.config.get('frontPwd.url') + '/initaccount/' + token,
179-
mail: identity.inetOrgPerson.mail
180-
},
181-
})
182-
.then(() => {
183-
this.logger.log('Init compte envoyé pour uid' + initDto.uid + ' à ' + mail);
184-
this.setInitState(identity, InitStatesEnum.SENT);
185-
})
186-
.catch((e) => {
187-
this.logger.error('Erreur serveur lors de l envoi du mail' + e);
188-
throw new BadRequestException({
189-
message: 'Erreur serveur lors de l envoi du mail' + e,
190-
error: 'Bad Request',
191-
statusCode: 400,
192-
});
193-
});
189+
const send = await this.mailer.sendMail({
190+
from: smtpParams.sender,
191+
to: mail,
192+
subject: 'Activation de votre compte',
193+
template: 'initaccount',
194+
context: {
195+
displayName: identity.inetOrgPerson.displayName,
196+
uid: initDto.uid,
197+
url: this.config.get('frontPwd.url') + '/initaccount/' + token,
198+
mail: identity.inetOrgPerson.mail
199+
},
200+
})
201+
this.logger.log('Init compte envoyé pour uid ' + initDto.uid + ' à ' + mail);
202+
this.setInitState(identity, InitStatesEnum.SENT);
194203

195-
return true;
196-
} else {
197-
this.logger.error('Error while initAccount identityMailAttribute Empty');
198-
return false;
199-
}
200-
} else {
201-
this.logger.error('Error while initAccount identityMailAttribute not defined');
202-
return false;
203-
}
204+
return send;
204205
} catch (e) {
205-
this.logger.error('Error while initialize password. ' + e + ` (uid=${initDto?.uid})`);
206-
return false;
206+
this.logger.error('Error while sending init account email: ' + e);
207+
throw new BadRequestException({
208+
message: 'Erreur serveur lors de l envoi du mail',
209+
error: 'Bad Request',
210+
statusCode: 400,
211+
});
207212
}
208213
}
209214

@@ -214,7 +219,7 @@ export class PasswdService extends AbstractService {
214219
'inetOrgPerson.uid': passwdDto.uid,
215220
state: IdentityState.SYNCED,
216221
})) as Identities;
217-
if ( identity.dataStatus === DataStatusEnum.INACTIVE || identity.dataStatus === DataStatusEnum.DELETED){
222+
if (identity.dataStatus === DataStatusEnum.INACTIVE || identity.dataStatus === DataStatusEnum.DELETED) {
218223
throw new BadRequestException(
219224
'Une erreur est survenue : Tentative de réinitialisation de mot de passe impossible',
220225
);
@@ -246,7 +251,7 @@ export class PasswdService extends AbstractService {
246251
},
247252
);
248253
// on met actif l'identité
249-
await this.identities.model.updateOne({ _id:identity._id},{dataStatus: DataStatusEnum.ACTIVE})
254+
await this.identities.model.updateOne({ _id: identity._id }, { dataStatus: DataStatusEnum.ACTIVE })
250255
return result;
251256
} catch (e) {
252257
let job = undefined;
@@ -446,12 +451,19 @@ export class PasswdService extends AbstractService {
446451
if (identities.length === 0) {
447452
throw new HttpException('Aucune identité trouvée.', 404);
448453
}
454+
449455
const updated = await Promise.all(
450-
identities.map((identity) => {
456+
identities.map(async (identity) => {
451457
this.logger.verbose('send To :' + identity.get('inetOrgPerson.uid'));
452-
return this.initAccount({ uid: identity.get('inetOrgPerson.uid') });
458+
try {
459+
return await this.initAccount({ uid: identity.get('inetOrgPerson.uid') });
460+
} catch (e) {
461+
this.logger.error('Error while init account for ' + identity.get('inetOrgPerson.uid') + ': ' + e);
462+
return null;
463+
}
453464
}),
454465
);
466+
455467
return updated as any;
456468
}
457469

0 commit comments

Comments
 (0)