Feature 11034: Forgot Password in OSM
[osm/NG-UI.git] / src / app / users / add-user / AddEditUserComponent.ts
1 /*
2  Copyright 2020 TATA ELXSI
3
4  Licensed under the Apache License, Version 2.0 (the 'License');
5  you may not use this file except in compliance with the License.
6  You may obtain a copy of the License at
7
8   http://www.apache.org/licenses/LICENSE-2.0
9
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15
16  Author: KUMARAN M (kumaran.m@tataelxsi.co.in), RAJESH S (rajesh.s@tataelxsi.co.in), BARATH KUMAR R (barath.r@tataelxsi.co.in)
17 */
18 /**
19  * @file Add Edit Component.
20  */
21 import { HttpHeaders } from '@angular/common/http';
22 import { ChangeDetectorRef, Component, Injector, Input, OnInit } from '@angular/core';
23 import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms';
24 import { Router } from '@angular/router';
25 import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
26 import { TranslateService } from '@ngx-translate/core';
27 import { NotifierService } from 'angular-notifier';
28 import { AuthenticationService } from 'AuthenticationService';
29 import { APIURLHEADER, ERRORDATA, LOGINPARAMS, MODALCLOSERESPONSEDATA, TYPESECTION } from 'CommonModel';
30 import { environment } from 'environment';
31 import { RestService } from 'RestService';
32 import { Observable } from 'rxjs';
33 import { SharedService, isNullOrUndefined } from 'SharedService';
34
35 /**
36  * Creating component
37  * @Component takes AddEditUserComponent.html as template url
38  */
39 @Component({
40     selector: 'app-add-edit-user',
41     templateUrl: './AddEditUserComponent.html',
42     styleUrls: ['./AddEditUserComponent.scss']
43 })
44 /** Exporting a class @exports AddEditUserComponent */
45 export class AddEditUserComponent implements OnInit {
46     /** To inject services @public */
47     public injector: Injector;
48
49     /** Instance for active modal service @public */
50     public activeModal: NgbActiveModal;
51
52     /** FormGroup user Edit Account added to the form @ html @public */
53     public userForm: FormGroup;
54
55     /** Form submission Add */
56     public submitted: boolean = false;
57
58     /** Input contains Modal dialog component Instance @public */
59     @Input() public userTitle: string;
60
61     /** Input contains Modal dialog component Instance @public */
62     @Input() public userType: string;
63
64     /** Input contains Modal dialog component Instance @public */
65     @Input() public userID: string;
66
67     /** Input contains Modal dialog component Instance @public */
68     @Input() public userName: string;
69
70     /** Input contains Modal dialog component Instance @public */
71     @Input() public email: string;
72
73     /** Check the loading results for loader status @public */
74     public isLoadingResults: boolean = false;
75
76     /** Give the message for the loading @public */
77     public message: string = 'PLEASEWAIT';
78
79     /** Contains token @public */
80     public idToken: string;
81
82     /** Holds list of domains @public */
83     public domains: TYPESECTION[] = [];
84
85     /** Variable contains type is changepassword or not @public */
86     public isPassword: boolean;
87
88     /** Variable contains type is forgotpassword or not @public */
89     public isforgetPassword: boolean;
90
91     /** Variable contains to show otp or not @public */
92     public isOtp: boolean = false;
93
94     /** Variable holds value for first login user @public */
95     public isFirstLogin: boolean = Boolean(sessionStorage.getItem('firstLogin') === 'true');
96
97     /** Observable Hold the value of subscription  @public */
98     public isForgotPassword$: Observable<boolean>;
99
100     /** Observable Hold the value of subscription  @public */
101     public forgotPassword: boolean;
102
103     /** Variable contains payload @private */
104     private payload: {};
105
106     /** Variable contains add user payload @private */
107     private addPayload: {};
108
109     /** Instance of the rest service @private */
110     private restService: RestService;
111
112     /** FormBuilder instance added to the formBuilder @private */
113     private formBuilder: FormBuilder;
114
115     /** Controls the header form @private */
116     private headers: HttpHeaders;
117
118     /** Notifier service to popup notification @private */
119     private notifierService: NotifierService;
120
121     /** Contains tranlsate instance @private */
122     private translateService: TranslateService;
123
124     /** Contains all methods related to shared @private */
125     private sharedService: SharedService;
126
127     /** ModalData instance of modal @private  */
128     private modalData: MODALCLOSERESPONSEDATA;
129
130     /** Utilizes auth service for any auth operations @private */
131     private authService: AuthenticationService;
132
133     /** Holds the instance of router class @private */
134     private router: Router;
135
136     /** Detect changes for the User Input */
137     private cd: ChangeDetectorRef;
138
139     constructor(injector: Injector) {
140         this.injector = injector;
141         this.formBuilder = this.injector.get(FormBuilder);
142         this.restService = this.injector.get(RestService);
143         this.activeModal = this.injector.get(NgbActiveModal);
144         this.notifierService = this.injector.get(NotifierService);
145         this.translateService = this.injector.get(TranslateService);
146         this.sharedService = this.injector.get(SharedService);
147         this.authService = this.injector.get(AuthenticationService);
148         this.router = this.injector.get(Router);
149         this.cd = this.injector.get(ChangeDetectorRef);
150
151         /** Initializing Form Action */
152         this.userForm = this.formBuilder.group({
153             userName: ['', Validators.required],
154             email_id: [null, [Validators.required, Validators.pattern(this.sharedService.REGX_EMAIL_PATTERN)]],
155             password: [null, [Validators.required, Validators.pattern(this.sharedService.REGX_PASSWORD_PATTERN)]],
156             password2: [null, Validators.required],
157             old_password: [null, Validators.required],
158             domain_name: [null],
159             otp: [null]
160         });
161     }
162
163     /** convenience getter for easy access to form fields */
164     get f(): FormGroup['controls'] { return this.userForm.controls; }
165
166     /** Lifecyle Hooks the trigger before component is instantiate @public */
167     public ngOnInit(): void {
168         this.headers = new HttpHeaders({
169             'Content-Type': 'application/json',
170             Accept: 'application/json',
171             'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0'
172         });
173         if (this.userType === 'add') {
174             this.getDomainList();
175         } else if (this.userType === 'editUserName') {
176             this.userForm.patchValue({ userName: this.userName });
177         } else if (this.isFirstLogin) {
178             this.isPassword = true;
179         } else if (this.userType === 'editmail') {
180             this.userForm.patchValue({ email_id: this.email });
181         }
182     }
183
184     /** On modal submit users acction will called @public */
185     public userAction(userType: string): void {
186         if (userType === 'editPassword' || this.isforgetPassword || userType === 'change_password') {
187             this.getFormControl('userName').setValidators([]);
188             this.getFormControl('userName').updateValueAndValidity();
189             this.getFormControl('old_password').setValidators([]);
190             this.getFormControl('old_password').updateValueAndValidity();
191             this.getFormControl('email_id').setValidators([]);
192             this.getFormControl('email_id').updateValueAndValidity();
193         } else if (userType === 'editUserName') {
194             this.getFormControl('password').setValidators([]);
195             this.getFormControl('password').updateValueAndValidity();
196             this.getFormControl('password2').setValidators([]);
197             this.getFormControl('password2').updateValueAndValidity();
198             this.getFormControl('old_password').setValidators([]);
199             this.getFormControl('old_password').updateValueAndValidity();
200             this.getFormControl('email_id').setValidators([]);
201             this.getFormControl('email_id').updateValueAndValidity();
202         } else if (userType === 'changePassword') {
203             this.getFormControl('userName').setValidators([]);
204             this.getFormControl('userName').updateValueAndValidity();
205             this.getFormControl('email_id').setValidators([]);
206             this.getFormControl('email_id').updateValueAndValidity();
207         } else if (userType === 'add') {
208             this.getFormControl('old_password').setValidators([]);
209             this.getFormControl('old_password').updateValueAndValidity();
210             this.getFormControl('email_id').setValidators([]);
211             this.getFormControl('email_id').updateValueAndValidity();
212         }
213         this.checkType(userType);
214         this.submitted = true;
215         this.modalData = {
216             message: 'Done'
217         };
218         this.sharedService.cleanForm(this.userForm);
219         if (!this.userForm.invalid) {
220             if (this.userForm.value.password !== this.userForm.value.password2) {
221                 this.notifierService.notify('error', this.translateService.instant('PAGE.USERS.PASSWORDCONFLICT'));
222                 return;
223             }
224             if (userType === 'add') {
225                 this.addUser();
226             } else if (userType === 'forgotPassword') {
227                 this.forgetPassword();
228             } else if (userType === 'change_password') {
229                 this.changePassword();
230             } else {
231                 this.editUser();
232             }
233         }
234     }
235
236     /** Used to set the validation and value and update the validation and value @public */
237     public checkType(userType: string): void {
238         if (userType === 'forgotPassword') {
239             this.getFormControl('password').setValidators([]);
240             this.getFormControl('password').updateValueAndValidity();
241             this.getFormControl('password2').setValidators([]);
242             this.getFormControl('password2').updateValueAndValidity();
243             this.getFormControl('old_password').setValidators([]);
244             this.getFormControl('old_password').updateValueAndValidity();
245         } else if (userType === 'editmail') {
246             this.getFormControl('password').setValidators([]);
247             this.getFormControl('password').updateValueAndValidity();
248             this.getFormControl('password2').setValidators([]);
249             this.getFormControl('password2').updateValueAndValidity();
250             this.getFormControl('old_password').setValidators([]);
251             this.getFormControl('old_password').updateValueAndValidity();
252             this.getFormControl('userName').setValidators([]);
253             this.getFormControl('userName').updateValueAndValidity();
254         }
255     }
256
257     /** Forgot password @public */
258     public forgetPassword(): void {
259         this.isLoadingResults = true;
260         if (isNullOrUndefined(this.userForm.value.otp)) {
261             this.payload = JSON.stringify({
262                 username: (this.userForm.value.userName).toLowerCase(),
263                 email_id: (this.userForm.value.email_id)
264             });
265         } else {
266             this.getFormControl('userName').enable();
267             this.payload = JSON.stringify({
268                 username: (this.userForm.value.userName).toLowerCase(),
269                 otp: (this.userForm.value.otp)
270             });
271         }
272         const apiURLHeader: APIURLHEADER = {
273             url: environment.GENERATETOKEN_URL,
274             httpOptions: { headers: this.headers }
275         };
276         this.restService.postResource(apiURLHeader, this.payload).subscribe((result:
277             { email: string, id: string, user_id: string, message: string, otp: string }
278         ): void => {
279             if (result.email === 'sent') {
280                 this.getFormControl('userName').disable();
281                 this.getFormControl('email_id').disable();
282                 this.isOtp = true;
283                 this.cd.detectChanges();
284                 this.notifierService.notify('success', this.translateService.instant('PAGE.USERS.USERSUCCESSFULLY'));
285             }
286             if (result.message === 'valid_otp') {
287                 this.activeModal.close(this.modalData);
288                 this.getFormControl('email_id').enable();
289                 sessionStorage.setItem('id_token', result.id);
290                 sessionStorage.setItem('user_id', result.user_id);
291                 sessionStorage.setItem('mail', this.userForm.value.email_id);
292                 this.userType = 'change_password';
293                 sessionStorage.setItem('usertype', this.userType);
294                 this.idToken = sessionStorage.getItem('id_token');
295                 this.notifierService.notify('success', this.translateService.instant('PAGE.USERS.OTPSUCCESSFULLY'));
296                 if (!isNullOrUndefined(sessionStorage.getItem('id_token')) && !isNullOrUndefined(sessionStorage.getItem('mail'))) {
297                     this.authService.forgotPassword.next(true);
298                     this.isForgotPassword$ = this.authService.forgotPassword;
299                     this.authService.isForgotPassword.subscribe((res: boolean): void => {
300                         this.forgotPassword = res;
301                     });
302                     if (this.forgotPassword === true) {
303                         this.router.navigate(['/forgotpassword/changepassword/', encodeURI(this.idToken)]).catch((): void => {
304                             // Catch Navigation Error
305                         });
306                     }
307                 }
308             } else if (result.otp === 'invalid') {
309                 this.getFormControl('userName').disable();
310                 this.notifierService.notify('warning', this.translateService.instant('PAGE.USERS.INVALIDOTP'));
311             }
312             this.isLoadingResults = false;
313         }, (error: ERRORDATA): void => {
314             // eslint-disable-next-line @typescript-eslint/no-magic-numbers
315             if (error.error.status === 401 || error.error.status === 429 || error.error.status === 404) {
316                 this.activeModal.close(this.modalData);
317                 this.router.navigate(['/login']).catch((): void => {
318                     // Catch Navigation Error
319                 });
320             }
321             this.restService.handleError(error, 'post');
322             this.isLoadingResults = false;
323         });
324     }
325
326     /** Change password @public */
327     public changePassword(): void {
328         this.isLoadingResults = true;
329         this.userID = sessionStorage.getItem('user_id');
330         const payLoad: LOGINPARAMS = {};
331         payLoad.password = (this.userForm.value.password);
332         payLoad.email_id = (sessionStorage.getItem('mail'));
333         const apiURLHeader: APIURLHEADER = {
334             url: environment.USERS_URL + '/' + this.userID,
335             httpOptions: { headers: this.headers }
336         };
337         this.restService.patchResource(apiURLHeader, payLoad).subscribe((result: {}): void => {
338             this.activeModal.close(this.modalData);
339             this.router.navigate(['/login']).catch((): void => {
340                 // Catch Navigation Error
341             });
342             this.authService.logoutResponse();
343             this.notifierService.notify('success', this.translateService.instant('PAGE.USERS.CHANGEDSUCCESSFULLY'));
344             this.isLoadingResults = false;
345         }, (error: ERRORDATA): void => {
346             this.restService.handleError(error, 'put');
347             this.isLoadingResults = false;
348         });
349     }
350
351     /** Add user @public */
352     public addUser(): void {
353         this.isLoadingResults = true;
354         if (!isNullOrUndefined(this.userForm.value.email_id) && this.userForm.value.email_id !== '') {
355             this.addPayload = JSON.stringify({
356                 username: (this.userForm.value.userName).toLowerCase(),
357                 password: (this.userForm.value.password),
358                 email_id: (this.userForm.value.email_id),
359                 domain_name: !isNullOrUndefined(this.userForm.value.domain_name) ? this.userForm.value.domain_name : undefined
360             });
361         } else {
362             this.addPayload = JSON.stringify({
363                 username: (this.userForm.value.userName).toLowerCase(),
364                 password: (this.userForm.value.password),
365                 domain_name: !isNullOrUndefined(this.userForm.value.domain_name) ? this.userForm.value.domain_name : undefined
366             });
367         }
368         const apiURLHeader: APIURLHEADER = {
369             url: environment.USERS_URL,
370             httpOptions: { headers: this.headers }
371         };
372         this.restService.postResource(apiURLHeader, this.addPayload).subscribe((result: {}): void => {
373             this.activeModal.close(this.modalData);
374             this.isLoadingResults = false;
375             this.notifierService.notify('success', this.translateService.instant('PAGE.USERS.CREATEDSUCCESSFULLY'));
376         }, (error: ERRORDATA): void => {
377             this.restService.handleError(error, 'post');
378             this.isLoadingResults = false;
379         });
380     }
381
382     /** Edit user @public */
383     public editUser(): void {
384         this.isLoadingResults = true;
385         const payLoad: LOGINPARAMS = {};
386         if (this.userType === 'editPassword') {
387             payLoad.password = (this.userForm.value.password);
388         } else if (this.userType === 'changePassword') {
389             payLoad.password = (this.userForm.value.password);
390             payLoad.old_password = (this.userForm.value.old_password);
391         } else if (this.userType === 'editmail') {
392             payLoad.email_id = (this.userForm.value.email_id);
393         }
394         else {
395             payLoad.username = this.userForm.value.userName.toLowerCase();
396         }
397         const apiURLHeader: APIURLHEADER = {
398             url: environment.USERS_URL + '/' + this.userID,
399             httpOptions: { headers: this.headers }
400         };
401         this.restService.patchResource(apiURLHeader, payLoad).subscribe((result: {}): void => {
402             this.checkUsername(payLoad);
403             this.activeModal.close(this.modalData);
404             if (this.isFirstLogin) {
405                 this.notifierService.notify('success', this.translateService.instant('PAGE.USERS.CHANGEPASSWORD'));
406                 this.authService.destoryToken();
407             } else if (this.userType === 'changePassword' && (!this.isFirstLogin)) {
408                 this.notifierService.notify('success', this.translateService.instant('PAGE.USERS.CHANGEDSUCCESSFULLY'));
409             } else {
410                 this.notifierService.notify('success', this.translateService.instant('PAGE.USERS.EDITEDSUCCESSFULLY'));
411             }
412             this.isLoadingResults = false;
413         }, (error: ERRORDATA): void => {
414             if (this.isFirstLogin) {
415                 this.notifierService.notify('error', error.error.detail);
416                 this.activeModal.close(this.modalData);
417                 this.authService.destoryToken();
418             } else {
419                 this.restService.handleError(error, 'put');
420             }
421             this.isLoadingResults = false;
422         });
423     }
424     /** Close the modal and destroy subscribe @public */
425     public close(): void {
426         if (this.isFirstLogin) {
427             this.activeModal.close(this.modalData);
428             this.authService.destoryToken();
429         } else if (this.userType === 'forgotPassword') {
430             this.activeModal.close(this.modalData);
431             this.router.navigate(['/login']).catch((): void => {
432                 // Catch Navigation Error
433             });
434         } else if (this.userType === 'change_password') {
435             this.authService.logoutResponse();
436             this.activeModal.close(this.modalData);
437             this.router.navigate(['/forgotpassword']).catch((): void => {
438                 // Catch Navigation Error
439             });
440         } else {
441             this.activeModal.close(this.modalData);
442         }
443     }
444     /** Get domain name list @private */
445     private getDomainList(): void {
446         this.isLoadingResults = true;
447         this.sharedService.getDomainName().subscribe((domainList: TYPESECTION[]): void => {
448             this.domains = domainList;
449             this.isLoadingResults = false;
450         }, (error: ERRORDATA): void => {
451             this.isLoadingResults = false;
452             this.restService.handleError(error, 'get');
453         });
454     }
455
456     /** Used to get the AbstractControl of controlName passed @private */
457     private getFormControl(controlName: string): AbstractControl {
458         // eslint-disable-next-line security/detect-object-injection
459         return this.userForm.controls[controlName];
460     }
461
462     /** Method to check loggedin username and update  @private */
463     private checkUsername(payLoad: LOGINPARAMS): void {
464         const logUsername: string = sessionStorage.getItem('username');
465         if (this.userType === 'editUserName' && logUsername === this.userName) {
466             this.authService.userName.next(payLoad.username);
467             sessionStorage.setItem('username', payLoad.username);
468         }
469     }
470 }