From fe95b500b07851312d8485e79ac769b8f6939fb4 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 21 Jun 2026 03:11:03 +0000 Subject: [PATCH 1/2] chore: update to core v0.5.0 and remove now-redundant workarounds Bump @haverstack/core and @haverstack/adapter-sqlite to ^0.5.0. Remove dead null guards in auth middleware: Stack.create() now throws if entity_id is absent, so ownerEntityId is always a string by the time the server starts. requireOwner() parameter type tightened to string. Relax PUT /records/:id/permissions from requireOwner to requireAuth: core v0.5.0 enforces creator-or-owner access in ScopedStack.setPermissions(), making the server-side owner-only restriction more restrictive than intended. Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01E2tdGyLhqTN2baMpaWDet3 --- package.json | 4 ++-- src/middleware/auth.ts | 8 ++------ src/routes/records.ts | 5 ++--- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index 64478a1..a38bf8f 100644 --- a/package.json +++ b/package.json @@ -17,8 +17,8 @@ "format:check": "prettier --check ." }, "dependencies": { - "@haverstack/adapter-sqlite": "^0.4.0", - "@haverstack/core": "^0.4.0", + "@haverstack/adapter-sqlite": "^0.5.0", + "@haverstack/core": "^0.5.0", "@hono/node-server": "^1.13.7", "hono": "^4.6.0", "pino": "^9.5.0", diff --git a/src/middleware/auth.ts b/src/middleware/auth.ts index f6bdc77..fbe1260 100644 --- a/src/middleware/auth.ts +++ b/src/middleware/auth.ts @@ -17,9 +17,6 @@ export function authMiddleware(ownerToken: string, ctx: StackContext): Middlewar if (header?.startsWith('Bearer ')) { const token = header.slice(7); if (safeCompare(token, ownerToken)) { - if (!ownerEntityId) { - return c.json({ error: 'Server misconfiguration: owner entity not set' }, 500); - } c.set('auth', { entityId: ownerEntityId }); } else { const result = await ctx.adapter.lookupToken(token); @@ -39,12 +36,11 @@ export function requireAuth(): MiddlewareHandler { }; } -export function requireOwner(ownerEntityId: string | null): MiddlewareHandler { +export function requireOwner(ownerEntityId: string): MiddlewareHandler { return async (c, next) => { const auth = c.get('auth'); if (!auth) return c.json({ error: 'Unauthorized' }, 401); - if (!ownerEntityId || auth.entityId !== ownerEntityId) - return c.json({ error: 'Forbidden' }, 403); + if (auth.entityId !== ownerEntityId) return c.json({ error: 'Forbidden' }, 403); await next(); }; } diff --git a/src/routes/records.ts b/src/routes/records.ts index a1620ac..dde1c16 100644 --- a/src/routes/records.ts +++ b/src/routes/records.ts @@ -1,7 +1,7 @@ import { Hono } from 'hono'; import type { AppEnv } from '../types.js'; import type { StackContext } from '../stack.js'; -import { requireAuth, requireOwner } from '../middleware/auth.js'; +import { requireAuth } from '../middleware/auth.js'; import { parseDate, serializeRecord, serializeVersion } from '../lib/serialize.js'; import { SYSTEM_TYPES } from '@haverstack/core'; import type { StackQuery, RecordFilter, Association, Permission, TypeId } from '@haverstack/core'; @@ -153,7 +153,6 @@ function parseQueryParams(url: URL): StackQuery { export function recordRoutes(ctx: StackContext): Hono { const app = new Hono(); const { stack } = ctx; - const { ownerEntityId } = stack; // POST /records/query — full query with content-field filters // Registered before /:id patterns to avoid param capture on the literal "query" segment. @@ -278,7 +277,7 @@ export function recordRoutes(ctx: StackContext): Hono { return c.json({ permissions: record.permissions ?? [] }); }); - app.put('/:id/permissions', requireOwner(ownerEntityId), async (c) => { + app.put('/:id/permissions', requireAuth(), async (c) => { const id = c.req.param('id'); const auth = c.get('auth')!; const body = await c.req.json<{ permissions: Permission[] }>(); From 8660d1fcd8cba5d4a467368f66958df4a9480ed3 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 21 Jun 2026 03:11:31 +0000 Subject: [PATCH 2/2] chore: update pnpm lockfile for core v0.5.0 Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01E2tdGyLhqTN2baMpaWDet3 --- pnpm-lock.yaml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a9af9ee..493ffaa 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,11 +9,11 @@ importers: .: dependencies: '@haverstack/adapter-sqlite': - specifier: ^0.4.0 - version: 0.4.0 + specifier: ^0.5.0 + version: 0.5.0 '@haverstack/core': - specifier: ^0.4.0 - version: 0.4.0 + specifier: ^0.5.0 + version: 0.5.0 '@hono/node-server': specifier: ^1.13.7 version: 1.19.14(hono@4.12.26) @@ -398,11 +398,11 @@ packages: resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@haverstack/adapter-sqlite@0.4.0': - resolution: {integrity: sha512-E7EvWLW/CWDOTrJ8hCLPbrkoduW7mfbd72jsyIZB+anxU4QEC1sUbksn71muTg8HiEB+ij1dso1m7DfM8Jl6vA==} + '@haverstack/adapter-sqlite@0.5.0': + resolution: {integrity: sha512-8gOtQRvX3hZTmxD1syFV6TzwvPPiOMd7tbLMGWslZAEOYp76UAjVRR5KV8CSnWuhY//2IgnHnrBZJtFtVrkBWA==} - '@haverstack/core@0.4.0': - resolution: {integrity: sha512-kauf46NBA99guAVj/t2Yy/3iu0h6vIbDlpLGrHk8iG0LFVLEaDPLEzX6gOeWdT6FdLCpZmGqnivxzo2b86d8mQ==} + '@haverstack/core@0.5.0': + resolution: {integrity: sha512-YIAvsWxWyM6VnZeyQhTcsujmj5VH+Oh1LmgpMzeJ4HR2Y60ml/ra+JhUh5Pvys7qm+ir+DVrxN4pZvcboQ9g/w==} '@hono/node-server@1.19.14': resolution: {integrity: sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==} @@ -1491,12 +1491,12 @@ snapshots: '@eslint/core': 0.17.0 levn: 0.4.1 - '@haverstack/adapter-sqlite@0.4.0': + '@haverstack/adapter-sqlite@0.5.0': dependencies: - '@haverstack/core': 0.4.0 + '@haverstack/core': 0.5.0 sql.js: 1.14.1 - '@haverstack/core@0.4.0': {} + '@haverstack/core@0.5.0': {} '@hono/node-server@1.19.14(hono@4.12.26)': dependencies: