user.component.ts 16.7 KB
Newer Older
1
import { Component, OnInit } from '@angular/core';
2
3
import { SignaturesContentService } from '../../service/signatures.service';
import { NotificationService } from '../../service/notification.service';
4
import { HttpClient, HttpHeaders } from '@angular/common/http';
5
import { MatDialog } from '@angular/material/dialog';
6
import {map, finalize, tap, catchError} from 'rxjs/operators';
7
8
import { ActivatedRoute, Router } from '@angular/router';
import { ConfirmComponent } from '../../plugins/confirm.component';
9
import { TranslateService } from '@ngx-translate/core';
10
import { AuthService } from '../../service/auth.service';
11
import { of } from 'rxjs';
12
import { AlertController } from '@ionic/angular';
13
14
15
16
17
18
19
20


export interface User {
    id: string;
    firstname: string;
    lastname: string;
    login: string;
    email: string;
21
    phone: string;
22
    picture: string;
23
    isRest: boolean;
24
    signatureModes: string[];
25
    canSendActivationNotification: boolean;
26
27
28
29
30
}

@Component({
    selector: 'app-administration-user',
    templateUrl: 'user.component.html',
Alex ORLUC's avatar
Alex ORLUC committed
31
    styleUrls: ['../administration.scss', 'user.component.scss'],
32
33
34
35
36
37
})

export class UserComponent implements OnInit {

    creationMode: boolean = true;
    loading: boolean = true;
38
39
40
41
42
43
    user: User = {
        id: '',
        firstname: '',
        lastname: '',
        login: '',
        email: '',
44
        phone: '',
45
        picture: '',
46
        isRest: false,
47
48
        signatureModes: ['stamp'],
        canSendActivationNotification: false
49
    };
50
    userClone: User;
51
    title: string = '';
52
53
54
    hideCurrentPassword: Boolean = true;
    hideNewPassword: Boolean = true;
    hideNewPasswordConfirm: Boolean = true;
55
    currentTool = 'info';
56

57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
    // HANDLE PASSWORD
    passwordRules: any = {
        minLength: { enabled: false, value: 0 },
        complexityUpper: { enabled: false, value: 0 },
        complexityNumber: { enabled: false, value: 0 },
        complexitySpecial: { enabled: false, value: 0 },
        renewal: { enabled: false, value: 0 },
        historyLastUse: { enabled: false, value: 0 },
    };
    passwordRest: any = {
        newPassword: '',
        passwordConfirmation: ''
    };

    ruleText = '';
    otherRuleText = '';

    showPassword = false;
    handlePassword: any = {
        error: false,
        errorMsg: ''
    };

80
81
    manageableGroups: number[] = [];

82
83
84
85
86
87
88
89
    constructor(
        public http: HttpClient,
        private translate: TranslateService,
        private route: ActivatedRoute,
        private router: Router,
        public signaturesService: SignaturesContentService,
        public notificationService: NotificationService,
        public dialog: MatDialog,
90
91
        public authService: AuthService,
        public alertController: AlertController
92
    ) {
93
94
95
    }

    ngOnInit(): void {
96
        this.route.params.subscribe(async (params: any) => {
97
98
            if (params['id'] === undefined) {
                this.creationMode = true;
99
100
101
102
103
104
105
                this.title = this.translate.instant('lang.userCreation');
                this.user = {
                    id: '',
                    firstname: '',
                    lastname: '',
                    login: '',
                    email: '',
106
                    phone: '',
107
                    picture: '',
108
                    signatureModes: ['stamp'],
109
110
                    isRest: false,
                    canSendActivationNotification: false
111
                };
112
                await this.getManageableGroups();
113
                await this.getGroups();
114
                this.loading = false;
115
116
117
            } else {
                this.creationMode = false;
                this.http.get('../rest/users/' + params['id'])
118
119
120
121
122
123
124
125
126
                    .pipe(
                        map((data: any) => data.user),
                        finalize(() => this.loading = false)
                    )
                    .subscribe({
                        next: data => {
                            this.user = data;
                            this.userClone = JSON.parse(JSON.stringify(this.user));
                            this.title = this.user.firstname + ' ' + this.user.lastname;
127
                            if (this.user.isRest) {
128
129
130
                                this.getPassRules({ detail: {
                                    checked: true
                                } });
131
                            }
132
133
                        },
                    });
134
135
136
137
138
            }
        });
    }

    canValidate() {
139
140
141
        if (this.user.isRest && this.passwordRest.newPassword !== '' && (this.handlePassword.error || this.passwordRest.passwordConfirmation !== this.passwordRest.newPassword)) {
            return false;
        } else if (JSON.stringify(this.user) === JSON.stringify(this.userClone) && this.passwordRest.newPassword === '') {
142
143
144
145
146
147
148
            return false;
        } else {
            return true;
        }
    }

