@unifiedmemory/cli 1.3.10 → 1.3.11

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/commands/login.js CHANGED
@@ -222,6 +222,7 @@ export async function login() {
222
222
  );
223
223
 
224
224
  // Update saved token with org-scoped version
225
+ // Preserve originalSid for recovery purposes (org-scoped token won't have sid)
225
226
  saveToken({
226
227
  accessToken: tokenData.access_token,
227
228
  idToken: orgToken.jwt,
@@ -230,7 +231,8 @@ export async function login() {
230
231
  expiresIn: tokenData.expires_in,
231
232
  receivedAt: Date.now(),
232
233
  decoded: parseJWT(orgToken.jwt),
233
- selectedOrg: selectedOrg
234
+ selectedOrg: selectedOrg,
235
+ originalSid: decoded.sid // Preserve session ID from original OAuth token
234
236
  });
235
237
 
236
238
  console.log(chalk.green(`\n✅ Using organization context: ${chalk.bold(selectedOrg.name)}`));
@@ -2,6 +2,7 @@ import { getToken, saveToken } from './token-storage.js';
2
2
  import { isTokenExpired, refreshAccessToken } from './token-refresh.js';
3
3
  import { getOrgScopedToken } from './clerk-api.js';
4
4
  import { parseJWT } from './jwt-utils.js';
5
+ import { config } from './config.js';
5
6
 
6
7
  /**
7
8
  * Load token and refresh if expired
@@ -47,28 +48,82 @@ export async function loadAndRefreshToken(requireAuth = true) {
47
48
 
48
49
  // Check if token has org context but lacks org claims in JWT
49
50
  // This can happen if getOrgScopedToken() failed during login
50
- if (tokenData.selectedOrg?.id && tokenData.decoded?.sid && !tokenData.decoded?.o) {
51
+ if (tokenData.selectedOrg?.id && !tokenData.decoded?.o) {
51
52
  console.error('⚠️ Token missing org claims, attempting to fix...');
52
- try {
53
- const orgToken = await getOrgScopedToken(
54
- tokenData.decoded.sid,
55
- tokenData.selectedOrg.id,
56
- tokenData.idToken || tokenData.accessToken
57
- );
58
53
 
59
- const decoded = parseJWT(orgToken.jwt);
60
- const updatedToken = {
61
- ...tokenData,
62
- idToken: orgToken.jwt,
63
- decoded: decoded,
64
- };
65
-
66
- saveToken(updatedToken);
67
- console.error('✓ Token updated with org claims');
68
- return updatedToken;
69
- } catch (error) {
70
- console.error(`⚠️ Could not get org-scoped token: ${error.message}`);
71
- // Continue with existing token - API calls may fail
54
+ // Check for sid in decoded token or preserved originalSid from login
55
+ let sessionId = tokenData.decoded?.sid || tokenData.originalSid;
56
+ let currentToken = tokenData.idToken || tokenData.accessToken;
57
+
58
+ // If no sid, try to refresh first to get a new base token with sid
59
+ if (!sessionId && tokenData.refresh_token) {
60
+ console.error(' Refreshing to obtain session ID...');
61
+ try {
62
+ const tokenParams = {
63
+ client_id: config.clerkClientId,
64
+ refresh_token: tokenData.refresh_token,
65
+ grant_type: 'refresh_token',
66
+ };
67
+
68
+ if (config.clerkClientSecret) {
69
+ tokenParams.client_secret = config.clerkClientSecret;
70
+ }
71
+
72
+ const response = await fetch(`https://${config.clerkDomain}/oauth/token`, {
73
+ method: 'POST',
74
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
75
+ body: new URLSearchParams(tokenParams),
76
+ });
77
+
78
+ if (response.ok) {
79
+ const newTokenData = await response.json();
80
+ const refreshedToken = newTokenData.id_token || newTokenData.access_token;
81
+ const refreshedDecoded = parseJWT(refreshedToken);
82
+
83
+ sessionId = refreshedDecoded?.sid;
84
+ currentToken = refreshedToken;
85
+
86
+ // Update tokenData with refreshed values
87
+ tokenData.accessToken = newTokenData.access_token;
88
+ tokenData.idToken = newTokenData.id_token;
89
+ tokenData.refresh_token = newTokenData.refresh_token || tokenData.refresh_token;
90
+ tokenData.decoded = refreshedDecoded;
91
+
92
+ if (sessionId) {
93
+ console.error(' ✓ Obtained session ID');
94
+ }
95
+ }
96
+ } catch (error) {
97
+ console.error(` Could not refresh token: ${error.message}`);
98
+ }
99
+ }
100
+
101
+ // Now try to get org-scoped token if we have sessionId
102
+ if (sessionId) {
103
+ try {
104
+ const orgToken = await getOrgScopedToken(
105
+ sessionId,
106
+ tokenData.selectedOrg.id,
107
+ currentToken
108
+ );
109
+
110
+ const decoded = parseJWT(orgToken.jwt);
111
+ const updatedToken = {
112
+ ...tokenData,
113
+ idToken: orgToken.jwt,
114
+ decoded: decoded,
115
+ };
116
+
117
+ saveToken(updatedToken);
118
+ console.error('✓ Token updated with org claims');
119
+ return updatedToken;
120
+ } catch (error) {
121
+ console.error(`⚠️ Could not get org-scoped token: ${error.message}`);
122
+ // Continue with existing token - API calls may fail
123
+ }
124
+ } else {
125
+ console.error('⚠️ Could not obtain session ID for org-scoped token');
126
+ console.error(' Please run: um login');
72
127
  }
73
128
  }
74
129
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unifiedmemory/cli",
3
- "version": "1.3.10",
3
+ "version": "1.3.11",
4
4
  "description": "UnifiedMemory CLI - AI code assistant integration",
5
5
  "main": "index.js",
6
6
  "type": "module",