api: switch license endpoint to POST/JSON, fix active check, add key copy button

- Change /api/v1/license from GET with query params to POST with JSON body
- Request body uses license_key and email_address
- Response returns key, email_address, subscription_level
- Add active check (reject deactivated license keys)
- Exclude /api/v1/automations/ from API key auth (GHL webhook)
- Add copyableFields prop to AdminTable with clipboard icon
- Enable copy button on license key field in license-keys admin page
This commit is contained in:
NeilClack
2026-07-08 14:11:01 -05:00
parent 46b2cdf53d
commit 4d21288511
4 changed files with 58 additions and 19 deletions
@@ -68,6 +68,7 @@
searchFields={config.searchFields}
fieldTypes={config.fieldTypes}
singular={config.displayNameSingular}
copyableFields={['key']}
onRowClick={openReplace}
/>
</div>
+20 -17
View File
@@ -2,29 +2,31 @@ import { error } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
import { prisma } from '$lib/db';
// Get the key and email form the URL
// First, check if the key even exists, throw error if not
// Second, check that the email is attached to a real user, throw error
// Third, check that the key retrieved from the database belongs to the user, throw error
// Return response
export const GET: RequestHandler = async ({ url }) => {
const key = url.searchParams.get('key') ?? '';
const email = url.searchParams.get('email') ?? '';
if (key === '') {
throw error(400, 'license key required');
export const POST: RequestHandler = async ({ request }) => {
const body = await request.json();
const licenseKey = body.license_key ?? '';
const email = body.email_address ?? '';
if (!licenseKey) {
throw error(400, 'license_key is required');
}
if (!email) {
throw error(400, 'email_address is required');
}
const storedKey = await prisma.licenseKey.findFirst({
where: {
key: key
}
where: { key: licenseKey }
});
if (!storedKey) {
throw error(400, 'license key not found');
}
const userAccount = await prisma.user.findUniqueOrThrow({ where: { email: email } });
if (!storedKey.active) {
throw error(400, 'license key is not active');
}
const userAccount = await prisma.user.findUnique({ where: { email } });
if (!userAccount) {
throw error(400, 'user does not exist');
@@ -37,8 +39,9 @@ export const GET: RequestHandler = async ({ url }) => {
return new Response(
JSON.stringify({
key: storedKey.key,
active: storedKey.active,
level: storedKey.level
})
email_address: email,
subscription_level: storedKey.level
}),
{ headers: { 'content-type': 'application/json' } }
);
};