@@ -3,10 +3,25 @@ import { Injectable } from '@angular/core';
33import { ApiResponse } from '@app/api/model/api-response' ;
44import { environment } from '@environments/environment' ;
55import { BehaviorSubject , Observable } from 'rxjs' ;
6- import { map } from 'rxjs/operators' ;
6+ import { map , tap } from 'rxjs/operators' ;
77import { LoginStatus } from '../model/login-status' ;
88import { User } from '../model/user' ;
99
10+ /**
11+ * Authentication service. Handles login and logout operations.
12+ *
13+ * Login requires sending a request to the login endpoint. While logout just requires cleaning up
14+ * the local context.
15+ *
16+ * ## Remember me
17+ *
18+ * This functionality allows storing the user into the local context, and recovering it automatically.
19+ * All this requires is setting the rememberMe flag to true. The service will take care of the rest.
20+ *
21+ * This is donde just by storing the user into the local context in a successful login. If said
22+ * login was successful. The service will always try to read a user from the local context when it
23+ * starts. Also any user in the local context will be removed on a logout.
24+ */
1025@Injectable ( {
1126 providedIn : 'root' ,
1227} )
@@ -29,29 +44,66 @@ export class AuthenticationService {
2944 this . user = this . userSubject . asObservable ( ) ;
3045 }
3146
47+ /**
48+ * Logs in a user. This requires sending a login request. If the request fails it returns an
49+ * empty user, otherwise it returns the user.
50+ *
51+ * If the 'remember me' option is active, the user will be stored in the local storage.
52+ *
53+ * @param username username for login
54+ * @param password password for login
55+ * @returns the user resulting from the login
56+ */
3257 public login ( username : string , password : string ) : Observable < User > {
3358 return this . http . post < ApiResponse < LoginStatus > > ( this . loginUrl , { username, password } )
3459 . pipe ( map ( response => response . content ) )
35- . pipe ( map ( r => this . loadUser ( r ) ) ) ;
60+ . pipe ( map ( response => this . toUser ( response ) ) )
61+ . pipe ( tap ( user => this . storeUser ( user ) ) ) ;
3662 }
3763
64+ /**
65+ * Logs out the current user.
66+ */
3867 public logout ( ) {
68+ // Store empty user
3969 this . userSubject . next ( new User ( ) ) ;
70+
71+ // Clear local storage
4072 localStorage . removeItem ( this . userKey ) ;
4173 }
4274
75+ /**
76+ * Returns the user currently in session.
77+ * @returns the user currently in session
78+ */
4379 public getUser ( ) : User {
4480 return this . userSubject . value ;
4581 }
4682
83+ /**
84+ * Returns the user currently in session as an observable. This allows reacting to new logins or logouts.
85+ *
86+ * @returns the user currently in session as an observable
87+ */
4788 public getUserObservable ( ) : Observable < User > {
4889 return this . user ;
4990 }
5091
92+ /**
93+ * Sets the status of the remember me option. If active the user will be stored on a succesful login.
94+ *
95+ * @param remember remember me flag
96+ */
5197 public setRememberMe ( remember : boolean ) {
5298 this . rememberMe = remember ;
5399 }
54100
101+ /**
102+ * Reads the user from the local storage. This allows recovering users stored as part of the 'remember me'
103+ * functionality.
104+ *
105+ * @returns the user stored in the local storage as part of the 'remember me'
106+ */
55107 private readUserFromLocal ( ) : BehaviorSubject < User > {
56108 let subject : BehaviorSubject < User > ;
57109
@@ -70,7 +122,13 @@ export class AuthenticationService {
70122 return subject ;
71123 }
72124
73- private loadUser ( status : LoginStatus ) : User {
125+ /**
126+ * Maps the login status into a user.
127+ *
128+ * @param status status to map
129+ * @returns user generated from the login status
130+ */
131+ private toUser ( status : LoginStatus ) : User {
74132 let loggedUser ;
75133
76134 loggedUser = new User ( ) ;
@@ -79,15 +137,24 @@ export class AuthenticationService {
79137 loggedUser . username = status . username ;
80138 loggedUser . logged = status . logged ;
81139 loggedUser . token = status . token ;
82-
83- if ( this . rememberMe ) {
84- // Store user
85- localStorage . setItem ( this . userKey , JSON . stringify ( loggedUser ) ) ;
86- }
87140 }
88141
89- this . userSubject . next ( loggedUser ) ;
90- return this . getUser ( ) ;
142+ return loggedUser ;
143+ }
144+
145+ /**
146+ * Stores the received user. This takes two steps, first it is stored in the local subject. Then, if
147+ * the 'remember me' option is enabled, it will be stored in the local storage.
148+ *
149+ * @param user user to store
150+ */
151+ private storeUser ( user : User ) {
152+ this . userSubject . next ( user ) ;
153+
154+ if ( this . rememberMe ) {
155+ // Store user
156+ localStorage . setItem ( this . userKey , JSON . stringify ( user ) ) ;
157+ }
91158 }
92159
93160}
0 commit comments