    onSubmit() {
149
150
151
152
153
154
155
156
        if (this.creationMode) {
            this.createUser();
        } else {
            this.modifyUser();
        }
    }

    modifyUser() {
157
        this.loading = true;
158
        this.http.put('../rest/users/' + this.user.id, this.user)
159
            .pipe(
160
161
                finalize(() => this.loading = false),
                tap(() => {
162
                    if (this.authService.user.id === this.user.id) {
163
                        this.authService.updateUserInfoWithTokenRefresh();
164
                    }
165
166
167
                    if (this.passwordRest.newPassword !== '') {
                        this.updateRestUser();
                    }
168
169
                    this.router.navigate(['/administration/users']);
                    this.notificationService.success('lang.userUpdated');
170
171
172
173
174
175
176
                }),
                catchError((err: any) => {
                    this.notificationService.handleErrors(err);
                    return of(false);
                })
            )
            .subscribe();
177
178
    }

179
180
181
182
183
184
185
186
187
188
189
190
191
    updateRestUser() {
        const headers = new HttpHeaders({
            'Authorization': 'Bearer ' + this.authService.getToken()
        });
        this.http.put('../rest/users/' + this.user.id + '/password', this.passwordRest, { headers: headers })
            .subscribe(() => {
                this.passwordRest.newPassword = '';
                this.passwordRest.passwordConfirmation = '';
            }, (err) => {
                this.notificationService.handleErrors(err);
            });
    }

192
193
194
195
    createUser() {
        this.loading = true;
        this.http.post('../rest/users', this.user)
            .pipe(
196
197
                finalize(() => this.loading = false),
                tap((data: any) => {
198
199
200
201
                    if (this.user.isRest) {
                        this.user.id = data.id;
                        this.updateRestUser();
                    }
202
203
                    this.router.navigate(['/administration/users']);
                    this.notificationService.success('lang.userAdded');
204
205
206
207
208
209
210
                }),
                catchError((err: any) => {
                    this.notificationService.handleErrors(err);
                    return of(false);
                })
            )
            .subscribe();
211
212
213
    }

    delete() {
214
        const dialogRef = this.dialog.open(ConfirmComponent, { autoFocus: false, data: { mode: '', title: 'lang.confirmMsg', msg: '' } });
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231

        dialogRef.afterClosed().subscribe(result => {
            if (result === 'yes') {
                this.loading = true;
                this.http.delete('../rest/users/' + this.user.id)
                    .pipe(
                        finalize(() => this.loading = false)
                    )
                    .subscribe({
                        next: () => {
                            this.router.navigate(['/administration/users']);
                            this.notificationService.success('lang.userDeleted');
                        },
                    });
            }
        });
    }
232
233

    cancel() {
Alex ORLUC's avatar
Alex ORLUC committed
234
        this.router.navigate(['/administration/users']);
235
    }
236
237

    getPassRules(ev: any) {
238
        if (ev.detail.checked) {
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
            this.handlePassword.error = false;
            this.handlePassword.errorMsg = '';

            this.http.get('../rest/passwordRules')
                .subscribe((data: any) => {
                    const ruleTextArr: String[] = [];
                    const otherRuleTextArr: String[] = [];

                    data.rules.forEach((rule: any) => {
                        if (rule.label === 'minLength') {
                            this.passwordRules.minLength.enabled = rule.enabled;
                            this.passwordRules.minLength.value = rule.value;
                            if (rule.enabled) {
                                this.translate.get('lang.minLengthChar', { charLength: rule.value }).subscribe((res: string) => {
                                    ruleTextArr.push(res);
                                });
                            }

                        } else if (rule.label === 'complexityUpper') {
                            this.passwordRules.complexityUpper.enabled = rule.enabled;
                            this.passwordRules.complexityUpper.value = rule.value;
                            if (rule.enabled) {
                                ruleTextArr.push('lang.upperRequired');
                            }

                        } else if (rule.label === 'complexityNumber') {
                            this.passwordRules.complexityNumber.enabled = rule.enabled;
                            this.passwordRules.complexityNumber.value = rule.value;
                            if (rule.enabled) {
                                ruleTextArr.push('lang.numberRequired');
                            }

                        } else if (rule.label === 'complexitySpecial') {
                            this.passwordRules.complexitySpecial.enabled = rule.enabled;
                            this.passwordRules.complexitySpecial.value = rule.value;
                            if (rule.enabled) {
                                ruleTextArr.push('lang.specialCharRequired');
                            }
                        } else if (rule.label === 'renewal') {
                            this.passwordRules.renewal.enabled = rule.enabled;
                            this.passwordRules.renewal.value = rule.value;
                            if (rule.enabled) {
                                this.translate.get('lang.renewalInfo', { time: rule.value }).subscribe((res: string) => {
                                    otherRuleTextArr.push(res);
                                });
                            }
                        } else if (rule.label === 'historyLastUse') {
                            this.passwordRules.historyLastUse.enabled = rule.enabled;
                            this.passwordRules.historyLastUse.value = rule.value;
                            if (rule.enabled) {
                                this.translate.get('lang.historyUseInfo', { countPwd: rule.value }).subscribe((res: string) => {
                                    otherRuleTextArr.push(res);
                                });
                            }
                        }

                    });
                    this.ruleText = ruleTextArr.join(', ');
                    this.otherRuleText = otherRuleTextArr.join('<br/>');
                }, (err) => {
                    this.notificationService.handleErrors(err);
                });
        }
    }

