API authentication updated to work correctly with public and private keys

This commit is contained in:
Matt Aitken
2023-07-25 17:52:20 +01:00
parent 642c95027c
commit 3a6c25d42d
2 changed files with 32 additions and 17 deletions
@@ -17,17 +17,10 @@ export async function findEnvironmentByApiKey(apiKey: string) {
return environment;
}
export async function findEnvironmentByPublicOrPrivateApiKey(apiKey: string) {
const environment = await prisma.runtimeEnvironment.findFirst({
export async function findEnvironmentByPublicApiKey(apiKey: string) {
const environment = await prisma.runtimeEnvironment.findUnique({
where: {
OR: [
{
apiKey,
},
{
pkApiKey: apiKey,
},
],
pkApiKey: apiKey,
},
include: {
project: true,
+29 -7
View File
@@ -1,7 +1,7 @@
import { z } from "zod";
import {
findEnvironmentByApiKey,
findEnvironmentByPublicOrPrivateApiKey,
findEnvironmentByPublicApiKey,
} from "~/models/runtimeEnvironment.server";
const AuthorizationHeaderSchema = z.string().regex(/^Bearer .+$/);
@@ -14,6 +14,30 @@ export async function authenticateApiRequest(
request: Request,
{ allowPublicKey = false }: { allowPublicKey?: boolean } = {}
): Promise<AuthenticatedEnvironment | null | undefined> {
const result = getApiKeyFromRequest(request);
if (!result) {
return;
}
//if it's a public API key and we don't allow public keys, return
if (!allowPublicKey) {
return findEnvironmentByApiKey(result.apiKey);
}
switch (result.type) {
case "PUBLIC":
return findEnvironmentByPublicApiKey(result.apiKey);
case "PRIVATE":
return findEnvironmentByApiKey(result.apiKey);
}
}
export function isPublicApiKey(key: string) {
return key.startsWith("pk_");
}
export function getApiKeyFromRequest(request: Request) {
const rawAuthorization = request.headers.get("Authorization");
const authorization = AuthorizationHeaderSchema.safeParse(rawAuthorization);
@@ -22,10 +46,8 @@ export async function authenticateApiRequest(
}
const apiKey = authorization.data.replace(/^Bearer /, "");
if (allowPublicKey) {
return findEnvironmentByPublicOrPrivateApiKey(apiKey);
}
return findEnvironmentByApiKey(apiKey);
const type = isPublicApiKey(apiKey)
? ("PUBLIC" as const)
: ("PRIVATE" as const);
return { apiKey, type };
}