fix(15): convert auth service/tests to async PGlite pattern

The executor agents wrote sync SQLite-style calls (.get(), .all(), .run())
instead of the async Postgres pattern established in Phase 14. Fixed:
- auth.service.ts: use await + destructuring for all DB operations
- auth routes: await listApiKeys
- All auth test files: async createTestDb(), await service calls

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-04 21:40:12 +02:00
parent 72eefd1a06
commit 59e7f4be8a
5 changed files with 22 additions and 25 deletions

View File

@@ -33,7 +33,7 @@ app.get("/me", async (c) => {
app.get("/keys", requireAuth, async (c) => { app.get("/keys", requireAuth, async (c) => {
const db = c.get("db"); const db = c.get("db");
const keys = listApiKeys(db); const keys = await listApiKeys(db);
return c.json(keys); return c.json(keys);
}); });

View File

@@ -12,11 +12,10 @@ export async function createApiKey(db: Db = prodDb, name: string) {
const keyHash = await Bun.password.hash(rawKey); const keyHash = await Bun.password.hash(rawKey);
const keyPrefix = rawKey.slice(0, 8); const keyPrefix = rawKey.slice(0, 8);
const record = db const [record] = await db
.insert(apiKeys) .insert(apiKeys)
.values({ name, keyHash, keyPrefix }) .values({ name, keyHash, keyPrefix })
.returning() .returning();
.get();
return { ...record, rawKey }; return { ...record, rawKey };
} }
@@ -26,11 +25,10 @@ export async function verifyApiKey(
rawKey: string, rawKey: string,
): Promise<boolean> { ): Promise<boolean> {
const prefix = rawKey.slice(0, 8); const prefix = rawKey.slice(0, 8);
const candidates = db const candidates = await db
.select() .select()
.from(apiKeys) .from(apiKeys)
.where(eq(apiKeys.keyPrefix, prefix)) .where(eq(apiKeys.keyPrefix, prefix));
.all();
for (const candidate of candidates) { for (const candidate of candidates) {
const valid = await Bun.password.verify(rawKey, candidate.keyHash); const valid = await Bun.password.verify(rawKey, candidate.keyHash);
@@ -40,7 +38,7 @@ export async function verifyApiKey(
return false; return false;
} }
export function listApiKeys(db: Db = prodDb) { export async function listApiKeys(db: Db = prodDb) {
return db return db
.select({ .select({
id: apiKeys.id, id: apiKeys.id,
@@ -48,10 +46,9 @@ export function listApiKeys(db: Db = prodDb) {
keyPrefix: apiKeys.keyPrefix, keyPrefix: apiKeys.keyPrefix,
createdAt: apiKeys.createdAt, createdAt: apiKeys.createdAt,
}) })
.from(apiKeys) .from(apiKeys);
.all();
} }
export function deleteApiKey(db: Db = prodDb, id: number) { export async function deleteApiKey(db: Db = prodDb, id: number) {
db.delete(apiKeys).where(eq(apiKeys.id, id)).run(); await db.delete(apiKeys).where(eq(apiKeys.id, id));
} }

View File

@@ -21,10 +21,10 @@ mock.module("../../src/server/services/oauth.service", () => ({
// Import middleware AFTER mocks are set up // Import middleware AFTER mocks are set up
const { requireAuth } = await import("../../src/server/middleware/auth"); const { requireAuth } = await import("../../src/server/middleware/auth");
let db: ReturnType<typeof createTestDb>; let db: Awaited<ReturnType<typeof createTestDb>>;
beforeEach(() => { beforeEach(async () => {
db = createTestDb(); db = await createTestDb();
mockGetAuth.mockReset(); mockGetAuth.mockReset();
mockGetAuth.mockReturnValue(null); mockGetAuth.mockReturnValue(null);
mockVerifyAccessToken.mockReset(); mockVerifyAccessToken.mockReset();

View File

@@ -20,8 +20,8 @@ mock.module("../../src/server/services/oauth.service", () => ({
// Import routes AFTER mocks // Import routes AFTER mocks
const { authRoutes } = await import("../../src/server/routes/auth.ts"); const { authRoutes } = await import("../../src/server/routes/auth.ts");
function createTestApp() { async function createTestApp() {
const db = createTestDb(); const db = await createTestDb();
const app = new Hono<{ Variables: { db?: any } }>(); const app = new Hono<{ Variables: { db?: any } }>();
app.use("*", async (c, next) => { app.use("*", async (c, next) => {
@@ -35,10 +35,10 @@ function createTestApp() {
describe("Auth Routes", () => { describe("Auth Routes", () => {
let app: Hono; let app: Hono;
let db: ReturnType<typeof createTestDb>; let db: Awaited<ReturnType<typeof createTestDb>>;
beforeEach(() => { beforeEach(async () => {
const testApp = createTestApp(); const testApp = await createTestApp();
app = testApp.app; app = testApp.app;
db = testApp.db; db = testApp.db;
mockGetAuth.mockReset(); mockGetAuth.mockReset();

View File

@@ -8,10 +8,10 @@ import {
import { createTestDb } from "../helpers/db.ts"; import { createTestDb } from "../helpers/db.ts";
describe("Auth Service", () => { describe("Auth Service", () => {
let db: ReturnType<typeof createTestDb>; let db: Awaited<ReturnType<typeof createTestDb>>;
beforeEach(() => { beforeEach(async () => {
db = createTestDb(); db = await createTestDb();
}); });
describe("API Key Management", () => { describe("API Key Management", () => {
@@ -41,7 +41,7 @@ describe("Auth Service", () => {
it("deletes key so it is no longer valid", async () => { it("deletes key so it is no longer valid", async () => {
const result = await createApiKey(db, "test-key"); const result = await createApiKey(db, "test-key");
deleteApiKey(db, result.id); await deleteApiKey(db, result.id);
const isValid = await verifyApiKey(db, result.rawKey); const isValid = await verifyApiKey(db, result.rawKey);
expect(isValid).toBe(false); expect(isValid).toBe(false);
@@ -51,7 +51,7 @@ describe("Auth Service", () => {
await createApiKey(db, "key-one"); await createApiKey(db, "key-one");
await createApiKey(db, "key-two"); await createApiKey(db, "key-two");
const keys = listApiKeys(db); const keys = await listApiKeys(db);
expect(keys).toHaveLength(2); expect(keys).toHaveLength(2);
expect(keys[0].name).toBe("key-one"); expect(keys[0].name).toBe("key-one");
expect(keys[1].name).toBe("key-two"); expect(keys[1].name).toBe("key-two");