]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/eg2/src/app/core/store.service.ts
LP2061136 - Stamping 1405 DB upgrade script
[Evergreen.git] / Open-ILS / src / eg2 / src / app / core / store.service.ts
1 /**
2  * Store and retrieve data from various sources.
3  *
4  * Data Types:
5  * 1. LocalItem: Stored in window.localStorage and persist indefinitely.
6  * 2. SessionItem: Stored in window.sessionStorage and persist until
7  *    the end of the current browser tab/window.  Data is only available
8  *    to the tab/window where the data was set.
9  * 3. LoginItem: Stored as session cookies and persist until the browser
10  *    is closed.  These values are avalable to all browser windows/tabs.
11  */
12 import {Injectable} from '@angular/core';
13 import {CookieService} from 'ngx-cookie';
14 import {HatchService} from './hatch.service';
15
16 const WS_ALL_KEY = 'eg.workstation.all';
17 const WS_DEF_KEY = 'eg.workstation.default';
18
19 @Injectable({providedIn: 'root'})
20 export class StoreService {
21
22     // Base path for cookie-based storage.
23     // Useful for limiting cookies to subsections of the application.
24     // Store cookies globally by default.
25     // Note cookies shared with /eg/staff must be stored at "/"
26     loginSessionBasePath = '/';
27
28     // Set of keys whose values should disappear at logout.
29     loginSessionKeys: string[] = [
30         'eg.auth.token',
31         'eg.auth.time',
32         'eg.auth.token.oc',
33         'eg.auth.time.oc'
34     ];
35
36     constructor(
37         private cookieService: CookieService,
38         private hatch: HatchService) {
39     }
40
41     private parseJson(valJson: string): any {
42         if (valJson === undefined || valJson === null || valJson === '') {
43             return null;
44         }
45         try {
46             return JSON.parse(valJson);
47         } catch (E) {
48             console.error(`Failure to parse JSON: ${E} => ${valJson}`);
49             return null;
50         }
51     }
52
53     /**
54      * Add a an app-local login session key
55      */
56     addLoginSessionKey(key: string): void {
57         if (!this.loginSessionKeys.includes(key)) {
58             this.loginSessionKeys.push(key);
59         }
60     }
61
62     setLocalItem(key: string, val: any, isJson?: boolean): void {
63         if (!isJson) {
64             val = JSON.stringify(val);
65         }
66         window.localStorage.setItem(key, val);
67     }
68
69     setSessionItem(key: string, val: any, isJson?: boolean): void {
70         console.log(`Setting session item: key=${key}, value=`, val, `isJson=${isJson}`);
71         if (!isJson) {
72             val = JSON.stringify(val);
73         }
74         window.sessionStorage.setItem(key, val);
75     }
76
77     setLoginSessionItem(key: string, val: any, isJson?: boolean): void {
78         if (!isJson) {
79             val = JSON.stringify(val);
80         }
81         this.cookieService.put(key, val,
82             {path : this.loginSessionBasePath, secure: true});
83     }
84
85     setWorkstations(val: any, isJson?: boolean): Promise<any> {
86         if (this.hatch.isAvailable) {
87             return this.hatch.setItem(WS_ALL_KEY, val).then(
88                 ok => {
89                     // When clearing workstations, remove the default.
90                     if (!val || val.length === 0) {
91                         return this.hatch.removeItem(WS_DEF_KEY);
92                     }
93                 }
94             );
95         } else {
96             return Promise.resolve(
97                 this.setLocalItem(WS_ALL_KEY, val, isJson));
98         }
99     }
100
101     setDefaultWorkstation(val: string, isJson?: boolean): Promise<any> {
102         if (this.hatch.isAvailable) {
103             return this.hatch.setItem(WS_DEF_KEY, val);
104         } else {
105             return Promise.resolve(
106                 this.setLocalItem(WS_DEF_KEY, val, isJson));
107         }
108     }
109
110     getLocalItem(key: string): any {
111         return this.parseJson(window.localStorage.getItem(key));
112     }
113
114     getSessionItem(key: string): any {
115         return this.parseJson(window.sessionStorage.getItem(key));
116     }
117
118     getLoginSessionItem(key: string): any {
119         return this.parseJson(this.cookieService.get(key));
120     }
121
122     getWorkstations(): Promise<any> {
123         if (this.hatch.isAvailable) {
124             return this.mergeWorkstations().then(ok => {
125                 this.removeLocalItem(WS_ALL_KEY);
126                 return this.hatch.getItem(WS_ALL_KEY);
127             });
128         } else {
129             return Promise.resolve(this.getLocalItem(WS_ALL_KEY));
130         }
131     }
132
133     // See if any workstatoins are stored in local storage.  If so, also
134     // see if we have any stored in Hatch.  If both, merged workstations
135     // from localStorage in Hatch storage, skipping any whose name
136     // collide with a workstation in Hatch.  If none exist in Hatch,
137     // copy the localStorage workstations over wholesale.
138     mergeWorkstations(): Promise<any> {
139         const existing = this.getLocalItem(WS_ALL_KEY);
140
141         if (!existing || existing.length === 0) {
142             return Promise.resolve();
143         }
144
145         return this.hatch.getItem(WS_ALL_KEY).then(inHatch => {
146
147             if (!inHatch || inHatch.length === 0) {
148                 // Nothing to merge, copy the data over directly
149                 return this.hatch.setItem('eg.workstation.all', existing);
150             }
151
152             const addMe: any = [];
153             existing.forEach(ws => {
154                 const match = inHatch.filter(w => w.name === ws.name)[0];
155                 if (!match) {
156                     console.log(
157                         'Migrating workstation from local storage to hatch: '
158                         + ws.name
159                     );
160                     addMe.push(ws);
161                 }
162             });
163             inHatch = inHatch.concat(addMe);
164             return this.hatch.setItem(WS_ALL_KEY, inHatch);
165         });
166     }
167
168     getDefaultWorkstation(): Promise<any> {
169         if (this.hatch.isAvailable) {
170             return this.hatch.getItem(WS_DEF_KEY).then(name => {
171                 if (name) {
172                     // We have a default in Hatch, remove any lingering
173                     // value from localStorage.
174                     this.removeLocalItem(WS_DEF_KEY);
175                     return name;
176                 } else {
177                     // Nothing in Hatch, see if we have a localStorage
178                     // value to migrate to Hatch
179                     name = this.getLocalItem(WS_DEF_KEY);
180                     if (name) {
181                         console.debug(
182                             'Migrating default workstation to Hatch ' + name);
183                         return this.hatch.setItem(WS_DEF_KEY, name)
184                             .then(ok => name);
185                     } else {
186                         return null;
187                     }
188                 }
189             });
190         } else {
191             return Promise.resolve(this.getLocalItem(WS_DEF_KEY));
192         }
193     }
194
195     removeLocalItem(key: string): void {
196         window.localStorage.removeItem(key);
197     }
198
199     removeSessionItem(key: string): void {
200         window.sessionStorage.removeItem(key);
201     }
202
203     removeLoginSessionItem(key: string): void {
204         this.cookieService.remove(key, {path : this.loginSessionBasePath});
205     }
206
207     removeDefaultWorkstation(val: string, isJson?: boolean): Promise<any> {
208         if (this.hatch.isAvailable) {
209             return this.hatch.removeItem(WS_DEF_KEY);
210         } else {
211             return Promise.resolve(
212                 this.removeLocalItem(WS_DEF_KEY));
213         }
214     }
215
216
217     clearLoginSessionItems(): void {
218         this.loginSessionKeys.forEach(
219             key => this.removeLoginSessionItem(key)
220         );
221     }
222 }
223