@delmaredigital/payload-better-auth 0.5.6 → 0.6.0

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.
@@ -1,17 +1,15 @@
1
- import type { AvailableScope } from '../../types/apiKey.js';
1
+ import type { PermissionDefinition } from '../../types/apiKey.js';
2
2
  export type ApiKeysManagementClientProps = {
3
3
  /** Optional pre-configured auth client with apiKey plugin */
4
4
  authClient?: any;
5
5
  /** Page title. Default: 'API Keys' */
6
6
  title?: string;
7
- /** Available scopes for key creation. Auto-generated if not provided. */
8
- availableScopes?: AvailableScope[];
9
- /** Default scopes to pre-select when creating a key */
10
- defaultScopes?: string[];
7
+ /** Available permission definitions (collections + actions). Auto-generated if not provided. */
8
+ permissions?: PermissionDefinition[];
11
9
  };
12
10
  /**
13
11
  * Client component for API keys management.
14
- * Lists, creates, and deletes API keys with scope selection.
12
+ * Lists, creates, and deletes API keys with permission selection (read/write per collection).
15
13
  */
16
- export declare function ApiKeysManagementClient({ authClient: providedClient, title, availableScopes, defaultScopes, }?: ApiKeysManagementClientProps): import("react").JSX.Element;
14
+ export declare function ApiKeysManagementClient({ authClient: providedClient, title, permissions, }?: ApiKeysManagementClientProps): import("react").JSX.Element;
17
15
  export default ApiKeysManagementClient;
@@ -2,59 +2,10 @@
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useState, useEffect, useMemo, useRef } from 'react';
4
4
  import { createAuthClient } from 'better-auth/react';
5
- /**
6
- * Group scopes by collection for the UI.
7
- * Scopes like "posts:read", "posts:write" get grouped under "Posts"
8
- */ function groupScopesByCollection(scopes) {
9
- const groups = new Map();
10
- for (const scope of scopes){
11
- // Parse scope ID like "posts:read" -> collection="posts", type="read"
12
- const colonIndex = scope.id.indexOf(':');
13
- let collection;
14
- let type;
15
- if (colonIndex > 0) {
16
- collection = scope.id.substring(0, colonIndex);
17
- const typeStr = scope.id.substring(colonIndex + 1);
18
- type = [
19
- 'read',
20
- 'write',
21
- 'delete'
22
- ].includes(typeStr) ? typeStr : 'other';
23
- } else {
24
- // No colon - treat as standalone scope
25
- collection = scope.id;
26
- type = 'other';
27
- }
28
- if (!groups.has(collection)) {
29
- // Create label from collection slug (posts -> Posts)
30
- const label = collection.charAt(0).toUpperCase() + collection.slice(1).replace(/-/g, ' ');
31
- groups.set(collection, {
32
- collection,
33
- label,
34
- scopes: []
35
- });
36
- }
37
- groups.get(collection).scopes.push({
38
- type,
39
- scope
40
- });
41
- }
42
- // Sort groups alphabetically, sort scopes within group by type order
43
- const typeOrder = {
44
- read: 0,
45
- write: 1,
46
- delete: 2,
47
- other: 3
48
- };
49
- return Array.from(groups.values()).sort((a, b)=>a.label.localeCompare(b.label)).map((group)=>({
50
- ...group,
51
- scopes: group.scopes.sort((a, b)=>typeOrder[a.type] - typeOrder[b.type])
52
- }));
53
- }
54
5
  /**
55
6
  * Client component for API keys management.
56
- * Lists, creates, and deletes API keys with scope selection.
57
- */ export function ApiKeysManagementClient({ authClient: providedClient, title = 'API Keys', availableScopes = [], defaultScopes = [] } = {}) {
7
+ * Lists, creates, and deletes API keys with permission selection (read/write per collection).
8
+ */ export function ApiKeysManagementClient({ authClient: providedClient, title = 'API Keys', permissions = [] } = {}) {
58
9
  const [apiKeys, setApiKeys] = useState([]);
59
10
  const [loading, setLoading] = useState(true);
60
11
  const [error, setError] = useState(null);
@@ -63,32 +14,10 @@ import { createAuthClient } from 'better-auth/react';
63
14
  const [showCreateForm, setShowCreateForm] = useState(false);
64
15
  const [newKeyName, setNewKeyName] = useState('');
65
16
  const [newKeyExpiry, setNewKeyExpiry] = useState('');
66
- const [selectedScopes, setSelectedScopes] = useState(defaultScopes);
17
+ // Selected permissions: { posts: ['read', 'write'], pages: ['read'] }
18
+ const [selectedPermissions, setSelectedPermissions] = useState({});
67
19
  const [newlyCreatedKey, setNewlyCreatedKey] = useState(null);
68
- const [expandedGroups, setExpandedGroups] = useState(new Set());
69
- const hasScopes = availableScopes.length > 0;
70
- // Group scopes by collection
71
- const scopeGroups = useMemo(()=>groupScopesByCollection(availableScopes), [
72
- availableScopes
73
- ]);
74
- // Get all scope IDs by type for bulk actions
75
- const scopesByType = useMemo(()=>{
76
- const result = {
77
- read: [],
78
- write: [],
79
- delete: []
80
- };
81
- for (const group of scopeGroups){
82
- for (const { type, scope } of group.scopes){
83
- if (type === 'read' || type === 'write' || type === 'delete') {
84
- result[type].push(scope.id);
85
- }
86
- }
87
- }
88
- return result;
89
- }, [
90
- scopeGroups
91
- ]);
20
+ const hasPermissions = permissions.length > 0;
92
21
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
93
22
  const clientRef = useRef(null);
94
23
  const getClient = async ()=>{
@@ -102,100 +31,140 @@ import { createAuthClient } from 'better-auth/react';
102
31
  });
103
32
  return clientRef.current;
104
33
  };
