Feature 11034: Forgot Password in OSM
[osm/NG-UI.git] / src / services / AuthenticationService.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 Auth service
20  */
21 import { HttpHeaders } from '@angular/common/http';
22 import { Injectable, Injector } from '@angular/core';
23 import { Router } from '@angular/router';
24 import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
25 import { Idle } from '@ng-idle/core';
26 import { APIURLHEADER, ERRORDATA } from 'CommonModel';
27 import { environment } from 'environment';
28 import { BehaviorSubject, Observable } from 'rxjs';
29 import { map } from 'rxjs/operators';
30 import { isNullOrUndefined } from 'SharedService';
31 import { SharedService } from 'SharedService';
32 import { ProjectModel } from '../models/VNFDModel';
33 import { RestService } from './RestService';
34
35 /**
36  * An Injectable is a class adorned with the @Injectable decorator function.
37  * @Injectable takes a metadata object that tells Angular how to compile and run module code
38  */
39 @Injectable()
40 export class AuthenticationService {
41     /** To inject services @public */
42     public injector: Injector;
43
44     /** Instance for modal service @public */
45     public modalService: NgbModal;
46
47     /** Handle 401 response for multiple API calls */
48     public handle401: boolean = true;
49
50     /** contains return URL link @public */
51     public returnUrl: string;
52
53     /** Holds the username in condition of type BehaviorSubject<string> @public */
54     public userName: BehaviorSubject<string> = new BehaviorSubject<string>('');
55
56     /** Holds the projectname in condition of type BehaviorSubject<string> @public */
57     public projectName$: BehaviorSubject<string> = new BehaviorSubject<string>('');
58
59     /** Holds the instance of router class @private */
60     private router: Router;
61
62     /** Holds the logged in condition of type BehaviorSubject<boolean> @private */
63     private loggedIn: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
64
65     /** Holds the change password in condition of type BehaviorSubject<boolean> @private */
66     private changePassword: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
67
68     /** Holds the forgotpassword in condition of type BehaviorSubject<string> @public */
69     public forgotPassword: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
70
71     /** Hold Rest Service Objects */
72     private restService: RestService;
73
74     /** Holds auth payloads @private */
75     private payLoad: {};
76
77     /** Holds header options for auth service @private */
78     private httpOptions: HttpHeaders;
79
80     /** handle idle time out service @private */
81     private idle: Idle;
82
83     /** Contains all methods related to shared @private */
84     private sharedService: SharedService;
85
86     /** create the instance of the component */
87     constructor(injector: Injector) {
88         this.injector = injector;
89         this.router = this.injector.get(Router);
90         this.restService = this.injector.get(RestService);
91         this.modalService = this.injector.get(NgbModal);
92         this.idle = this.injector.get(Idle);
93         this.sharedService = this.injector.get(SharedService);
94         if (sessionStorage.getItem('username') !== null) {
95             this.loggedIn.next(true);
96             this.changePassword.next(false);
97         } else if (sessionStorage.getItem('firstLogin') !== null) {
98             this.changePassword.next(true);
99             this.loggedIn.next(false);
100         } else {
101             this.loggedIn.next(false);
102         }
103         this.userName.next(sessionStorage.getItem('username'));
104         this.redirectToPage();
105     }
106
107     /**
108      * Get method for  Observable loggedIn
109      */
110     get isLoggedIn(): Observable<boolean> {
111         return this.loggedIn.asObservable();
112     }
113
114     /**
115      * Get method for  Observable changepassword
116      */
117     get isChangePassword(): Observable<boolean> {
118         return this.changePassword.asObservable();
119     }
120
121     /**
122      * Get method for  Observable forgotssword
123      */
124     get isForgotPassword(): Observable<boolean> {
125         return this.forgotPassword.asObservable();
126     }
127
128     /**
129      * Get method for Observable Username
130      */
131     get username(): Observable<string> {
132         return this.userName.asObservable();
133     }
134
135     /** Get method for project name */
136     get ProjectName(): Observable<string> {
137         return this.projectName$.asObservable();
138     }
139
140     /**
141      * Send request and authenticate the user
142      * @param user of type User
143      */
144     public login(username: string, password: string): Observable<{}> {
145         this.setHeader();
146         this.setPayLoad(username, password);
147         const apiURLHeader: APIURLHEADER = {
148             url: environment.GENERATETOKEN_URL,
149             httpOptions: { headers: this.httpOptions }
150         };
151         return this.restService.postResource(apiURLHeader, this.payLoad)
152             .pipe(map((data: ProjectModel): BehaviorSubject<boolean> => {
153                 if (data.message === 'change_password') {
154                     sessionStorage.setItem('firstLogin', 'true');
155                     sessionStorage.setItem('id_token', data.id);
156                     sessionStorage.setItem('user_id', data.user_id);
157                     this.idle.watch(true);
158                     this.changePassword.next(true);
159                     this.loggedIn.next(false);
160                     return this.changePassword;
161                 } else {
162                     this.setLocalStorage(data);
163                     this.idle.watch(true);
164                     this.loggedIn.next(true);
165                     this.handle401 = true;
166                     this.userName.next(data.username);
167                     return this.loggedIn;
168                 }
169             }, (error: ERRORDATA): void => { this.restService.handleError(error, 'post'); }
170             ));
171     }
172
173     /** Set headers for auth session @public */
174     public setHeader(): void {
175         this.httpOptions = new HttpHeaders({
176             'Content-Type': 'application/json; charset=UTF-8',
177             Accept: 'application/json',
178             'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0'
179         });
180     }
181
182     /** Set payloads for auth session @public  */
183     public setPayLoad(username: string, password: string): void {
184         this.payLoad = JSON.stringify({
185             username,
186             password
187         });
188     }
189
190     /** set local storage on auth process @public */
191     public setLocalStorage(data: ProjectModel): void {
192         sessionStorage.setItem('id_token', data.id);
193         sessionStorage.setItem('expires', data.expires.toString());
194         sessionStorage.setItem('username', data.username);
195         sessionStorage.setItem('isAdmin', (data.admin) ? 'true' : 'false');
196         sessionStorage.setItem('project_id', data.project_id);
197         sessionStorage.setItem('project', data.project_name);
198         sessionStorage.setItem('token_state', data.id);
199         sessionStorage.setItem('user_id', data.user_id);
200         sessionStorage.setItem('user_show', String(data.user_show));
201         sessionStorage.setItem('admin_show', String(data.admin_show));
202         sessionStorage.setItem('last_login', this.sharedService.convertEpochTime(!isNullOrUndefined(data.last_login) ? data.last_login : null));
203         sessionStorage.setItem('failed_count', data.login_count);
204         this.projectName$.next(data.project_name);
205     }
206     /** Destory tokens API response handling @public */
207     public logoutResponse(): void {
208         this.loggedIn.next(false);
209         this.changePassword.next(false);
210         const langCode: string = sessionStorage.getItem('languageCode');
211         const redirecturl: string = isNullOrUndefined(sessionStorage.getItem('returnUrl')) ? '/' : sessionStorage.getItem('returnUrl');
212         const osmVersion: string = isNullOrUndefined(sessionStorage.getItem('version')) ? '' : sessionStorage.getItem('version');
213         sessionStorage.clear();
214         sessionStorage.setItem('languageCode', langCode);
215         sessionStorage.setItem('returnUrl', redirecturl);
216         sessionStorage.setItem('token_state', null);
217         sessionStorage.setItem('osmVersion', osmVersion);
218         this.idle.stop();
219         this.router.navigate(['login']).catch((): void => {
220             // Catch Navigation Error
221         });
222     }
223     /**
224      * Logout the user & clearing the token.
225      */
226     public logout(): void {
227         this.returnUrl = this.router.url;
228         sessionStorage.setItem('returnUrl', this.returnUrl);
229         this.modalService.dismissAll();
230         this.destoryToken();
231     }
232     /** Destory tokens on logout @public */
233     public destoryToken(): void {
234         const tokenID: string = sessionStorage.getItem('id_token');
235         if (tokenID !== null) {
236             const deletingURl: string = environment.GENERATETOKEN_URL + '/' + tokenID;
237             this.restService.deleteResource(deletingURl).subscribe((res: {}): void => {
238                 this.logoutResponse();
239             }, (error: ERRORDATA): void => {
240                 this.restService.handleError(error, 'delete');
241             });
242         }
243     }
244
245     /** Return to previous page deny access to changepassword */
246     public redirectToPage(): void {
247         if (window.location.pathname === '/changepassword' && sessionStorage.getItem('username') !== null) {
248             window.history.back();
249         } else if (window.location.pathname === '/' && sessionStorage.getItem('firstLogin') === 'true') {
250             this.router.navigate(['/login']).catch((): void => {
251                 // Catch Navigation Error
252             });
253         }
254     }
255 }