roboto-js 1.7.0 → 1.7.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/esm/index.js CHANGED
@@ -2,20 +2,22 @@ import RbtApi from './rbt_api.js';
2
2
  import RbtObject from './rbt_object.js';
3
3
  import RbtFile from './rbt_file.js';
4
4
  import RbtMetricsApi from './rbt_metrics_api.js';
5
- export { RbtApi, RbtObject, RbtFile
5
+ import CookieStorageAdaptor from './cookie_storage_adaptor.js';
6
+ export { RbtApi, RbtObject, RbtFile, CookieStorageAdaptor
6
7
  //User,
7
8
  //Site
8
9
  };
9
10
  export default class Roboto {
10
11
  getVersion() {
11
- return '1.6.17';
12
+ return '1.7.3';
12
13
  }
13
14
  constructor({
14
15
  host,
15
16
  accessKey,
16
17
  localStorageAdaptor,
17
18
  disableWebSocket = false,
18
- metricsHost
19
+ metricsHost,
20
+ useCookies = true
19
21
  }, proxyReq = null) {
20
22
  if (Roboto.instance && !proxyReq) {
21
23
  // if on client, there can only be one instance
@@ -24,12 +26,29 @@ export default class Roboto {
24
26
  }
25
27
  const isBrowser = typeof window !== "undefined";
26
28
  this.data = {};
29
+
30
+ // Auto-configure storage adaptor
31
+ let storageAdaptor = localStorageAdaptor;
32
+ if (!storageAdaptor && isBrowser && useCookies) {
33
+ // Use cookies by default in browser for better server-side compatibility
34
+ storageAdaptor = new CookieStorageAdaptor({
35
+ secure: window.location.protocol === 'https:',
36
+ sameSite: 'Lax',
37
+ maxAge: 24 * 60 * 60 // 24 hours
38
+ });
39
+ console.log('[Roboto] Using CookieStorageAdaptor for authentication tokens');
40
+
41
+ // Set accessKey for server-side authentication (handled automatically by adapter)
42
+ if (accessKey) {
43
+ storageAdaptor.setItem('accessKey', accessKey).catch(e => console.warn('[Roboto] Failed to set accessKey cookie:', e));
44
+ }
45
+ }
27
46
  this.config = {
28
47
  accessKey: accessKey,
29
48
  // Use passed accessKey
30
49
  baseUrl: `https://${host}`,
31
50
  // Use passed host
32
- localStorageAdaptor: localStorageAdaptor
51
+ localStorageAdaptor: storageAdaptor
33
52
  };
34
53
 
35
54
  // DEVELOPMENT
@@ -54,6 +73,12 @@ export default class Roboto {
54
73
  this.api = new RbtApi(this.config);
55
74
  if (isBrowser) {
56
75
  this.api.initLocalDb();
76
+
77
+ // Add global debug method for cookie storage adapter
78
+ if (this.config.localStorageAdaptor && this.config.localStorageAdaptor.debugState) {
79
+ window.debugRobotoCookies = () => this.config.localStorageAdaptor.debugState();
80
+ console.log('[Roboto] Added global debug method: window.debugRobotoCookies()');
81
+ }
57
82
  }
58
83
 
59
84
  // METRICS API instance (separate host or same)
@@ -130,7 +155,14 @@ export default class Roboto {
130
155
  return this.api.loginWithOauth(params);
131
156
  }
132
157
  async logout() {
133
- return this.api.logout();
158
+ const result = await this.api.logout();
159
+
160
+ // Clear accessKey and authtoken using standard localStorage interface
161
+ if (this.config.localStorageAdaptor) {
162
+ await this.config.localStorageAdaptor.removeItem('accessKey');
163
+ await this.config.localStorageAdaptor.removeItem('authtoken');
164
+ }
165
+ return result;
134
166
  }
135
167
  async refreshAuthToken() {
136
168
  return this.api.refreshAuthToken(this.config.authtoken);
@@ -42,28 +42,9 @@ export default class RbtApi {
42
42
  };
43
43
  }
44
44
 
45
- // Synchronous browser hydration: set auth header and in-memory user immediately
46
- if (typeof localStorage !== 'undefined') {
47
- try {
48
- const token = localStorage.getItem('authtoken');
49
- if (token) {
50
- this.authtoken = token;
51
- this.axios.defaults.headers.common['authtoken'] = token;
52
- }
53
- } catch {}
54
- try {
55
- const cachedUser = localStorage.getItem('rbtUser');
56
- if (cachedUser) {
57
- const parsed = JSON.parse(cachedUser);
58
- if (parsed && parsed.id) {
59
- this.currentUser = new RbtUser({
60
- id: parsed.id
61
- }, this.axios);
62
- this.currentUser.setData(parsed);
63
- }
64
- }
65
- } catch {}
66
- }
45
+ // Asynchronous browser hydration: set auth header and in-memory user
46
+ // Use storage adaptor if available, otherwise fallback to localStorage
47
+ this._initializeFromStorage().catch(e => console.warn('[RbtApi] Storage initialization failed:', e));
67
48
  this.localDb = null;
68
49
  this.iac_session = null;
69
50
  this.appServiceHost = baseUrl;
@@ -75,6 +56,51 @@ export default class RbtApi {
75
56
  this.initAuthToken(authtoken);
76
57
  this.initApiKey(apikey);
77
58
  }
59
+
60
+ // Initialize authtoken and user from storage (cookies or localStorage)
61
+ async _initializeFromStorage() {
62
+ if (!this.localStorageAdaptor) return;
63
+ try {
64
+ // Try to get authtoken from storage adaptor (prefixed: rbt_authtoken)
65
+ let token = await this.localStorageAdaptor.getItem('authtoken');
66
+
67
+ // If not found in prefixed storage, try raw cookie (like accessKey)
68
+ if (!token && typeof document !== 'undefined') {
69
+ // Try to get from raw cookie
70
+ const cookies = document.cookie.split(';');
71
+ for (let cookie of cookies) {
72
+ const [name, value] = cookie.trim().split('=');
73
+ if (name === 'authtoken') {
74
+ token = decodeURIComponent(value);
75
+ break;
76
+ }
77
+ }
78
+ }
79
+ if (token) {
80
+ this.authtoken = token;
81
+ this.axios.defaults.headers.common['authtoken'] = token;
82
+ console.log('[RbtApi] Loaded authtoken from storage adaptor');
83
+ }
84
+ } catch (e) {
85
+ console.warn('[RbtApi] Failed to load authtoken from storage adaptor:', e);
86
+ }
87
+ try {
88
+ // Try to get user from storage adaptor
89
+ const cachedUser = await this.localStorageAdaptor.getItem('rbtUser');
90
+ if (cachedUser) {
91
+ const parsed = typeof cachedUser === 'string' ? JSON.parse(cachedUser) : cachedUser;
92
+ if (parsed && parsed.id) {
93
+ this.currentUser = new RbtUser({
94
+ id: parsed.id
95
+ }, this.axios);
96
+ this.currentUser.setData(parsed);
97
+ console.log('[RbtApi] Loaded user from storage adaptor');
98
+ }
99
+ }
100
+ } catch (e) {
101
+ console.warn('[RbtApi] Failed to load user from storage adaptor:', e);
102
+ }
103
+ }
78
104
  getWebSocketClient() {
79
105
  // Reuse existing WebSocket if it's OPEN or CONNECTING (to prevent race condition)
80
106
  if (this.websocketClient && (this.websocketClient.readyState === WebSocket.OPEN || this.websocketClient.readyState === WebSocket.CONNECTING)) {
@@ -242,6 +268,8 @@ export default class RbtApi {
242
268
  if (this.iac_session?.user) {
243
269
  await this.localStorageAdaptor.setItem('rbtUser', JSON.stringify(this.iac_session.user));
244
270
  }
271
+
272
+ // authtoken is automatically stored for server-side access by the adapter
245
273
  }
246
274
  return response.data;
247
275
  } catch (e) {