Skip to content

Commit 5a2c495

Browse files
committed
feat: API keys work
1 parent 7345d7a commit 5a2c495

File tree

3 files changed

+30
-6
lines changed

3 files changed

+30
-6
lines changed

apps/api/src/lib/api-key.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,12 @@ const getCachedAccessEntries = cacheable(
5050
export async function getApiKeyFromHeader(
5151
headers: Headers
5252
): Promise<ApiKeyRow | null> {
53-
const secret = headers.get('x-api-key');
53+
const xApiKey = headers.get('x-api-key');
54+
const auth = headers.get('authorization');
55+
const bearer = auth?.toLowerCase().startsWith('bearer ')
56+
? auth.slice(7).trim()
57+
: null;
58+
const secret = xApiKey ?? bearer ?? null;
5459
if (!secret) {
5560
return null;
5661
}
@@ -64,6 +69,15 @@ export async function getApiKeyFromHeader(
6469
return key;
6570
}
6671

72+
export function isApiKeyPresent(headers: Headers): boolean {
73+
const xApiKey = headers.get('x-api-key');
74+
if (xApiKey) {
75+
return true;
76+
}
77+
const auth = headers.get('authorization');
78+
return auth?.toLowerCase().startsWith('bearer ') ?? false;
79+
}
80+
6781
export async function resolveEffectiveScopesForWebsite(
6882
key: ApiKeyRow,
6983
websiteId: string

apps/api/src/lib/website-utils.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@ import { db, userPreferences, websites } from '@databuddy/db';
33
import { cacheable } from '@databuddy/redis';
44
import type { Website } from '@databuddy/shared';
55
import { eq } from 'drizzle-orm';
6-
import { getApiKeyFromHeader, hasWebsiteScope } from './api-key';
6+
import {
7+
getApiKeyFromHeader,
8+
hasWebsiteScope,
9+
isApiKeyPresent,
10+
} from './api-key';
711

812
export interface WebsiteContext {
913
user: unknown;
@@ -115,8 +119,7 @@ export async function getTimezone(
115119
}
116120

117121
export async function deriveWebsiteContext({ request }: { request: Request }) {
118-
const apiKeyPresent = request.headers.get('x-api-key') != null;
119-
if (apiKeyPresent) {
122+
if (isApiKeyPresent(request.headers)) {
120123
return await deriveWithApiKey(request);
121124
}
122125
return await deriveWithSession(request);

apps/api/src/middleware/website-auth.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import { auth } from '@databuddy/auth';
22
import { Elysia } from 'elysia';
3-
import { getApiKeyFromHeader, hasWebsiteScope } from '../lib/api-key';
3+
import {
4+
getApiKeyFromHeader,
5+
hasWebsiteScope,
6+
isApiKeyPresent,
7+
} from '../lib/api-key';
48
import { getCachedWebsite, getTimezone } from '../lib/website-utils';
59

610
function json(status: number, body: unknown) {
@@ -40,7 +44,10 @@ export function websiteAuth() {
4044
.derive(async ({ request }) => {
4145
const url = new URL(request.url);
4246
const websiteId = url.searchParams.get('website_id');
43-
const session = await auth.api.getSession({ headers: request.headers });
47+
const apiKeyPresent = isApiKeyPresent(request.headers);
48+
const session = apiKeyPresent
49+
? null
50+
: await auth.api.getSession({ headers: request.headers });
4451
const timezone = session?.user
4552
? await getTimezone(request, session)
4653
: await getTimezone(request, null);

0 commit comments

Comments
 (0)