1- // @flow weak
1+ // @flow
2+
3+ import type {
4+ Storage ,
5+ TokenKey ,
6+ UserInfoKey ,
7+ STORES_TYPES
8+ } from './type' ;
9+ import decode from 'jwt-decode' ;
10+ import moment from 'moment' ;
11+
212
313const TOKEN_KEY = 'token' ;
414const USER_INFO = 'userInfo' ;
515
6- const APP_PERSIST_STORES_TYPES = [ 'localStorage' , 'sessionStorage' ] ;
16+ const APP_PERSIST_STORES_TYPES : Array < STORES_TYPES > = [
17+ 'localStorage',
18+ 'sessionStorage'
19+ ];
720
8- const parse = JSON . parse ;
21+ const parse = JSON.parse;
922const stringify = JSON.stringify;
23+
1024/*
1125 auth object
1226 -> store "TOKEN_KEY"
1327 - default storage is "localStorage"
1428 - default token key is 'token'
1529 * /
1630export const auth = {
17- // -------------------------
18- // token
19- // -------------------------
20- getToken ( fromStorage = APP_PERSIST_STORES_TYPES [ 0 ] , tokenKey = TOKEN_KEY ) {
31+ // /////////////////////////////////////////////////////////////
32+ // TOKEN
33+ // /////////////////////////////////////////////////////////////
34+
35+ /**
36+ * get token from localstorage
37+ *
38+ * @param {'localStorage' | 'sessionStorage' } [fromStorage='localStorage'] specify storage
39+ * @param {any } [tokenKey=TOKEN_KEY] optionnal parameter to specify a token key
40+ * @returns {string } token value
41+ */
42+ getToken (
43+ fromStorage : Storage = APP_PERSIST_STORES_TYPES [ 0 ] ,
44+ tokenKey : TokenKey = TOKEN_KEY
45+ ) : ?string {
2146 // localStorage:
2247 if ( fromStorage === APP_PERSIST_STORES_TYPES [ 0 ] ) {
2348 return ( localStorage && localStorage . getItem ( tokenKey ) ) || null ;
@@ -30,7 +55,19 @@ export const auth = {
3055 return null ;
3156 } ,
3257
33- setToken ( value = '' , toStorage = APP_PERSIST_STORES_TYPES [ 0 ] , tokenKey = TOKEN_KEY ) {
58+ /**
59+ * set the token value into localstorage (managed by localforage)
60+ *
61+ * @param {string } [value=''] token value
62+ * @param {'localStorage' | 'sessionStorage' } [toStorage='localStorage'] specify storage
63+ * @param {any } [tokenKey='token'] token key
64+ * @returns {boolean } success/failure flag
65+ */
66+ setToken (
67+ value : string = '' ,
68+ toStorage : Storage = APP_PERSIST_STORES_TYPES [ 0 ] ,
69+ tokenKey : TokenKey = TOKEN_KEY
70+ ) : ?string {
3471 if ( ! value || value . length <= 0 ) {
3572 return ;
3673 }
@@ -47,19 +84,33 @@ export const auth = {
4784 }
4885 }
4986 } ,
50- /*
51- Note: 'isAuthenticated' just checks 'tokenKey' on store (localStorage by default or sessionStorage)
5287
53- You may think: 'ok I just put an empty token key and I have access to protected routes?''
54- -> answer is: YES^^
55- BUT
56- -> : your backend will not recognize a wrong token so private data or safe and you protected view could be a bit ugly without any data.
5788
58- => ON CONCLUSION: this aim of 'isAuthenticated'
59- -> is to help for a better "user experience" (= better than displaying a view with no data since server did not accept the user).
60- -> it is not a security purpose (security comes from backend, since frontend is easily hackable => user has access to all your frontend)
89+ /**
90+ * check
91+ * - if token key contains a valid token value (defined and not an empty value)
92+ * - if the token expiration date is passed
93+ *
94+ *
95+ * Note: 'isAuthenticated' just checks 'tokenKey' on store (localStorage by default or sessionStorage)
96+ *
97+ * You may think: 'ok I just put an empty token key and I have access to protected routes?''
98+ * -> answer is: YES^^
99+ * BUT
100+ * -> : your backend will not recognize a wrong token so private data or safe and you protected view could be a bit ugly without any data.
101+ *
102+ * => ON CONCLUSION: this aim of 'isAuthenticated'
103+ * -> is to help for a better "user experience" (= better than displaying a view with no data since server did not accept the user).
104+ * -> it is not a security purpose (security comes from backend, since frontend is easily hackable => user has access to all your frontend)
105+ *
106+ * @param {'localStorage' | 'sessionStorage' } [fromStorage='localStorage'] specify storage
107+ * @param {any } [tokenKey=TOKEN_KEY] token key
108+ * @returns {bool } is authenticed response
61109 */
62- isAuthenticated ( fromStorage = APP_PERSIST_STORES_TYPES [ 0 ] , tokenKey = TOKEN_KEY ) {
110+ isAuthenticated (
111+ fromStorage : Storage = APP_PERSIST_STORES_TYPES [ 0 ] ,
112+ tokenKey : TokenKey = TOKEN_KEY
113+ ) : boolean {
63114 // localStorage:
64115 if ( fromStorage === APP_PERSIST_STORES_TYPES [ 0 ] ) {
65116 if ( ( localStorage && localStorage . getItem ( tokenKey ) ) ) {
@@ -80,22 +131,82 @@ export const auth = {
80131 return false ;
81132 } ,
82133
83- clearToken ( tokenKey = TOKEN_KEY ) {
134+ /**
135+ * delete token
136+ *
137+ * @param {any } [tokenKey='token'] token key
138+ * @returns {bool } success/failure flag
139+ */
140+ clearToken (
141+ storage : Storage = APP_PERSIST_STORES_TYPES [ 0 ] ,
142+ tokenKey : TokenKey = TOKEN_KEY
143+ ) : boolean {
84144 // localStorage:
85145 if ( localStorage && localStorage [ tokenKey ] ) {
86146 localStorage . removeItem ( tokenKey ) ;
147+ return true ;
87148 }
88149 // sessionStorage:
89150 if ( sessionStorage && sessionStorage [ tokenKey ] ) {
90151 sessionStorage . removeItem ( tokenKey ) ;
152+ return true ;
91153 }
154+
155+ return false ;
92156 } ,
93157
158+ /**
159+ * return expiration date from token
160+ *
161+ * @param {string } encodedToken - base 64 token received from server and stored in local storage
162+ * @returns {date | null } returns expiration date or null id expired props not found in decoded token
163+ */
164+ getTokenExpirationDate (
165+ encodedToken : any
166+ ) : Date {
167+ if ( ! encodedToken ) {
168+ return new Date ( 0 ) ; // is expired
169+ }
94170
95- // -------------------------
171+ const token = decode ( encodedToken ) ;
172+ if ( ! token . exp ) {
173+ return new Date ( 0 ) ; // is expired
174+ }
175+ const expirationDate = new Date ( token . exp * 1000 ) ;
176+ return expirationDate ;
177+ } ,
178+
179+ /**
180+ * tell is token is expired (compared to now)
181+ *
182+ * @param {string } encodedToken - base 64 token received from server and stored in local storage
183+ * @returns {bool } returns true if expired else false
184+ */
185+ isExpiredToken (
186+ encodedToken : any
187+ ) : boolean {
188+ const expirationDate = this . getTokenExpirationDate ( encodedToken ) ;
189+ const rightNow = moment ( ) ;
190+ const isExpiredToken = moment ( rightNow ) . isAfter ( moment ( expirationDate ) ) ;
191+
192+ return isExpiredToken ;
193+ } ,
194+
195+
196+ // /////////////////////////////////////////////////////////////
96197 // USER_INFO
97- // -------------------------
98- getUserInfo ( fromStorage = APP_PERSIST_STORES_TYPES [ 0 ] , userInfoKey = USER_INFO ) {
198+ // /////////////////////////////////////////////////////////////
199+ /**
200+ * get user info from localstorage
201+ *
202+ * @param {'localStorage' | 'sessionStorage' } [fromStorage='localStorage'] specify storage
203+ * @param {any } [userInfoKey='userInfo'] optionnal parameter to specify a token key
204+ * @returns {string } token value
205+ */
206+ getUserInfo (
207+ fromStorage : Storage = APP_PERSIST_STORES_TYPES [ 0 ] ,
208+ userInfoKey : UserInfoKey = USER_INFO
209+ ) : ?string {
99210 // localStorage:
100211 if ( fromStorage === APP_PERSIST_STORES_TYPES [ 0 ] ) {
101212 return ( localStorage && parse ( localStorage . getItem ( userInfoKey ) ) ) || null ;
@@ -108,7 +219,19 @@ export const auth = {
108219 return null ;
109220 } ,
110221
111- setUserInfo ( value = '' , toStorage = APP_PERSIST_STORES_TYPES [ 0 ] , userInfoKey = USER_INFO ) {
222+ /**
223+ * set the userInfo value into localstorage
224+ *
225+ * @param {object } [value=''] token value
226+ * @param {'localStorage' | 'sessionStorage' } [toStorage='localStorage'] specify storage
227+ * @param {any } [userInfoKey='userInfo'] token key
228+ * @returns {boolean } success/failure flag
229+ */
230+ setUserInfo (
231+ value : string = '' ,
232+ toStorage :Storage = APP_PERSIST_STORES_TYPES [ 0 ] ,
233+ userInfoKey :UserInfoKey = USER_INFO
234+ ) : any {
112235 if ( ! value || value . length <= 0 ) {
113236 return ;
114237 }
@@ -126,7 +249,15 @@ export const auth = {
126249 }
127250 } ,
128251
129- clearUserInfo ( userInfoKey = USER_INFO ) {
252+ /**
253+ * delete userInfo
254+ *
255+ * @param {string } [userInfoKey='userInfo'] token key
256+ * @returns {bool } success/failure flag
257+ */
258+ clearUserInfo (
259+ userInfoKey : UserInfoKey = USER_INFO
260+ ) : any {
130261 // localStorage:
131262 if ( localStorage && localStorage [ userInfoKey ] ) {
132263 localStorage . removeItem ( userInfoKey ) ;
@@ -138,10 +269,15 @@ export const auth = {
138269 } ,
139270
140271
141- // ---------------------------
142- // common
143- // ---------------------------
144- clearAllAppStorage ( ) {
272+ // /////////////////////////////////////////////////////////////
273+ // COMMON
274+ // /////////////////////////////////////////////////////////////
275+
276+ /**
277+ * forget me method: clear all
278+ * @returns {bool } success/failure flag
279+ */
280+ clearAllAppStorage ( ) : any {
145281 if ( localStorage ) {
146282 localStorage . clear ( ) ;
147283 }
0 commit comments