service-product.ts30 lines · main
1/**
2 * Product wall for service badges.
3 *
4 * After requireProjectAuth, if the caller authenticated with a service badge
5 * (c.var.serviceBadgeProduct is set), they may only hit routes for that product.
6 * Humans (session), deploy keys (brk_), CLI JWT, and Auth M2M JWTs are not
7 * product-locked — they keep full project access for their role.
8 */
9
10import { ForbiddenError } from '@briven/shared';
11import type { MiddlewareHandler } from 'hono';
12
13import type { ServiceBadgeProduct } from '../db/schema.js';
14import { serviceBadgeAllowedOnRoute } from '../services/service-badges.js';
15
16/**
17 * Require that a service-badge caller is allowed on this product wall.
18 * Pass the product this route family belongs to (db | s3 | auth).
19 */
20export const requireServiceProduct =
21 (routeProduct: ServiceBadgeProduct): MiddlewareHandler =>
22 async (c, next) => {
23 const badgeProduct = c.get('serviceBadgeProduct') as ServiceBadgeProduct | null | undefined;
24 if (!serviceBadgeAllowedOnRoute(badgeProduct ?? null, routeProduct)) {
25 throw new ForbiddenError(
26 `this service badge only opens the ${badgeProduct} product — not ${routeProduct}`,
27 );
28 }
29 await next();
30 };