mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
## Problem Studio expected aliased fields from the last-used API-key endpoint, but the live endpoint returns OTEL attribute names. This kept legacy API-key activity unavailable and prevented Studio from showing activity for new JWT signing keys. Tracks FE-2462 and FE-4315. ## Fix Normalize the endpoint response at the data boundary, keep the `showApiKeysLastUsed` feature flag, and show activity from the past 24 hours for new JWT signing keys. Legacy HS256 signing keys remain blank because the analytics response does not provide a stable signing-key record ID for them. The request remains hosted-only, permission-gated, and non-blocking, and the existing last-rotated column remains intact. ## How to test - Make a request with a legacy anon or service-role API key, then open Project Settings > API Keys and verify its last request appears. - Make an Auth request signed by a new JWT signing key, then open JWT Keys and verify the matching key shows a Last used timestamp. - Verify a new key without activity shows No requests in the past 24 hours. - Verify the legacy HS256 signing-key row leaves Last used blank. - Expected result: legacy API keys and new JWT signing keys display activity from the shared endpoint without changing self-hosted Studio. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a **Last used** column for JWT signing keys on supported platforms. * Displays usage timestamps, loading and error states, or when a key has had no requests in the past 24 hours. * Usage tracking now includes both API keys and JWT signing keys. * **Bug Fixes** * Improved handling of usage records for legacy and current keys. * Usage details appear only on supported platforms and for users with the required permissions. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
37 lines
813 B
TypeScript
37 lines
813 B
TypeScript
import dayjs from 'dayjs'
|
|
|
|
import type { ApiKeyLastUsed } from '@/data/analytics/api-keys-last-used-query'
|
|
|
|
export function getLastUsedAPIKeys(
|
|
apiKeys: {
|
|
tags: string
|
|
api_key: string
|
|
}[],
|
|
logData: ApiKeyLastUsed[] | null | undefined
|
|
) {
|
|
if (apiKeys.length < 1 || !logData || logData.length < 1) {
|
|
return {}
|
|
}
|
|
|
|
const now = dayjs()
|
|
|
|
return apiKeys.reduce(
|
|
(a, i) => {
|
|
const entry = logData?.find(
|
|
({ role, signaturePrefix }) =>
|
|
role &&
|
|
signaturePrefix &&
|
|
i.tags.indexOf(role) >= 0 &&
|
|
i.api_key.split('.')[2]?.startsWith(signaturePrefix)
|
|
)?.timestamp
|
|
|
|
if (entry) {
|
|
a[i.api_key] = dayjs.duration(now.diff(dayjs(entry))).humanize(false)
|
|
}
|
|
|
|
return a
|
|
},
|
|
{} as { [apikey: string]: string }
|
|
)
|
|
}
|