@kolbo/app-sdk
Advanced tools
+1
-1
| { | ||
| "name": "@kolbo/app-sdk", | ||
| "version": "2.0.16", | ||
| "version": "2.0.17", | ||
| "description": "Kolbo App Builder SDK — auth, data, storage and AI for generated apps", | ||
@@ -5,0 +5,0 @@ "type": "module", |
@@ -865,4 +865,24 @@ // Kolbo-native adapter. | ||
| if (!stored || !stored.access_token) return { data: { user: null }, error: null }; | ||
| // If still valid, just return the cached user. | ||
| if (!_isExpired(stored, 0)) return { data: { user: stored.user || null }, error: null }; | ||
| // If still valid AND already have a hydrated user object, return it. | ||
| if (!_isExpired(stored, 0) && stored.user) { | ||
| return { data: { user: stored.user }, error: null }; | ||
| } | ||
| // Token is valid but we don't have the user object yet — this is | ||
| // the just-received-OAuth-tokens case. Fetch /me to hydrate the | ||
| // user from the server, and cache it back into the stored session | ||
| // so AuthProvider's next getSession() / getUser() returns it | ||
| // synchronously. Without this, an OAuth popup handoff lands a | ||
| // session with user:null into storage, the consumer's AuthProvider | ||
| // initial mount calls getSession() and caches user:null, and the | ||
| // AuthGuard redirects to /login even though sign-in succeeded. | ||
| if (!_isExpired(stored, 0) && !stored.user) { | ||
| const { data, error } = await self._authFetch('/me', { method: 'GET', accessToken: stored.access_token }); | ||
| if (!error && data) { | ||
| const withUser = { ...stored, user: data }; | ||
| _writeStored(self._storageKey, withUser); | ||
| return { data: { user: data }, error: null }; | ||
| } | ||
| // /me failed — fall through and still return whatever we have. | ||
| return { data: { user: null }, error: null }; | ||
| } | ||
| // Expired — try to refresh silently. | ||
@@ -881,3 +901,17 @@ if (stored.refresh_token) { | ||
| if (!stored || !stored.access_token) return { data: { session: null }, error: null }; | ||
| if (!_isExpired(stored, 0)) return { data: { session: stored }, error: null }; | ||
| if (!_isExpired(stored, 0)) { | ||
| // If the stored session lacks a user (just came out of the | ||
| // OAuth popup handoff), fetch /me and merge. Keeps auth | ||
| // providers that only subscribe to session changes from | ||
| // rendering a null-user signed-in-ish state. | ||
| if (!stored.user) { | ||
| const { data, error } = await self._authFetch('/me', { method: 'GET', accessToken: stored.access_token }); | ||
| if (!error && data) { | ||
| const withUser = { ...stored, user: data }; | ||
| _writeStored(self._storageKey, withUser); | ||
| return { data: { session: withUser }, error: null }; | ||
| } | ||
| } | ||
| return { data: { session: stored }, error: null }; | ||
| } | ||
| if (stored.refresh_token) { | ||
@@ -884,0 +918,0 @@ const refreshed = await self._refreshSession(); |
69216
2.83%1221
2.86%