105
- // Toggle a scope selection
106
- function toggleScope(scopeId) {
107
- setSelectedScopes((prev)=>prev.includes(scopeId) ? prev.filter((s)=>s !== scopeId) : [
108
- ...prev,
109
- scopeId
110
- ]);
111
- }
112
- // Toggle all scopes in a group
113
- function toggleGroup(group) {
114
- const groupScopeIds = group.scopes.map((s)=>s.scope.id);
115
- const allSelected = groupScopeIds.every((id)=>selectedScopes.includes(id));
116
- if (allSelected) {
117
- // Deselect all in group
118
- setSelectedScopes((prev)=>prev.filter((id)=>!groupScopeIds.includes(id)));
119
- } else {
120
- // Select all in group
121
- setSelectedScopes((prev)=>[
122
- ...new Set([
34
+ // Toggle a specific action for a collection
35
+ function toggleAction(slug, action) {
36
+ setSelectedPermissions((prev)=>{
37
+ const current = prev[slug] ?? [];
38
+ if (current.includes(action)) {
39
+ // Remove action — if removing 'read' also remove 'write'
40
+ if (action === 'read') {
41
+ const filtered = current.filter((a)=>a !== 'read' && a !== 'write');
42
+ if (filtered.length === 0) {
43
+ const { [slug]: _, ...rest } = prev;
44
+ return rest;
45
+ }
46
+ return {
123
47
  ...prev,
124
- ...groupScopeIds
125
- ])
126
- ]);
127
- }
128
- }
129
- // Toggle expand/collapse for a group
130
- function toggleExpanded(collection) {
131
- setExpandedGroups((prev)=>{
132
- const next = new Set(prev);
133
- if (next.has(collection)) {
134
- next.delete(collection);
48
+ [slug]: filtered
49
+ };
50
+ }
51
+ const filtered = current.filter((a)=>a !== action);
52
+ if (filtered.length === 0) {
53
+ const { [slug]: _, ...rest } = prev;
54
+ return rest;
55
+ }
56
+ return {
57
+ ...prev,
58
+ [slug]: filtered
59
+ };
135
60
  } else {
136
- next.add(collection);
61
+ // Add action — if adding 'write' also add 'read'
62
+ if (action === 'write') {
63
+ return {
64
+ ...prev,
65
+ [slug]: [
66
+ ...new Set([
67
+ ...current,
68
+ 'read',
69
+ 'write'
70
+ ])
71
+ ]
72
+ };
73
+ }
74
+ return {
75
+ ...prev,
76
+ [slug]: [
77
+ ...current,
78
+ action
79
+ ]
80
+ };
137
81
  }
138
- return next;
139
82
  });
140
83
  }
141
- // Bulk toggle all scopes of a type
142
- function toggleAllOfType(type) {
143
- const typeScopes = scopesByType[type];
144
- const allSelected = typeScopes.every((id)=>selectedScopes.includes(id));
145
- if (allSelected) {
146
- setSelectedScopes((prev)=>prev.filter((id)=>!typeScopes.includes(id)));
84
+ // Bulk toggle all of an action type
85
+ function toggleAllOfType(action) {
86
+ const allHave = permissions.every((p)=>(selectedPermissions[p.slug] ?? []).includes(action));
87
+ if (allHave) {
88
+ // Remove this action from all — if removing 'read' also remove 'write'
89
+ setSelectedPermissions((prev)=>{
90
+ const next = {};
91
+ for (const [slug, actions] of Object.entries(prev)){
92
+ const filtered = action === 'read' ? actions.filter((a)=>a !== 'read' && a !== 'write') : actions.filter((a)=>a !== action);
93
+ if (filtered.length > 0) next[slug] = filtered;
94
+ }
95
+ return next;
96
+ });
147
97
  } else {
148
- setSelectedScopes((prev)=>[
149
- ...new Set([
150
- ...prev,
151
- ...typeScopes
152
- ])
153
- ]);
98
+ // Add this action to all — if 'write' also add 'read'
99
+ setSelectedPermissions((prev)=>{
100
+ const next = {
101
+ ...prev
102
+ };
103
+ for (const p of permissions){
104
+ const current = next[p.slug] ?? [];
105
+ if (action === 'write') {
106
+ next[p.slug] = [
107
+ ...new Set([
108
+ ...current,
109
+ 'read',
110
+ 'write'
111
+ ])
112
+ ];
113
+ } else {
114
+ next[p.slug] = [
115
+ ...new Set([
116
+ ...current,
117
+ action
118
+ ])
119
+ ];
120
+ }
121
+ }
122
+ return next;
123
+ });
154
124
  }
155
125
  }
156
- // Check if all scopes of a type are selected
157
- function isAllOfTypeSelected(type) {
158
- return scopesByType[type].length > 0 && scopesByType[type].every((id)=>selectedScopes.includes(id));
126
+ function isAllOfTypeSelected(action) {
127
+ return permissions.length > 0 && permissions.every((p)=>(selectedPermissions[p.slug] ?? []).includes(action));
159
128
  }
160
- // Check if some (but not all) scopes of a type are selected
161
- function isSomeOfTypeSelected(type) {
162
- const typeScopes = scopesByType[type];
163
- const selectedCount = typeScopes.filter((id)=>selectedScopes.includes(id)).length;
164
- return selectedCount > 0 && selectedCount < typeScopes.length;
129
+ function isSomeOfTypeSelected(action) {
130
+ const count = permissions.filter((p)=>(selectedPermissions[p.slug] ?? []).includes(action)).length;
131
+ return count > 0 && count < permissions.length;
165
132
  }
166
- // Clear all selections
167
133
  function clearAll() {
168
- setSelectedScopes([]);
134
+ setSelectedPermissions({});
169
135
  }
170
- // Select all scopes
171
136
  function selectAll() {
172
- setSelectedScopes(availableScopes.map((s)=>s.id));
173
- }
174
- // Get group selection state
175
- function getGroupState(group) {
176
- const groupScopeIds = group.scopes.map((s)=>s.scope.id);
177
- const selectedCount = groupScopeIds.filter((id)=>selectedScopes.includes(id)).length;
178
- if (selectedCount === 0) return 'none';
179
- if (selectedCount === groupScopeIds.length) return 'all';
180
- return 'some';
181
- }
182
- // Get scope label by ID
183
- function getScopeLabel(scopeId) {
184
- const scope = availableScopes.find((s)=>s.id === scopeId);
185
- return scope?.label ?? scopeId;
137
+ const next = {};
138
+ for (const p of permissions){
139
+ next[p.slug] = [
140
+ 'read',
141
+ 'write'
142
+ ];
143
+ }
144
+ setSelectedPermissions(next);
186
145
  }
187
- // Get short label for scope type
188
- function getTypeLabel(type) {
189
- switch(type){
190
- case 'read':
191
- return 'Read';
192
- case 'write':
193
- return 'Write';
194
- case 'delete':
195
- return 'Delete';
196
- default:
197
- return 'Access';
146
+ // Count total selected actions
147
+ const selectedCount = useMemo(()=>{
148
+ let count = 0;
149
+ for (const actions of Object.values(selectedPermissions)){
150
+ count += actions.length;
198
151
  }
152
+ return count;
153
+ }, [
154
+ selectedPermissions
155
+ ]);
156
+ // Format permissions for display
157
+ function formatPermissions(perms) {
158
+ if (!perms) return [];
159
+ const labels = [];
160
+ for (const [slug, actions] of Object.entries(perms)){
161
+ const def = permissions.find((p)=>p.slug === slug);
162
+ const label = def?.label ?? slug;
163
+ for (const action of actions){
164
+ labels.push(`${label}: ${action}`);
165
+ }
166
+ }
167
+ return labels;
199
168
  }
200
169
  useEffect(()=>{
201
170
  fetchApiKeys();
@@ -226,16 +195,15 @@ import { createAuthClient } from 'better-auth/react';
226
195
  setNewlyCreatedKey(null);
227
196
  try {
228
197
  const client = await getClient();
229
- // Send scopes to server - server will convert to permissions
230
198
  const createOptions = {
231
199
  name: newKeyName
232
200
  };
233
201
  if (newKeyExpiry) {
234
- createOptions.expiresIn = parseInt(newKeyExpiry) * 24 * 60 * 60; // Convert days to seconds
202
+ createOptions.expiresIn = parseInt(newKeyExpiry) * 24 * 60 * 60;
235
203
  }
236
- // Add scopes if any are selected - server handles conversion to permissions
237
- if (hasScopes && selectedScopes.length > 0) {
238
- createOptions.scopes = selectedScopes;
204
+ // Send permissions directly in BA's native format
205
+ if (hasPermissions && selectedCount > 0) {
206
+ createOptions.permissions = selectedPermissions;
239
207
  }
240
208
  const result = await client.apiKey.create(createOptions);
241
209
  if (result.error) {
@@ -245,7 +213,7 @@ import { createAuthClient } from 'better-auth/react';
245
213
  setShowCreateForm(false);
246
214
  setNewKeyName('');
247
215
  setNewKeyExpiry('');
248
- setSelectedScopes(defaultScopes); // Reset to defaults
216
+ setSelectedPermissions({});
249
217
  fetchApiKeys();
250
218
  }
251
219
  } catch {
@@ -480,7 +448,7 @@ import { createAuthClient } from 'better-auth/react';
480
448
  })
481
449
  ]
482
450
  }),
483
- hasScopes && /*#__PURE__*/ _jsxs("div", {
451
+ hasPermissions && /*#__PURE__*/ _jsxs("div", {
484
452
  style: {
485
453
  marginBottom: 'var(--base)'
486
454
  },
@@ -514,12 +482,6 @@ import { createAuthClient } from 'better-auth/react';
514
482
  indeterminate: isSomeOfTypeSelected('write'),
515
483
  onClick: ()=>toggleAllOfType('write')
516
484
  }),
517
- /*#__PURE__*/ _jsx(BulkButton, {
518
- label: "All Delete",
519
- active: isAllOfTypeSelected('delete'),
520
- indeterminate: isSomeOfTypeSelected('delete'),
521
- onClick: ()=>toggleAllOfType('delete')
522
- }),
523
485
  /*#__PURE__*/ _jsx("div", {
524
486
  style: {
525
487
  flex: 1
@@ -557,7 +519,7 @@ import { createAuthClient } from 'better-auth/react';
557
519
  })
558
520
  ]
559
521
  }),
560
- /*#__PURE__*/ _jsx("div", {
522
+ /*#__PURE__*/ _jsxs("div", {
561
523
  style: {
562
524
  background: 'var(--theme-input-bg)',
563
525
  border: '1px solid var(--theme-elevation-150)',
@@ -565,113 +527,103 @@ import { createAuthClient } from 'better-auth/react';
565
527
  maxHeight: '400px',
566
528
  overflowY: 'auto'
567
529
  },
568
- children: scopeGroups.map((group)=>{
569
- const groupState = getGroupState(group);
570
- const isExpanded = expandedGroups.has(group.collection);
571
- return /*#__PURE__*/ _jsxs("div", {
530
+ children: [
531
+ /*#__PURE__*/ _jsxs("div", {
572
532
  style: {
573
- borderBottom: '1px solid var(--theme-elevation-100)'
533
+ display: 'grid',
534
+ gridTemplateColumns: '1fr 60px 60px',
535
+ gap: 'calc(var(--base) * 0.5)',
536
+ padding: 'calc(var(--base) * 0.5) calc(var(--base) * 0.75)',
537
+ borderBottom: '1px solid var(--theme-elevation-150)',
538
+ fontSize: '11px',
539
+ fontWeight: 600,
540
+ color: 'var(--theme-elevation-600)',
541
+ textTransform: 'uppercase',
542
+ letterSpacing: '0.5px'
574
543
  },
575
544
  children: [
576
- /*#__PURE__*/ _jsxs("div", {
545
+ /*#__PURE__*/ _jsx("span", {
546
+ children: "Collection"
547
+ }),
548
+ /*#__PURE__*/ _jsx("span", {
577
549
  style: {
578
- display: 'flex',
579
- alignItems: 'center',
580
- gap: 'calc(var(--base) * 0.5)',
581
- padding: 'calc(var(--base) * 0.5) calc(var(--base) * 0.75)',
582
- cursor: 'pointer',
583
- background: groupState !== 'none' ? 'var(--theme-elevation-50)' : 'transparent'
550
+ textAlign: 'center'
584
551
  },
585
- onClick: ()=>toggleExpanded(group.collection),
586
- children: [
587
- /*#__PURE__*/ _jsx("span", {
588
- style: {
589
- color: 'var(--theme-elevation-500)',
590
- fontSize: '10px',
591
- width: '12px',
592
- transition: 'transform 0.15s',
593
- transform: isExpanded ? 'rotate(90deg)' : 'rotate(0deg)'
594
- },
595
- children: "▶"
596
- }),
597
- /*#__PURE__*/ _jsx(IndeterminateCheckbox, {
598
- checked: groupState === 'all',
599
- indeterminate: groupState === 'some',
600
- onChange: (e)=>{
601
- e.stopPropagation();
602
- toggleGroup(group);
603
- }
604
- }),
605
- /*#__PURE__*/ _jsx("span", {
606
- style: {
607
- color: 'var(--theme-text)',
608
- fontSize: 'var(--font-size-small)',
609
- fontWeight: 500,
610
- flex: 1
611
- },
612
- children: group.label
613
- }),
614
- groupState !== 'none' && /*#__PURE__*/ _jsxs("span", {
615
- style: {
616
- padding: '2px 6px',
617
- background: 'var(--theme-elevation-200)',
618
- borderRadius: '10px',
619
- fontSize: '10px',
620
- color: 'var(--theme-elevation-700)'
621
- },
622
- children: [
623
- group.scopes.filter((s)=>selectedScopes.includes(s.scope.id)).length,
624
- "/",
625
- group.scopes.length
626
- ]
627
- })
628
- ]
552
+ children: "Read"
629
553
  }),
630
- isExpanded && /*#__PURE__*/ _jsx("div", {
554
+ /*#__PURE__*/ _jsx("span", {
631
555
  style: {
632
- padding: '0 calc(var(--base) * 0.75) calc(var(--base) * 0.5)',
633
- paddingLeft: 'calc(var(--base) * 2.5)',
634
- display: 'flex',
635
- flexDirection: 'column',
636
- gap: 'calc(var(--base) * 0.25)'
556
+ textAlign: 'center'
637
557
  },
638
- children: group.scopes.map(({ type, scope })=>/*#__PURE__*/ _jsxs("label", {
639
- style: {
640
- display: 'flex',
641
- alignItems: 'center',
642
- gap: 'calc(var(--base) * 0.5)',
643
- cursor: 'pointer',
644
- padding: 'calc(var(--base) * 0.25)',
645
- borderRadius: 'var(--style-radius-s)',
646
- background: selectedScopes.includes(scope.id) ? 'var(--theme-elevation-100)' : 'transparent'
647
- },
648
- children: [
649
- /*#__PURE__*/ _jsx("input", {
650
- type: "checkbox",
651
- checked: selectedScopes.includes(scope.id),
652
- onChange: ()=>toggleScope(scope.id)
653
- }),
654
- /*#__PURE__*/ _jsx("span", {
655
- style: {
656
- color: 'var(--theme-text)',
657
- fontSize: 'var(--font-size-small)'
658
- },
659
- children: getTypeLabel(type)
660
- })
661
- ]
662
- }, scope.id))
558
+ children: "Write"
663
559
  })
664
560
  ]
665
- }, group.collection);
666
- })
561
+ }),
562
+ permissions.map((perm)=>{
563
+ const actions = selectedPermissions[perm.slug] ?? [];
564
+ const hasRead = actions.includes('read');
565
+ const hasWrite = actions.includes('write');
566
+ return /*#__PURE__*/ _jsxs("div", {
567
+ style: {
568
+ display: 'grid',
569
+ gridTemplateColumns: '1fr 60px 60px',
570
+ gap: 'calc(var(--base) * 0.5)',
571
+ padding: 'calc(var(--base) * 0.5) calc(var(--base) * 0.75)',
572
+ borderBottom: '1px solid var(--theme-elevation-100)',
573
+ alignItems: 'center',
574
+ background: hasRead || hasWrite ? 'var(--theme-elevation-50)' : 'transparent'
575
+ },
576
+ children: [
577
+ /*#__PURE__*/ _jsx("span", {
578
+ style: {
579
+ color: 'var(--theme-text)',
580
+ fontSize: 'var(--font-size-small)',
581
+ fontWeight: 500
582
+ },
583
+ children: perm.label
584
+ }),
585
+ /*#__PURE__*/ _jsx("label", {
586
+ style: {
587
+ display: 'flex',
588
+ justifyContent: 'center',
589
+ cursor: 'pointer'
590
+ },
591
+ children: /*#__PURE__*/ _jsx("input", {
592
+ type: "checkbox",
593
+ checked: hasRead,
594
+ onChange: ()=>toggleAction(perm.slug, 'read'),
595
+ style: {
596
+ cursor: 'pointer'
597
+ }
598
+ })
599
+ }),
600
+ /*#__PURE__*/ _jsx("label", {
601
+ style: {
602
+ display: 'flex',
603
+ justifyContent: 'center',
604
+ cursor: 'pointer'
605
+ },
606
+ children: /*#__PURE__*/ _jsx("input", {
607
+ type: "checkbox",
608
+ checked: hasWrite,
609
+ onChange: ()=>toggleAction(perm.slug, 'write'),
610
+ style: {
611
+ cursor: 'pointer'
612
+ }
613
+ })
614
+ })
615
+ ]
616
+ }, perm.slug);
617
+ })
618
+ ]
667
619
  }),
668
620
  /*#__PURE__*/ _jsx("div", {
669
621
  style: {
670
622
  marginTop: 'calc(var(--base) * 0.5)',
671
623
  fontSize: '11px',
672
- color: selectedScopes.length === 0 ? 'var(--theme-warning-500)' : 'var(--theme-elevation-600)'
624
+ color: selectedCount === 0 ? 'var(--theme-warning-500)' : 'var(--theme-elevation-600)'
673
625
  },
674
- children: selectedScopes.length === 0 ? 'No permissions selected. Key will have no access.' : `${selectedScopes.length} permission${selectedScopes.length === 1 ? '' : 's'} selected`
626
+ children: selectedCount === 0 ? 'No permissions selected. Key will have no access.' : `${selectedCount} permission${selectedCount === 1 ? '' : 's'} selected`
675
627
  })
676
628
  ]
677
629
  }),
@@ -793,14 +745,14 @@ import { createAuthClient } from 'better-auth/react';
793
745
  })
794
746
  ]
795
747
  }),
796
- key.metadata?.scopes && key.metadata.scopes.length > 0 && /*#__PURE__*/ _jsx("div", {
748
+ key.permissions && Object.keys(key.permissions).length > 0 && /*#__PURE__*/ _jsx("div", {
797
749
  style: {
798
750
  display: 'flex',
799
751
  flexWrap: 'wrap',
800
752
  gap: 'calc(var(--base) * 0.25)',
801
753
  marginTop: 'calc(var(--base) * 0.5)'
802
754
  },
803
- children: key.metadata.scopes.map((scopeId)=>/*#__PURE__*/ _jsx("span", {
755
+ children: formatPermissions(key.permissions).map((label)=>/*#__PURE__*/ _jsx("span", {
804
756
  style: {
805
757
  padding: '2px 6px',
806
758
  background: 'var(--theme-elevation-100)',
@@ -808,8 +760,8 @@ import { createAuthClient } from 'better-auth/react';
808
760
  fontSize: '11px',
809
761
  color: 'var(--theme-elevation-700)'
810
762
  },
811
- children: getScopeLabel(scopeId)
812
- }, scopeId))
763
+ children: label
764
+ }, label))
813
765
  })
814
766
  ]
815
767
  }),
@@ -854,26 +806,4 @@ import { createAuthClient } from 'better-auth/react';
854
806
  children: label
855
807
  });
856
808
  }
857
- /**
858
- * Checkbox that supports indeterminate state
859
- */ function IndeterminateCheckbox({ checked, indeterminate, onChange }) {
860
- const ref = useRef(null);
861
- useEffect(()=>{
862
- if (ref.current) {
863
- ref.current.indeterminate = indeterminate;
864
- }
865
- }, [
866
- indeterminate
867
- ]);
868
- return /*#__PURE__*/ _jsx("input", {
869
- ref: ref,
870
- type: "checkbox",
871
- checked: checked,
872
- onChange: ()=>{},
873
- onClick: onChange,
874
- style: {
875
- cursor: 'pointer'
876
- }
877
- });
878
- }
879
809
  export default ApiKeysManagementClient;