diff --git a/README.md b/README.md index be75cca..43da4d6 100644 --- a/README.md +++ b/README.md @@ -50,4 +50,3 @@ CRUD layer has been removed; see `docs/ADMIN_OVERHAUL.md` for the migration note | `/admin/proclamation-categories` | Draggable reorder | | `/admin/proclamation-groups` | Draggable reorder | | `/admin/license-keys` | List-only + rotate | -| `/admin/api-keys` | Super-only key rotation | diff --git a/src/routes/(protected)/admin/api-keys/+page.server.ts b/src/routes/(protected)/admin/api-keys/+page.server.ts deleted file mode 100644 index 49a5628..0000000 --- a/src/routes/(protected)/admin/api-keys/+page.server.ts +++ /dev/null @@ -1,62 +0,0 @@ -import type { PageServerLoad } from './$types'; -import { error } from '@sveltejs/kit'; -import { prisma } from '$lib/db'; -import { rotateApiKey } from '$lib/server/api-key'; -import { isSuper } from '$lib/server/roles'; - -export const load: PageServerLoad = async ({ locals }) => { - if (!isSuper(locals)) { - throw error(403, 'Only Super admins can manage API keys'); - } - - const now = new Date(); - const activeKey = await prisma.apiKey.findFirst({ - where: { - revokedAt: null, - OR: [{ expiresAt: null }, { expiresAt: { gt: now } }] - }, - select: { keyPrefix: true, createdAt: true, expiresAt: true }, - orderBy: { createdAt: 'desc' } - }); - - const expiredCount = await prisma.apiKey.count({ - where: { - OR: [{ revokedAt: { not: null, lte: now } }, { expiresAt: { not: null, lte: now } }] - } - }); - - return { - activeKey: activeKey - ? { - prefix: activeKey.keyPrefix, - createdAt: activeKey.createdAt.toISOString(), - expiresAt: activeKey.expiresAt?.toISOString() ?? null - } - : null, - totalRotated: expiredCount - }; -}; - -export const actions = { - rotate: async ({ locals }) => { - if (!isSuper(locals)) { - return { success: false, error: 'Not authorized' }; - } - - const result = await rotateApiKey(false); - return { - success: true, - newKey: result.plaintext, - mode: 'normal' as const, - expiresAt: result.previousExpiresAt?.toISOString() ?? null - }; - }, - rotateEmergency: async ({ locals }) => { - if (!isSuper(locals)) { - return { success: false, error: 'Not authorized' }; - } - - const result = await rotateApiKey(true); - return { success: true, newKey: result.plaintext, mode: 'emergency' as const }; - } -}; diff --git a/src/routes/(protected)/admin/api-keys/+page.svelte b/src/routes/(protected)/admin/api-keys/+page.svelte deleted file mode 100644 index 40e23e0..0000000 --- a/src/routes/(protected)/admin/api-keys/+page.svelte +++ /dev/null @@ -1,143 +0,0 @@ - - -
- {mode === 'emergency' ? 'Emergency Rotation Complete' : 'New API Key Generated'} -
-This key will not be shown again. Copy it now.
-{newKey}
- - The previous key will remain valid until {new Date(expiryDate).toLocaleString()} - to give in-field devices time to update. -
- {/if} -{data.activeKey.prefix}
- No active API key. Generate one below.
- {/if} - {#if data.totalRotated > 0} -- {data.totalRotated} previous key(s) have been rotated. -
- {/if} -