@forklaunch/core 1.3.4 → 1.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -179,9 +179,6 @@ type TokenOptions = {
179
179
  readonly headerName?: string;
180
180
  };
181
181
  type DecodeResource = (token: string) => JWTPayload | Promise<JWTPayload>;
182
- type AuthMethodsBase = TokenOptions & (HmacMethods | ({
183
- readonly decodeResource?: DecodeResource;
184
- } & (PermissionSet | RoleSet) & (BasicAuthMethods | JwtAuthMethods)));
185
182
  type PermissionSet = {
186
183
  readonly allowedPermissions: Set<string>;
187
184
  } | {
@@ -192,11 +189,30 @@ type RoleSet = {
192
189
  } | {
193
190
  readonly forbiddenRoles: Set<string>;
194
191
  };
192
+ /** Auth base for authenticated routes — JWT/Basic, no RBAC. */
193
+ type AuthenticatedAuthBase = TokenOptions & {
194
+ readonly decodeResource?: DecodeResource;
195
+ readonly allowedPermissions?: never;
196
+ readonly forbiddenPermissions?: never;
197
+ readonly allowedRoles?: never;
198
+ readonly forbiddenRoles?: never;
199
+ } & (BasicAuthMethods | JwtAuthMethods);
200
+ /** Auth base for protected routes — JWT/Basic with required RBAC. */
201
+ type ProtectedAuthBase = TokenOptions & {
202
+ readonly decodeResource?: DecodeResource;
203
+ } & (PermissionSet | RoleSet) & (BasicAuthMethods | JwtAuthMethods);
204
+ /**
205
+ * @deprecated Use AccessAuth discriminated union instead.
206
+ * Kept for backwards compatibility with AuthMethods.
207
+ */
208
+ type AuthMethodsBase = TokenOptions & (HmacMethods | ({
209
+ readonly decodeResource?: DecodeResource;
210
+ } & ((PermissionSet & (BasicAuthMethods | JwtAuthMethods)) | (RoleSet & (BasicAuthMethods | JwtAuthMethods)) | (BasicAuthMethods | JwtAuthMethods))));
195
211
  /**
196
212
  * Route access level — determines authentication and authorization requirements.
197
213
  *
198
214
  * - `'public'` — No authentication required. `auth` must not be provided.
199
- * - `'authenticated'` — JWT or Basic auth required, any valid user. RBAC optional.
215
+ * - `'authenticated'` — JWT or Basic auth required, any valid user. RBAC not allowed.
200
216
  * - `'protected'` — JWT or Basic auth required. Must declare roles, permissions, or scope.
201
217
  * - `'internal'` — HMAC auth required (inter-service communication).
202
218
  */
@@ -204,7 +220,7 @@ type AccessLevel = 'public' | 'authenticated' | 'protected' | 'internal';
204
220
  /**
205
221
  * Discriminated union that narrows the `auth` type based on the `access` level.
206
222
  * - `public`: auth not allowed
207
- * - `authenticated`: auth optional (JWT/Basic, RBAC not required)
223
+ * - `authenticated`: JWT/Basic auth required, RBAC fields disallowed
208
224
  * - `protected`: auth required, must include at least one RBAC declaration
209
225
  * - `internal`: auth required, must be HMAC
210
226
  */
@@ -213,10 +229,10 @@ type AccessAuth<Auth> = {
213
229
  readonly auth?: never;
214
230
  } | {
215
231
  readonly access: 'authenticated';
216
- readonly auth?: Auth;
232
+ readonly auth?: Auth & AuthenticatedAuthBase;
217
233
  } | {
218
234
  readonly access: 'protected';
219
- readonly auth: Auth & ({
235
+ readonly auth: Auth & ProtectedAuthBase & ({
220
236
  readonly allowedPermissions: Set<string>;
221
237
  } | {
222
238
  readonly forbiddenPermissions: Set<string>;
@@ -179,9 +179,6 @@ type TokenOptions = {
179
179
  readonly headerName?: string;
180
180
  };
181
181
  type DecodeResource = (token: string) => JWTPayload | Promise<JWTPayload>;
182
- type AuthMethodsBase = TokenOptions & (HmacMethods | ({
183
- readonly decodeResource?: DecodeResource;
184
- } & (PermissionSet | RoleSet) & (BasicAuthMethods | JwtAuthMethods)));
185
182
  type PermissionSet = {
186
183
  readonly allowedPermissions: Set<string>;
187
184
  } | {
@@ -192,11 +189,30 @@ type RoleSet = {
192
189
  } | {
193
190
  readonly forbiddenRoles: Set<string>;
194
191
  };
192
+ /** Auth base for authenticated routes — JWT/Basic, no RBAC. */
193
+ type AuthenticatedAuthBase = TokenOptions & {
194
+ readonly decodeResource?: DecodeResource;
195
+ readonly allowedPermissions?: never;
196
+ readonly forbiddenPermissions?: never;
197
+ readonly allowedRoles?: never;
198
+ readonly forbiddenRoles?: never;
199
+ } & (BasicAuthMethods | JwtAuthMethods);
200
+ /** Auth base for protected routes — JWT/Basic with required RBAC. */
201
+ type ProtectedAuthBase = TokenOptions & {
202
+ readonly decodeResource?: DecodeResource;
203
+ } & (PermissionSet | RoleSet) & (BasicAuthMethods | JwtAuthMethods);
204
+ /**
205
+ * @deprecated Use AccessAuth discriminated union instead.
206
+ * Kept for backwards compatibility with AuthMethods.
207
+ */
208
+ type AuthMethodsBase = TokenOptions & (HmacMethods | ({
209
+ readonly decodeResource?: DecodeResource;
210
+ } & ((PermissionSet & (BasicAuthMethods | JwtAuthMethods)) | (RoleSet & (BasicAuthMethods | JwtAuthMethods)) | (BasicAuthMethods | JwtAuthMethods))));
195
211
  /**
196
212
  * Route access level — determines authentication and authorization requirements.
197
213
  *
198
214
  * - `'public'` — No authentication required. `auth` must not be provided.
199
- * - `'authenticated'` — JWT or Basic auth required, any valid user. RBAC optional.
215
+ * - `'authenticated'` — JWT or Basic auth required, any valid user. RBAC not allowed.
200
216
  * - `'protected'` — JWT or Basic auth required. Must declare roles, permissions, or scope.
201
217
  * - `'internal'` — HMAC auth required (inter-service communication).
202
218
  */
@@ -204,7 +220,7 @@ type AccessLevel = 'public' | 'authenticated' | 'protected' | 'internal';
204
220
  /**
205
221
  * Discriminated union that narrows the `auth` type based on the `access` level.
206
222
  * - `public`: auth not allowed
207
- * - `authenticated`: auth optional (JWT/Basic, RBAC not required)
223
+ * - `authenticated`: JWT/Basic auth required, RBAC fields disallowed
208
224
  * - `protected`: auth required, must include at least one RBAC declaration
209
225
  * - `internal`: auth required, must be HMAC
210
226
  */
@@ -213,10 +229,10 @@ type AccessAuth<Auth> = {
213
229
  readonly auth?: never;
214
230
  } | {
215
231
  readonly access: 'authenticated';
216
- readonly auth?: Auth;
232
+ readonly auth?: Auth & AuthenticatedAuthBase;
217
233
  } | {
218
234
  readonly access: 'protected';
219
- readonly auth: Auth & ({
235
+ readonly auth: Auth & ProtectedAuthBase & ({
220
236
  readonly allowedPermissions: Set<string>;
221
237
  } | {
222
238
  readonly forbiddenPermissions: Set<string>;
@@ -5,8 +5,8 @@ import { AnySchemaValidator } from '@forklaunch/validator';
5
5
  import { ServerOptions, IncomingMessage, ServerResponse } from 'node:http';
6
6
  import { O as OpenTelemetryCollector, M as MetricsDefinition, T as TelemetryOptions } from '../openTelemetryCollector-DorlR4pn.mjs';
7
7
  export { L as LogFn, a as LoggerMeta, b as MetricType, P as PinoLogger, h as httpRequestsTotalCounter, c as httpServerDurationHistogram, l as logger, m as meta } from '../openTelemetryCollector-DorlR4pn.mjs';
8
- import { M as Method, P as PathParamHttpContractDetails, H as HttpContractDetails, E as ExpressLikeRouterOptions, a as SessionObject, b as ParamsObject, R as ResponsesObject, B as Body, Q as QueryObject, c as HeadersObject, V as VersionSchema, d as SchemaAuthMethods, e as ExpressLikeSchemaHandler, f as ResolvedSessionObject, C as ContractDetails, g as PathMatch, L as LiveTypeFunction, h as LiveSdkFunction, A as AuthMethodsBase, i as ExpressLikeApplicationOptions, j as ParamsDictionary, k as VersionedRequests, l as AuthMethods, D as DecodeResource, m as BasicAuthMethods, F as ForklaunchRequest, n as MiddlewareContractDetails, o as ExpressLikeSchemaAuthMapper, p as ForklaunchNextFunction, q as ForklaunchResponse, r as ForklaunchResHeaders, s as ForklaunchStatusResponse, t as ForklaunchSendableData } from '../apiDefinition.types-pmtOHamW.mjs';
9
- export { u as AccessLevel, v as BodyObject, w as DefaultSubscriptionData, x as DocsConfiguration, y as ErrorContainer, z as ExpressLikeAuthMapper, G as ExpressLikeGlobalAuthOptions, I as ExpressLikeHandler, J as ExpressLikeSchemaGlobalAuthOptions, K as ExtractBody, N as ExtractContentType, O as ExtractResponseBody, T as ExtractedParamsObject, U as FileBody, W as ForklaunchBaseRequest, X as ForklaunchResErrors, Y as HmacMethods, Z as HttpMethod, _ as JsonBody, $ as JwtAuthMethods, a0 as LiveTypeFunctionRequestInit, a1 as MapParamsSchema, a2 as MapReqBodySchema, a3 as MapReqHeadersSchema, a4 as MapReqQuerySchema, a5 as MapResBodyMapSchema, a6 as MapResHeadersSchema, a7 as MapSchema, a8 as MapSessionSchema, a9 as MapVersionedReqsSchema, aa as MapVersionedRespsSchema, ab as MultipartForm, ac as NumberOnlyObject, ad as PathParamMethod, ae as PermissionSet, af as RawTypedResponseBody, ag as RequestContext, ah as ResolvedForklaunchAuthRequest, ai as ResolvedForklaunchRequest, aj as ResolvedForklaunchResponse, ak as ResponseBody, al as ResponseCompiledSchema, am as ResponseShape, an as RoleSet, ao as ServerSentEventBody, S as StringOnlyObject, ap as TextBody, aq as TypedBody, ar as TypedRequestBody, as as TypedResponseBody, at as UnknownBody, au as UnknownResponseBody, av as UrlEncodedForm, aw as VersionedResponses } from '../apiDefinition.types-pmtOHamW.mjs';
8
+ import { M as Method, P as PathParamHttpContractDetails, H as HttpContractDetails, E as ExpressLikeRouterOptions, a as SessionObject, b as ParamsObject, R as ResponsesObject, B as Body, Q as QueryObject, c as HeadersObject, V as VersionSchema, d as SchemaAuthMethods, e as ExpressLikeSchemaHandler, f as ResolvedSessionObject, C as ContractDetails, g as PathMatch, L as LiveTypeFunction, h as LiveSdkFunction, A as AuthMethodsBase, i as ExpressLikeApplicationOptions, j as ParamsDictionary, k as VersionedRequests, l as AuthMethods, D as DecodeResource, m as BasicAuthMethods, F as ForklaunchRequest, n as MiddlewareContractDetails, o as ExpressLikeSchemaAuthMapper, p as ForklaunchNextFunction, q as ForklaunchResponse, r as ForklaunchResHeaders, s as ForklaunchStatusResponse, t as ForklaunchSendableData } from '../apiDefinition.types-CN-qa49j.mjs';
9
+ export { u as AccessLevel, v as BodyObject, w as DefaultSubscriptionData, x as DocsConfiguration, y as ErrorContainer, z as ExpressLikeAuthMapper, G as ExpressLikeGlobalAuthOptions, I as ExpressLikeHandler, J as ExpressLikeSchemaGlobalAuthOptions, K as ExtractBody, N as ExtractContentType, O as ExtractResponseBody, T as ExtractedParamsObject, U as FileBody, W as ForklaunchBaseRequest, X as ForklaunchResErrors, Y as HmacMethods, Z as HttpMethod, _ as JsonBody, $ as JwtAuthMethods, a0 as LiveTypeFunctionRequestInit, a1 as MapParamsSchema, a2 as MapReqBodySchema, a3 as MapReqHeadersSchema, a4 as MapReqQuerySchema, a5 as MapResBodyMapSchema, a6 as MapResHeadersSchema, a7 as MapSchema, a8 as MapSessionSchema, a9 as MapVersionedReqsSchema, aa as MapVersionedRespsSchema, ab as MultipartForm, ac as NumberOnlyObject, ad as PathParamMethod, ae as PermissionSet, af as RawTypedResponseBody, ag as RequestContext, ah as ResolvedForklaunchAuthRequest, ai as ResolvedForklaunchRequest, aj as ResolvedForklaunchResponse, ak as ResponseBody, al as ResponseCompiledSchema, am as ResponseShape, an as RoleSet, ao as ServerSentEventBody, S as StringOnlyObject, ap as TextBody, aq as TypedBody, ar as TypedRequestBody, as as TypedResponseBody, at as UnknownBody, au as UnknownResponseBody, av as UrlEncodedForm, aw as VersionedResponses } from '../apiDefinition.types-CN-qa49j.mjs';
10
10
  import { JWTPayload, JWK } from 'jose';
11
11
  import { ZodSchemaValidator } from '@forklaunch/validator/zod';
12
12
  import { FastMCP } from 'fastmcp';
@@ -5,8 +5,8 @@ import { AnySchemaValidator } from '@forklaunch/validator';
5
5
  import { ServerOptions, IncomingMessage, ServerResponse } from 'node:http';
6
6
  import { O as OpenTelemetryCollector, M as MetricsDefinition, T as TelemetryOptions } from '../openTelemetryCollector-DorlR4pn.js';
7
7
  export { L as LogFn, a as LoggerMeta, b as MetricType, P as PinoLogger, h as httpRequestsTotalCounter, c as httpServerDurationHistogram, l as logger, m as meta } from '../openTelemetryCollector-DorlR4pn.js';
8
- import { M as Method, P as PathParamHttpContractDetails, H as HttpContractDetails, E as ExpressLikeRouterOptions, a as SessionObject, b as ParamsObject, R as ResponsesObject, B as Body, Q as QueryObject, c as HeadersObject, V as VersionSchema, d as SchemaAuthMethods, e as ExpressLikeSchemaHandler, f as ResolvedSessionObject, C as ContractDetails, g as PathMatch, L as LiveTypeFunction, h as LiveSdkFunction, A as AuthMethodsBase, i as ExpressLikeApplicationOptions, j as ParamsDictionary, k as VersionedRequests, l as AuthMethods, D as DecodeResource, m as BasicAuthMethods, F as ForklaunchRequest, n as MiddlewareContractDetails, o as ExpressLikeSchemaAuthMapper, p as ForklaunchNextFunction, q as ForklaunchResponse, r as ForklaunchResHeaders, s as ForklaunchStatusResponse, t as ForklaunchSendableData } from '../apiDefinition.types-D3fcC39w.js';
9
- export { u as AccessLevel, v as BodyObject, w as DefaultSubscriptionData, x as DocsConfiguration, y as ErrorContainer, z as ExpressLikeAuthMapper, G as ExpressLikeGlobalAuthOptions, I as ExpressLikeHandler, J as ExpressLikeSchemaGlobalAuthOptions, K as ExtractBody, N as ExtractContentType, O as ExtractResponseBody, T as ExtractedParamsObject, U as FileBody, W as ForklaunchBaseRequest, X as ForklaunchResErrors, Y as HmacMethods, Z as HttpMethod, _ as JsonBody, $ as JwtAuthMethods, a0 as LiveTypeFunctionRequestInit, a1 as MapParamsSchema, a2 as MapReqBodySchema, a3 as MapReqHeadersSchema, a4 as MapReqQuerySchema, a5 as MapResBodyMapSchema, a6 as MapResHeadersSchema, a7 as MapSchema, a8 as MapSessionSchema, a9 as MapVersionedReqsSchema, aa as MapVersionedRespsSchema, ab as MultipartForm, ac as NumberOnlyObject, ad as PathParamMethod, ae as PermissionSet, af as RawTypedResponseBody, ag as RequestContext, ah as ResolvedForklaunchAuthRequest, ai as ResolvedForklaunchRequest, aj as ResolvedForklaunchResponse, ak as ResponseBody, al as ResponseCompiledSchema, am as ResponseShape, an as RoleSet, ao as ServerSentEventBody, S as StringOnlyObject, ap as TextBody, aq as TypedBody, ar as TypedRequestBody, as as TypedResponseBody, at as UnknownBody, au as UnknownResponseBody, av as UrlEncodedForm, aw as VersionedResponses } from '../apiDefinition.types-D3fcC39w.js';
8
+ import { M as Method, P as PathParamHttpContractDetails, H as HttpContractDetails, E as ExpressLikeRouterOptions, a as SessionObject, b as ParamsObject, R as ResponsesObject, B as Body, Q as QueryObject, c as HeadersObject, V as VersionSchema, d as SchemaAuthMethods, e as ExpressLikeSchemaHandler, f as ResolvedSessionObject, C as ContractDetails, g as PathMatch, L as LiveTypeFunction, h as LiveSdkFunction, A as AuthMethodsBase, i as ExpressLikeApplicationOptions, j as ParamsDictionary, k as VersionedRequests, l as AuthMethods, D as DecodeResource, m as BasicAuthMethods, F as ForklaunchRequest, n as MiddlewareContractDetails, o as ExpressLikeSchemaAuthMapper, p as ForklaunchNextFunction, q as ForklaunchResponse, r as ForklaunchResHeaders, s as ForklaunchStatusResponse, t as ForklaunchSendableData } from '../apiDefinition.types-CAOGkjXe.js';
9
+ export { u as AccessLevel, v as BodyObject, w as DefaultSubscriptionData, x as DocsConfiguration, y as ErrorContainer, z as ExpressLikeAuthMapper, G as ExpressLikeGlobalAuthOptions, I as ExpressLikeHandler, J as ExpressLikeSchemaGlobalAuthOptions, K as ExtractBody, N as ExtractContentType, O as ExtractResponseBody, T as ExtractedParamsObject, U as FileBody, W as ForklaunchBaseRequest, X as ForklaunchResErrors, Y as HmacMethods, Z as HttpMethod, _ as JsonBody, $ as JwtAuthMethods, a0 as LiveTypeFunctionRequestInit, a1 as MapParamsSchema, a2 as MapReqBodySchema, a3 as MapReqHeadersSchema, a4 as MapReqQuerySchema, a5 as MapResBodyMapSchema, a6 as MapResHeadersSchema, a7 as MapSchema, a8 as MapSessionSchema, a9 as MapVersionedReqsSchema, aa as MapVersionedRespsSchema, ab as MultipartForm, ac as NumberOnlyObject, ad as PathParamMethod, ae as PermissionSet, af as RawTypedResponseBody, ag as RequestContext, ah as ResolvedForklaunchAuthRequest, ai as ResolvedForklaunchRequest, aj as ResolvedForklaunchResponse, ak as ResponseBody, al as ResponseCompiledSchema, am as ResponseShape, an as RoleSet, ao as ServerSentEventBody, S as StringOnlyObject, ap as TextBody, aq as TypedBody, ar as TypedRequestBody, as as TypedResponseBody, at as UnknownBody, au as UnknownResponseBody, av as UrlEncodedForm, aw as VersionedResponses } from '../apiDefinition.types-CAOGkjXe.js';
10
10
  import { JWTPayload, JWK } from 'jose';
11
11
  import { ZodSchemaValidator } from '@forklaunch/validator/zod';
12
12
  import { FastMCP } from 'fastmcp';
package/lib/http/index.js CHANGED
@@ -756,7 +756,7 @@ function parseHmacTokenPart(part, expectedKey) {
756
756
  if (key !== expectedKey || rest.length === 0) return void 0;
757
757
  return rest.join("=");
758
758
  }
759
- async function checkAuthorizationToken(req, authorizationMethod, authorizationToken, globalOptions) {
759
+ async function checkAuthorizationToken(req, authorizationMethod, authorizationToken, globalOptions, access) {
760
760
  if (authorizationMethod == null) {
761
761
  return void 0;
762
762
  }
@@ -893,7 +893,8 @@ async function checkAuthorizationToken(req, authorizationMethod, authorizationTo
893
893
  }
894
894
  }
895
895
  }
896
- if (hasPermissionChecks(collapsedAuthorizationMethod)) {
896
+ if (access === "authenticated" || access === "internal") {
897
+ } else if (hasPermissionChecks(collapsedAuthorizationMethod)) {
897
898
  if (!collapsedAuthorizationMethod.surfacePermissions) {
898
899
  return [500, "No permission surfacing function provided."];
899
900
  }
@@ -933,7 +934,7 @@ async function checkAuthorizationToken(req, authorizationMethod, authorizationTo
933
934
  return invalidAuthorizationTokenRoles;
934
935
  }
935
936
  }
936
- } else {
937
+ } else if (access === "protected") {
937
938
  return invalidAuthorizationMethod;
938
939
  }
939
940
  if (hasSubscriptionChecks(collapsedAuthorizationMethod)) {
@@ -966,9 +967,14 @@ async function checkAuthorizationToken(req, authorizationMethod, authorizationTo
966
967
  }
967
968
  }
968
969
  async function parseRequestAuth(req, res, next) {
970
+ const access = req.contractDetails.access;
971
+ if (access === "public") {
972
+ next?.();
973
+ return;
974
+ }
969
975
  const auth = req.contractDetails.auth;
970
976
  const token = req.headers[auth?.headerName ?? "Authorization"] || req.headers[auth?.headerName ?? "authorization"];
971
- const [error, message] = await checkAuthorizationToken(req, auth, token, req._globalOptions?.()?.auth) ?? [];
977
+ const [error, message] = await checkAuthorizationToken(req, auth, token, req._globalOptions?.()?.auth, access) ?? [];
972
978
  if (error != null) {
973
979
  req.openTelemetryCollector?.error(
974
980
  message || "Authorization Failed",