    checkPasswordValidity(password: string) {
        this.handlePassword.error = true;

        if (!password.match(/[A-Z]/g) && this.passwordRules.complexityUpper.enabled) {
            this.handlePassword.errorMsg = 'lang.upperRequired';
        } else if (!password.match(/[0-9]/g) && this.passwordRules.complexityNumber.enabled) {
            this.handlePassword.errorMsg = 'lang.numberRequired';
        } else if (!password.match(/[^A-Za-z0-9]/g) && this.passwordRules.complexitySpecial.enabled) {
            this.handlePassword.errorMsg = 'lang.specialCharRequired';
        } else if (password.length < this.passwordRules.minLength.value && this.passwordRules.minLength.enabled) {
            this.translate.get('lang.minLengthChar', { charLength: this.passwordRules.minLength.value }).subscribe((res: string) => {
                this.handlePassword.errorMsg = res;
            });
        } else {
            this.handlePassword.error = false;
            this.handlePassword.errorMsg = '';
        }
    }
322
323
324

    toggleSignMode(signMode: any, state: boolean) {
        if (state) {
325
326
327
            if (this.user.signatureModes.indexOf(signMode.id) === -1) {
                this.user.signatureModes.push(signMode.id);
            }
328
        } else {
329
            this.user.signatureModes = this.user.signatureModes.filter((item: any) => item !== signMode.id);
330
331
        }
    }
332
333
334
335

    initTab(val: any) {
        this.currentTool = val;
    }
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367

    async resendActivationNotification() {
        const alert = await this.alertController.create({
            header: this.translate.instant('lang.confirmMsg'),
            buttons: [
                {
                    text: this.translate.instant('lang.no'),
                    role: 'cancel',
                    cssClass: 'secondary',
                    handler: () => { }
                },
                {
                    text: this.translate.instant('lang.yes'),
                    handler: () => {
                        this.http.put('../rest/users/' + this.user.id + '/accountActivationNotification', {})
                            .pipe(
                                tap(() => {
                                    this.notificationService.success(this.translate.instant('lang.activationNotificationSend'));
                                }),
                                catchError((err: any) => {
                                    this.notificationService.handleErrors(err);
                                    return of(false);
                                })
                            )
                            .subscribe();
                    }
                }
            ]
        });

        await alert.present();
    }
368
369
370
371
372

    getGroups() {
        return new Promise((resolve) => {
            this.http.get('../rest/groups').pipe(
                tap((data: any) => {
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
                    const groups: any[] = [];
                    data.groups.forEach((element: any) => {
                        groups.push(
                            {
                                id: element.id,
                                label: element.label,
                                checked: this.manageableGroups.indexOf(element.id) > -1 ? true : false
                            }
                        );

                    });
                    this.user['groups'] = groups;
                    resolve(true);
                }),
                catchError((err: any) => {
                    this.notificationService.handleErrors(err);
                    return of(false);
                })
            ).subscribe();
        });
    }

    getManageableGroups() {
        return new Promise((resolve) => {
            this.http.get('../rest/manageablegroups').pipe(
                tap((data: any) => {
                    this.manageableGroups = data.groups;
400
401
402
403
404
405
406
407
408
                    resolve(true);
                }),
                catchError((err: any) => {
                    this.notificationService.handleErrors(err);
                    return of(false);
                })
            ).subscribe();
        });
    }
409
410
411
412
413
414
415
416
417
418
419
420
421
422

    async unlinkGroup(groupId: number) {
        const alert = await this.alertController.create({
            header: this.translate.instant('lang.confirmMsg'),
            buttons: [
                {
                    text: this.translate.instant('lang.no'),
                    role: 'cancel',
                    cssClass: 'secondary',
                    handler: () => { }
                },
                {
                    text: this.translate.instant('lang.yes'),
                    handler: () => {
423
                        this.http.delete(`../rest/groups/${groupId}/users/${this.user.id}`, {})
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
                            .pipe(
                                finalize(() => this.loading = false)
                            )
                            .subscribe({
                                next: data => {
                                    const indexToDelete = this.user['groups'].findIndex((group: any) => group.id === groupId);
                                    this.user['groups'].splice(indexToDelete, 1);
                                    this.notificationService.success('lang.groupDeleted');
                                },
                                error: err => {
                                    this.notificationService.handleErrors(err);
                                }
                            });
                    }
                }
            ]
        });
        await alert.present();
    }
443
}