@makolabs/ripple 1.6.6 → 1.6.8

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.
@@ -88,43 +88,56 @@ async function makeAuthRequest(endpoint, options = {}) {
88
88
  ...options.headers
89
89
  }
90
90
  });
91
- const data = await response.json();
92
- // Return both status and data for verification purposes
91
+ const text = await response.text();
92
+ let data;
93
+ try {
94
+ data = JSON.parse(text);
95
+ }
96
+ catch (parseError) {
97
+ // Not JSON, treat as plain text error (e.g., "404 page not found")
98
+ data = { error: text, message: text };
99
+ }
93
100
  return {
94
101
  ok: response.ok,
95
102
  status: response.status,
96
- data: JSON.parse(JSON.stringify(data))
103
+ data: data
97
104
  };
98
105
  }
99
106
  async function verifyApiKeyToken(apiKey) {
100
107
  try {
101
- const result = await makeAuthRequest('/auth/issue', {
108
+ const result = await makeAuthRequest('/auth/token', {
102
109
  method: 'POST',
103
110
  headers: {
104
111
  'X-API-Key': apiKey
105
112
  }
106
113
  });
107
114
  if (result.ok && result.data?.data?.access_token) {
108
- // Parse the JWT to get scopes (or use verify endpoint)
115
+ const token = result.data.data.access_token;
109
116
  const verifyResult = await makeAuthRequest('/auth/verify', {
110
- method: 'POST',
117
+ method: 'GET',
111
118
  headers: {
112
- 'Authorization': `Bearer ${result.data.data.access_token}`
119
+ 'Authorization': `Bearer ${token}`
113
120
  }
114
121
  });
115
122
  if (verifyResult.ok && verifyResult.data?.data) {
123
+ // The API returns "scope" (singular) as a space-separated string, not "scopes" array
124
+ const scopeString = verifyResult.data.data.scope;
125
+ const scopes = scopeString ? scopeString.split(' ').filter(Boolean) : [];
116
126
  return {
117
127
  valid: true,
118
- scopes: verifyResult.data.data.scopes || []
128
+ scopes: scopes
119
129
  };
120
130
  }
121
131
  }
132
+ const errorMsg = result.data?.message || result.data?.error || `API key verification failed with status ${result.status}`;
133
+ console.warn('[verifyApiKeyToken] Verification failed:', errorMsg);
122
134
  return {
123
135
  valid: false,
124
- error: result.data?.error || `API key verification failed with status ${result.status}`
136
+ error: errorMsg
125
137
  };
126
138
  }
127
139
  catch (error) {
140
+ console.error('[verifyApiKeyToken] Exception during verification:', error);
128
141
  return {
129
142
  valid: false,
130
143
  error: error instanceof Error ? error.message : 'Unknown error during verification'
@@ -444,12 +457,12 @@ export const updateUserPermissions = command('unchecked', async (options) => {
444
457
  if (apiKeyString) {
445
458
  try {
446
459
  const verification = await verifyApiKeyToken(apiKeyString);
460
+ console.log('[updateUserPermissions] Key verification:', verification);
447
461
  if (verification.valid) {
448
- console.log('[updateUserPermissions] Token verification successful. Scopes:', verification.scopes);
449
462
  // Check if the scopes match what we expect
450
463
  const scopesMatch = filteredPermissions.every(perm => verification.scopes?.includes(perm));
451
464
  if (!scopesMatch) {
452
- console.warn('[updateUserPermissions] Token scopes do not match expected permissions');
465
+ console.warn('[updateUserPermissions] Scopes mismatch. Expected:', filteredPermissions, 'Got:', verification.scopes);
453
466
  }
454
467
  }
455
468
  else {
@@ -490,12 +503,14 @@ export const generateApiKey = command('unchecked', async (options) => {
490
503
  const userKeys = (allKeysData?.data?.data || []).filter((key) => key.status === 'active');
491
504
  let newApiKey;
492
505
  let wasRotated = false;
506
+ let oldApiKey;
507
+ let currentUser = null;
493
508
  if (userKeys.length > 0 && options.revokeOld) {
494
509
  // Use rotate endpoint (per Mako Auth API spec)
495
510
  const keyId = userKeys[0].id;
496
- // Get the old API key string before rotating
497
- const oldKeyData = await makeAdminRequest(`/admin/keys/${keyId}`);
498
- const oldApiKey = oldKeyData?.data?.key;
511
+ // Get the old API key from Clerk's private_metadata
512
+ currentUser = await makeClerkRequest(`/users/${options.userId}`);
513
+ oldApiKey = currentUser.private_metadata?.mako_api_key;
499
514
  const rotateResult = await makeAdminRequest(`/admin/keys/${keyId}/rotate`, {
500
515
  method: 'POST',
501
516
  body: JSON.stringify({
@@ -512,11 +527,9 @@ export const generateApiKey = command('unchecked', async (options) => {
512
527
  if (oldApiKey) {
513
528
  try {
514
529
  const oldKeyVerification = await verifyApiKeyToken(oldApiKey);
530
+ console.log('[generateApiKey] Old key verification:', oldKeyVerification.valid ? 'Still valid ⚠️' : 'Revoked ✓');
515
531
  if (oldKeyVerification.valid) {
516
- console.warn('[generateApiKey] Old API key is still valid after rotation');
517
- }
518
- else {
519
- console.log('[generateApiKey] Old API key successfully revoked');
532
+ console.warn('[generateApiKey] Old API key still valid after rotation');
520
533
  }
521
534
  }
522
535
  catch (verifyError) {
@@ -526,16 +539,16 @@ export const generateApiKey = command('unchecked', async (options) => {
526
539
  // Verify new key works with correct scopes
527
540
  try {
528
541
  const newKeyVerification = await verifyApiKeyToken(newApiKey);
542
+ console.log('[generateApiKey] New key verification:', newKeyVerification);
529
543
  if (newKeyVerification.valid) {
530
- console.log('[generateApiKey] New API key verification successful. Scopes:', newKeyVerification.scopes);
531
544
  // Check if the scopes match what we expect
532
545
  const scopesMatch = filteredPermissions.every(perm => newKeyVerification.scopes?.includes(perm));
533
546
  if (!scopesMatch) {
534
- console.warn('[generateApiKey] New key scopes do not match expected permissions');
547
+ console.warn('[generateApiKey] Scopes mismatch. Expected:', filteredPermissions, 'Got:', newKeyVerification.scopes);
535
548
  }
536
549
  }
537
550
  else {
538
- console.warn('[generateApiKey] New API key verification failed:', newKeyVerification.error);
551
+ console.warn('[generateApiKey] New key verification failed:', newKeyVerification.error);
539
552
  }
540
553
  }
541
554
  catch (verifyError) {
@@ -555,7 +568,10 @@ export const generateApiKey = command('unchecked', async (options) => {
555
568
  }
556
569
  // Update Clerk profile with new key
557
570
  try {
558
- const currentUser = await makeClerkRequest(`/users/${options.userId}`);
571
+ // Reuse currentUser if already fetched (during rotation), otherwise fetch it
572
+ if (!currentUser) {
573
+ currentUser = await makeClerkRequest(`/users/${options.userId}`);
574
+ }
559
575
  await makeClerkRequest(`/users/${options.userId}`, {
560
576
  method: 'PATCH',
561
577
  body: JSON.stringify({
@@ -589,24 +605,39 @@ export const verifyToken = command('unchecked', async (options) => {
589
605
  const result = await verifyApiKeyToken(options.apiKey);
590
606
  // Also return the issued token for debugging
591
607
  if (result.valid) {
592
- const tokenResult = await makeAuthRequest('/auth/issue', {
593
- method: 'POST',
594
- headers: {
595
- 'X-API-Key': options.apiKey
596
- }
597
- });
598
- return {
599
- ...result,
600
- token: tokenResult.data?.data?.access_token
601
- };
608
+ try {
609
+ const tokenResult = await makeAuthRequest('/auth/token', {
610
+ method: 'POST',
611
+ headers: {
612
+ 'X-API-Key': options.apiKey
613
+ }
614
+ });
615
+ const finalResult = {
616
+ valid: result.valid,
617
+ scopes: result.scopes,
618
+ token: tokenResult.data?.data?.access_token
619
+ };
620
+ // Ensure result is serializable
621
+ return JSON.parse(JSON.stringify(finalResult));
622
+ }
623
+ catch (tokenError) {
624
+ console.warn('[verifyToken] Could not fetch token:', tokenError);
625
+ // Return result without token
626
+ return JSON.parse(JSON.stringify({
627
+ valid: result.valid,
628
+ scopes: result.scopes
629
+ }));
630
+ }
602
631
  }
603
- return result;
632
+ // Ensure result is serializable
633
+ return JSON.parse(JSON.stringify(result));
604
634
  }
605
635
  catch (error) {
606
636
  console.error('[verifyToken] Error:', error);
607
- return {
637
+ const errorResult = {
608
638
  valid: false,
609
639
  error: error instanceof Error ? error.message : 'Unknown error during verification'
610
640
  };
641
+ return JSON.parse(JSON.stringify(errorResult));
611
642
  }
612
643
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@makolabs/ripple",
3
- "version": "1.6.6",
3
+ "version": "1.6.8",
4
4
  "description": "Simple Svelte 5 powered component library ✨",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "repository": {