From 17bdabadd69ca97f4bf61d45811174f9e61984ee Mon Sep 17 00:00:00 2001 From: Nathan Flurry Date: Fri, 27 Jun 2025 01:25:28 +0000 Subject: [PATCH] chore: split out onauth type from main config --- packages/core/src/actor/config.ts | 65 ++++++++++++++++++------------- packages/core/src/actor/mod.ts | 24 ++++++------ packages/core/src/manager/auth.ts | 2 +- 3 files changed, 50 insertions(+), 41 deletions(-) diff --git a/packages/core/src/actor/config.ts b/packages/core/src/actor/config.ts index 17d42b5df..546c19a91 100644 --- a/packages/core/src/actor/config.ts +++ b/packages/core/src/actor/config.ts @@ -172,6 +172,40 @@ type CreateVars = } | Record; +// Creates auth config +// +// This must have only one or the other or else AD will not be able to be inferred +type OnAuth = + | { + /** + * Called on the HTTP server before clients can interact with the actor. + * + * Only called for public endpoints. Calls to actors from within the backend + * do not trigger this handler. + * + * Data returned from this handler will be available on `c.conn.auth`. + * + * This function is required for any public HTTP endpoint access. Use this hook + * to validate client credentials and return authentication data that will be + * available on connections. This runs on the HTTP server (not the actor) + * in order to reduce load on the actor & prevent denial of server attacks + * against individual actors. + * + * If you need access to actor state for authentication, use onBeforeConnect + * with an empty onAuth function instead. + * + * You can also provide your own authentication middleware on your router if you + * choose, then use onAuth to pass the authentication data (e.g. user ID) to the + * actor itself. + * + * @param opts Authentication options including request and intent + * @returns Authentication data to attach to connections (must be serializable) + * @throws Throw an error to deny access to the actor + */ + onAuth: (opts: OnAuthOptions) => AD | Promise; + } + | Record; + export interface Actions { [Action: string]: ( c: ActionContext, @@ -189,7 +223,7 @@ export interface Actions { */ export type AuthIntent = "get" | "create" | "connect" | "action" | "message"; -interface OnAuthOptions { +export interface OnAuthOptions { req: Request; /** * @experimental @@ -208,33 +242,6 @@ interface BaseActorConfig< DB, R extends Actions, > { - /** - * Called on the HTTP server before clients can interact with the actor. - * - * Only called for public endpoints. Calls to actors from within the backend - * do not trigger this handler. - * - * Data returned from this handler will be available on `c.conn.auth`. - * - * This function is required for any public HTTP endpoint access. Use this hook - * to validate client credentials and return authentication data that will be - * available on connections. This runs on the HTTP server (not the actor) - * in order to reduce load on the actor & prevent denial of server attacks - * against individual actors. - * - * If you need access to actor state for authentication, use onBeforeConnect - * with an empty onAuth function instead. - * - * You can also provide your own authentication middleware on your router if you - * choose, then use onAuth to pass the authentication data (e.g. user ID) to the - * actor itself. - * - * @param opts Authentication options including request and intent - * @returns Authentication data to attach to connections (must be serializable) - * @throws Throw an error to deny access to the actor - */ - onAuth?: (opts: OnAuthOptions) => AD | Promise; - /** * Called when the actor is first initialized. * @@ -389,6 +396,7 @@ export type ActorConfig = Omit< | "db" > & BaseActorConfig> & + OnAuth & CreateState & CreateConnState & CreateVars & @@ -424,6 +432,7 @@ export type ActorConfigInput< | "db" > & BaseActorConfig & + OnAuth & CreateState & CreateConnState & CreateVars & diff --git a/packages/core/src/actor/mod.ts b/packages/core/src/actor/mod.ts index e4d7f30c4..a3c1d1698 100644 --- a/packages/core/src/actor/mod.ts +++ b/packages/core/src/actor/mod.ts @@ -6,18 +6,6 @@ import { } from "./config"; import { ActorDefinition } from "./definition"; -export type { ActorContext } from "./context"; -export { UserError, type UserErrorOptions } from "./errors"; -export type { Conn } from "./connection"; -export type { ActionContext } from "./action"; -export type { ActorConfig, OnConnectOptions } from "./config"; -export type { Encoding } from "@/actor/protocol/serde"; -export type { - ActorDefinition, - AnyActorDefinition, - ActorContextOf, - ActionContextOf, -} from "./definition"; export function actor< S, @@ -43,3 +31,15 @@ export function actor< return new ActorDefinition(config); } export type { ActorKey } from "@/manager/protocol/query"; +export type { ActorContext } from "./context"; +export { UserError, type UserErrorOptions } from "./errors"; +export type { Conn } from "./connection"; +export type { ActionContext } from "./action"; +export type * from "./config"; +export type { Encoding } from "@/actor/protocol/serde"; +export type { + ActorDefinition, + AnyActorDefinition, + ActorContextOf, + ActionContextOf, +} from "./definition"; diff --git a/packages/core/src/manager/auth.ts b/packages/core/src/manager/auth.ts index c4cb880d6..56056c241 100644 --- a/packages/core/src/manager/auth.ts +++ b/packages/core/src/manager/auth.ts @@ -64,7 +64,7 @@ export async function authenticateRequest( intents: Set, params: unknown, ): Promise { - if (!actorDefinition.config.onAuth) { + if (!("onAuth" in actorDefinition.config)) { throw new errors.Forbidden( "Actor requires authentication but no onAuth handler is defined", );