Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | 5x 46x 46x 46x 46x 46x 15x 1x 14x 14x 14x 13x 13x 13x 14x 14x 14x 1x 14x 6x 6x 6x 6x 5x 1x 6x 6x 1x 1x 1x 1x 7x 1x 2x 1x 1x 1x 1x 1x 2x 1x 1x 1x 1x 46x | import { defineStore } from 'pinia'
import { ref } from 'vue'
import api from '@/services/api'
export interface ApiKey {
id: string
tenantId: string
name: string
keyHash: string
permissions: string[]
allowedEntityIds: string[]
expiresAt?: string
status: 'active' | 'expired' | 'revoked'
createdBy: string
createdAt: string
revokedAt?: string
revokedBy?: string
lastUsedAt?: string
}
export interface CreateApiKeyRequest {
name: string
permissions: string[]
allowedEntityIds: string[]
expiresAt?: string
}
export interface CreateApiKeyResponse {
apiKey: ApiKey // The API key object
key: string // The plain key (only returned once!)
message?: string
warning?: string
}
export const useApiKeysStore = defineStore('apiKeys', () => {
const apiKeys = ref<ApiKey[]>([])
const loading = ref(false)
const error = ref<string | null>(null)
const nextToken = ref<string | null>(null)
const hasMore = ref(false)
async function fetchApiKeys(reset = true) {
if (loading.value || (!reset && !hasMore.value)) {
return
}
loading.value = true
error.value = null
if (reset) {
apiKeys.value = []
nextToken.value = null
hasMore.value = true
}
try {
const params: any = { limit: 30 }
if (!reset && nextToken.value) {
params.nextToken = nextToken.value
}
const response = await api.get('/v1/admin/api-keys', { params })
const data = response.data
// Handle different response formats
Iif (Array.isArray(data)) {
// Direct array response
if (reset) {
apiKeys.value = data
} else {
apiKeys.value = [...apiKeys.value, ...data]
}
hasMore.value = false
} else if (Idata.apiKeys) {
// Backend returns { apiKeys: [...], count: n }
if (reset) {
apiKeys.value = data.apiKeys
} else {
apiKeys.value = [...apiKeys.value, ...data.apiKeys]
}
hasMore.value = false
} else {
// Paginated response { items: [...], nextToken, hasMore }
if (reset) {
apiKeys.value = data.items
} else {
apiKeys.value = [...apiKeys.value, ...data.items]
}
nextToken.value = data.nextToken
hasMore.value = data.hasMore
}
} catch (err: any) {
error.value = err.response?.data?.error || err.message || 'Failed to fetch API keys'
Eif (reset) {
apiKeys.value = []
}
throw err
} finally {
loading.value = false
}
}
async function loadMoreApiKeys() {
await fetchApiKeys(false)
}
async function createApiKey(data: CreateApiKeyRequest): Promise<CreateApiKeyResponse> {
const response = await api.post('/v1/admin/api-keys', data)
Iif (!Array.isArray(apiKeys.value)) {
apiKeys.value = []
}
apiKeys.value.unshift(response.data.apiKey) // Add the API key object to beginning
return response.data
}
async function getApiKey(id: string): Promise<ApiKey> {
const response = await api.get(`/v1/admin/api-keys/${id}`)
return response.data
}
async function revokeApiKey(id: string) {
await api.delete(`/v1/admin/api-keys/${id}`)
const index = apiKeys.value.findIndex((k) => k.id === id)
Eif (index !== -1 && apiKeys.value[index]) {
apiKeys.value[index].status = 'revoked'
apiKeys.value[index].revokedAt = new Date().toISOString()
}
}
return {
apiKeys,
loading,
error,
nextToken,
hasMore,
fetchApiKeys,
loadMoreApiKeys,
createApiKey,
getApiKey,
revokeApiKey
}
})
|