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