@makolabs/ripple 1.6.3 → 1.6.5
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.
|
@@ -285,6 +285,7 @@ async function fetchUserPermissions(userId) {
|
|
|
285
285
|
return [];
|
|
286
286
|
}
|
|
287
287
|
catch (error) {
|
|
288
|
+
console.error('[fetchUserPermissions] Error fetching user permissions:', error);
|
|
288
289
|
try {
|
|
289
290
|
const allKeysData = await makeAdminRequest('/admin/keys');
|
|
290
291
|
const userKey = allKeysData.data.data.find((key) => key.sub === userId && key.client_id === CLIENT_ID && key.status === 'active');
|
|
@@ -348,20 +349,47 @@ async function refreshTokenIfSelfUpdate(userId) {
|
|
|
348
349
|
export const updateUserPermissions = command('unchecked', async (options) => {
|
|
349
350
|
const { userId, permissions } = options;
|
|
350
351
|
try {
|
|
351
|
-
// Fetch
|
|
352
|
+
// Fetch user's active keys
|
|
352
353
|
const allKeysData = await makeAdminRequest(`/admin/keys?client_id=${CLIENT_ID}&sub=${userId}`);
|
|
353
|
-
// Find ALL active keys for this user (not just one)
|
|
354
354
|
const userKeys = (allKeysData?.data?.data || []).filter((key) => key.status === 'active');
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
355
|
+
const filteredPermissions = PERMISSION_PREFIX
|
|
356
|
+
? permissions.filter((scope) => scope.startsWith(PERMISSION_PREFIX))
|
|
357
|
+
: permissions;
|
|
358
|
+
if (userKeys.length === 0) {
|
|
359
|
+
// No active key exists, create new one
|
|
360
|
+
const newKeyResult = await createUserPermissions(userId, permissions);
|
|
361
|
+
const newApiKey = newKeyResult?.data?.key;
|
|
362
|
+
if (newApiKey) {
|
|
363
|
+
const currentUser = await makeClerkRequest(`/users/${userId}`);
|
|
364
|
+
await makeClerkRequest(`/users/${userId}`, {
|
|
365
|
+
method: 'PATCH',
|
|
366
|
+
body: JSON.stringify({
|
|
367
|
+
private_metadata: {
|
|
368
|
+
...(currentUser.private_metadata || {}),
|
|
369
|
+
mako_api_key: newApiKey
|
|
370
|
+
}
|
|
371
|
+
})
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
else {
|
|
376
|
+
// Use PUT to update existing key (per Mako Auth API spec)
|
|
377
|
+
const keyId = userKeys[0].id;
|
|
378
|
+
await makeAdminRequest(`/admin/keys/${keyId}`, {
|
|
379
|
+
method: 'PUT',
|
|
380
|
+
body: JSON.stringify({
|
|
381
|
+
scopes: filteredPermissions
|
|
382
|
+
})
|
|
383
|
+
});
|
|
384
|
+
// Clean up any extra keys (there should only be one)
|
|
385
|
+
if (userKeys.length > 1) {
|
|
386
|
+
await Promise.all(userKeys.slice(1).map((key) => makeAdminRequest(`/admin/keys/${key.id}`, {
|
|
387
|
+
method: 'DELETE'
|
|
388
|
+
}).catch((err) => {
|
|
389
|
+
console.warn(`[updateUserPermissions] Failed to delete extra key ${key.id}:`, err);
|
|
390
|
+
})));
|
|
391
|
+
}
|
|
362
392
|
}
|
|
363
|
-
// Create one new key with updated permissions
|
|
364
|
-
await createUserPermissions(userId, permissions);
|
|
365
393
|
await refreshTokenIfSelfUpdate(userId);
|
|
366
394
|
}
|
|
367
395
|
catch (error) {
|
|
@@ -378,30 +406,39 @@ export const generateApiKey = command('unchecked', async (options) => {
|
|
|
378
406
|
if (filteredPermissions.length === 0 && PERMISSION_PREFIX) {
|
|
379
407
|
filteredPermissions = [`${PERMISSION_PREFIX}readonly`];
|
|
380
408
|
}
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
409
|
+
// Check if user has existing active key
|
|
410
|
+
const allKeysData = await makeAdminRequest(`/admin/keys?client_id=${CLIENT_ID}&sub=${options.userId}`);
|
|
411
|
+
const userKeys = (allKeysData?.data?.data || []).filter((key) => key.status === 'active');
|
|
412
|
+
let newApiKey;
|
|
413
|
+
let wasRotated = false;
|
|
414
|
+
if (userKeys.length > 0 && options.revokeOld) {
|
|
415
|
+
// Use rotate endpoint (per Mako Auth API spec)
|
|
416
|
+
const keyId = userKeys[0].id;
|
|
417
|
+
const rotateResult = await makeAdminRequest(`/admin/keys/${keyId}/rotate`, {
|
|
418
|
+
method: 'POST',
|
|
419
|
+
body: JSON.stringify({
|
|
420
|
+
scopes: filteredPermissions
|
|
421
|
+
})
|
|
422
|
+
});
|
|
423
|
+
// Rotate endpoint returns key in data.key field
|
|
424
|
+
newApiKey = rotateResult?.data?.key;
|
|
425
|
+
wasRotated = true;
|
|
426
|
+
if (!newApiKey) {
|
|
427
|
+
throw new Error('Failed to rotate API key - no key in response');
|
|
394
428
|
}
|
|
395
429
|
}
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
430
|
+
else {
|
|
431
|
+
// Create new key if none exists or revokeOld is false
|
|
432
|
+
const createData = await createUserPermissions(options.userId, filteredPermissions);
|
|
433
|
+
if (!createData) {
|
|
434
|
+
throw new Error('Failed to create admin key');
|
|
435
|
+
}
|
|
436
|
+
newApiKey = createData?.data?.key;
|
|
437
|
+
if (!newApiKey) {
|
|
438
|
+
throw new Error('Failed to generate API key - no key in response');
|
|
439
|
+
}
|
|
404
440
|
}
|
|
441
|
+
// Update Clerk profile with new key
|
|
405
442
|
try {
|
|
406
443
|
const currentUser = await makeClerkRequest(`/users/${options.userId}`);
|
|
407
444
|
await makeClerkRequest(`/users/${options.userId}`, {
|
|
@@ -418,22 +455,11 @@ export const generateApiKey = command('unchecked', async (options) => {
|
|
|
418
455
|
console.error('[generateApiKey] Failed to update Clerk profile:', clerkError);
|
|
419
456
|
console.warn('[generateApiKey] Key generated but could not update Clerk profile');
|
|
420
457
|
}
|
|
421
|
-
if (oldKeyId) {
|
|
422
|
-
try {
|
|
423
|
-
await makeAdminRequest(`/admin/keys/${oldKeyId}`, {
|
|
424
|
-
method: 'DELETE'
|
|
425
|
-
});
|
|
426
|
-
}
|
|
427
|
-
catch (revokeError) {
|
|
428
|
-
console.error('[generateApiKey] Failed to revoke old key:', revokeError);
|
|
429
|
-
console.warn('[generateApiKey] New key generated but could not revoke old key');
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
458
|
const result = {
|
|
433
459
|
success: true,
|
|
434
460
|
apiKey: newApiKey,
|
|
435
|
-
message:
|
|
436
|
-
? '
|
|
461
|
+
message: wasRotated
|
|
462
|
+
? 'API key rotated successfully'
|
|
437
463
|
: 'API key generated successfully'
|
|
438
464
|
};
|
|
439
465
|
return JSON.parse(JSON.stringify(result));
|
|
@@ -164,7 +164,7 @@
|
|
|
164
164
|
role: formData.role,
|
|
165
165
|
permissions: formData.permissions
|
|
166
166
|
};
|
|
167
|
-
|
|
167
|
+
|
|
168
168
|
await onSave(userData, mode);
|
|
169
169
|
handleClose();
|
|
170
170
|
} catch (error) {
|
|
@@ -177,7 +177,7 @@
|
|
|
177
177
|
|
|
178
178
|
function handleRoleChange(roleValue: string) {
|
|
179
179
|
const role = roles?.find((r: Role) => r.value === roleValue);
|
|
180
|
-
|
|
180
|
+
|
|
181
181
|
// Reassign entire formData object to ensure Svelte 5 reactivity
|
|
182
182
|
formData = {
|
|
183
183
|
...formData,
|