authhero 8.18.0 → 8.19.0
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.
- package/dist/authhero.cjs +112 -112
- package/dist/authhero.d.ts +316 -238
- package/dist/authhero.mjs +10529 -10428
- package/dist/tsconfig.types.tsbuildinfo +1 -1
- package/dist/types/authentication-flows/passwordless.d.ts +4 -4
- package/dist/types/helpers/audit-target-types.d.ts +6 -0
- package/dist/types/helpers/default-destinations.d.ts +14 -4
- package/dist/types/helpers/outbox-destinations/code-hooks.d.ts +56 -0
- package/dist/types/helpers/password-connection.d.ts +16 -0
- package/dist/types/helpers/run-outbox-relay.d.ts +8 -1
- package/dist/types/hooks/codehooks.d.ts +78 -9
- package/dist/types/index.d.ts +235 -234
- package/dist/types/routes/auth-api/index.d.ts +22 -22
- package/dist/types/routes/auth-api/passwordless.d.ts +12 -12
- package/dist/types/routes/auth-api/register/index.d.ts +2 -2
- package/dist/types/routes/auth-api/token.d.ts +10 -10
- package/dist/types/routes/management-api/authentication-methods.d.ts +1 -1
- package/dist/types/routes/management-api/clients.d.ts +9 -9
- package/dist/types/routes/management-api/connections.d.ts +6 -6
- package/dist/types/routes/management-api/custom-domains.d.ts +6 -6
- package/dist/types/routes/management-api/email-templates.d.ts +18 -18
- package/dist/types/routes/management-api/forms.d.ts +126 -126
- package/dist/types/routes/management-api/guardian.d.ts +5 -5
- package/dist/types/routes/management-api/hooks.d.ts +24 -24
- package/dist/types/routes/management-api/index.d.ts +211 -211
- package/dist/types/routes/management-api/migration-sources.d.ts +6 -6
- package/dist/types/routes/management-api/organizations.d.ts +2 -2
- package/dist/types/routes/management-api/prompts.d.ts +4 -4
- package/dist/types/routes/management-api/roles.d.ts +6 -6
- package/dist/types/routes/management-api/tenant-export-import.d.ts +5 -5
- package/dist/types/routes/management-api/tenants.d.ts +1 -1
- package/dist/types/routes/management-api/users.d.ts +2 -2
- package/dist/types/routes/universal-login/common.d.ts +4 -4
- package/dist/types/routes/universal-login/flow-api.d.ts +8 -8
- package/dist/types/routes/universal-login/u2-index.d.ts +5 -5
- package/dist/types/routes/universal-login/u2-routes.d.ts +5 -5
- package/package.json +5 -5
|
@@ -414,7 +414,7 @@ export declare function passwordlessGrantUser(ctx: Context<{
|
|
|
414
414
|
} | undefined;
|
|
415
415
|
} | undefined;
|
|
416
416
|
passkey_options?: {
|
|
417
|
-
challenge_ui?: "
|
|
417
|
+
challenge_ui?: "both" | "autofill" | "button" | undefined;
|
|
418
418
|
local_enrollment_enabled?: boolean | undefined;
|
|
419
419
|
progressive_enrollment_enabled?: boolean | undefined;
|
|
420
420
|
} | undefined;
|
|
@@ -458,7 +458,7 @@ export declare function passwordlessGrantUser(ctx: Context<{
|
|
|
458
458
|
custom_login_page_preview?: string | undefined;
|
|
459
459
|
form_template?: string | undefined;
|
|
460
460
|
addons?: Record<string, any> | undefined;
|
|
461
|
-
token_endpoint_auth_method?: "none" | "
|
|
461
|
+
token_endpoint_auth_method?: "none" | "client_secret_post" | "client_secret_basic" | "client_secret_jwt" | "private_key_jwt" | undefined;
|
|
462
462
|
client_metadata?: Record<string, string> | undefined;
|
|
463
463
|
hide_sign_up_disabled_error?: boolean | undefined;
|
|
464
464
|
mobile?: Record<string, any> | undefined;
|
|
@@ -541,8 +541,8 @@ export declare function passwordlessGrantUser(ctx: Context<{
|
|
|
541
541
|
} | undefined;
|
|
542
542
|
authenticated_at?: string | undefined;
|
|
543
543
|
};
|
|
544
|
-
connectionType: "username" | "
|
|
545
|
-
authConnection: "username" | "
|
|
544
|
+
connectionType: "username" | "email" | "sms";
|
|
545
|
+
authConnection: "username" | "email" | "sms";
|
|
546
546
|
session_id: string | undefined;
|
|
547
547
|
authParams: {
|
|
548
548
|
client_id: string;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Target entity types whose id identifies an affected user. For these, the
|
|
2
|
+
* flat log's `user_id` is the target (the user the operation acted on) rather
|
|
3
|
+
* than the actor — matching Auth0, e.g. "Delete a User" logs the deleted user.
|
|
4
|
+
* Shared by `helpers/logging.ts` (write path) and
|
|
5
|
+
* `outbox-destinations/logs.ts` (outbox transform) so the two never drift. */
|
|
6
|
+
export declare const USER_TARGET_TYPES: Set<string>;
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import { DataAdapters } from "@authhero/adapter-interfaces";
|
|
1
|
+
import { CodeExecutor, DataAdapters } from "@authhero/adapter-interfaces";
|
|
2
2
|
import { EventDestination } from "./outbox-relay";
|
|
3
3
|
import { type GetServiceToken } from "./outbox-destinations/webhooks";
|
|
4
4
|
import type { WebhookInvoker } from "../types/AuthHeroConfig";
|
|
5
5
|
export interface CreateDefaultDestinationsConfig {
|
|
6
6
|
/**
|
|
7
|
-
* Data adapter —
|
|
8
|
-
*
|
|
7
|
+
* Data adapter — the `logs`, `hooks`, `users`, and `logStreams` adapters are
|
|
8
|
+
* used by the built-in destinations. When `codeExecutor` is set, the
|
|
9
|
+
* `actions`, `hookCode`, and `actionExecutions` adapters are also required so
|
|
10
|
+
* `CodeHookDestination` can resolve and run tenant code hooks.
|
|
9
11
|
*/
|
|
10
|
-
dataAdapter: Pick<DataAdapters, "logs" | "hooks" | "users" | "logStreams"
|
|
12
|
+
dataAdapter: Pick<DataAdapters, "logs" | "hooks" | "users" | "logStreams"> & Partial<Pick<DataAdapters, "actions" | "hookCode" | "actionExecutions" | "multiTenancyConfig">>;
|
|
11
13
|
/**
|
|
12
14
|
* Produces a Bearer access token for the given tenant, used when POSTing
|
|
13
15
|
* `hook.*` events to the configured webhook URLs.
|
|
@@ -37,6 +39,14 @@ export interface CreateDefaultDestinationsConfig {
|
|
|
37
39
|
* deliveries don't diverge from inline per-request ones.
|
|
38
40
|
*/
|
|
39
41
|
webhookInvoker?: WebhookInvoker;
|
|
42
|
+
/**
|
|
43
|
+
* Code executor — same instance passed to `init({ codeExecutor })`. When
|
|
44
|
+
* provided (and `dataAdapter` carries `actions`, `hookCode`, and
|
|
45
|
+
* `actionExecutions`), a `CodeHookDestination` is added so cron-drained
|
|
46
|
+
* `hook.*` events also run tenant code hooks. Without it, code hooks that
|
|
47
|
+
* failed per-request delivery would be silently skipped on retry.
|
|
48
|
+
*/
|
|
49
|
+
codeExecutor?: CodeExecutor;
|
|
40
50
|
}
|
|
41
51
|
/**
|
|
42
52
|
* Build the same array of outbox destinations that authhero's per-request
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { AuditEvent, CodeExecutor } from "@authhero/adapter-interfaces";
|
|
2
|
+
import { EventDestination } from "../outbox-relay";
|
|
3
|
+
import { CodeHookData } from "../../hooks/codehooks";
|
|
4
|
+
interface CodeHookInvocation {
|
|
5
|
+
eventId: string;
|
|
6
|
+
tenantId: string;
|
|
7
|
+
triggerId: string;
|
|
8
|
+
/** Serialized user snapshot from the audit event (`target.after`). */
|
|
9
|
+
user?: unknown;
|
|
10
|
+
/** Serialized request context from the audit event. */
|
|
11
|
+
request?: unknown;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Delivers `hook.*` outbox events to tenant-authored **code hooks** (actions)
|
|
15
|
+
* for the matching `trigger_id`. Runs alongside `WebhookDestination` — both
|
|
16
|
+
* accept the same `hook.*` events — so a single registration/deletion event
|
|
17
|
+
* fans out to webhooks *and* code hooks. The fan-out is not retried
|
|
18
|
+
* independently: the relay retries the whole outbox event, running its
|
|
19
|
+
* destinations in order and stopping at the first failure, so a code-hook
|
|
20
|
+
* failure here causes earlier destinations (e.g. webhooks) to run again on the
|
|
21
|
+
* retry. Every destination on the event must therefore be idempotent.
|
|
22
|
+
*
|
|
23
|
+
* Reliability model: unlike the previous inline execution (best-effort,
|
|
24
|
+
* at-most-once, failures logged and dropped), code hooks delivered here are
|
|
25
|
+
* **at-least-once**. If any code hook for the trigger fails, `deliver` throws
|
|
26
|
+
* so the relay retries the whole event with backoff and, after `maxRetries`,
|
|
27
|
+
* dead-letters it. A retry re-runs every code hook for the trigger, so the
|
|
28
|
+
* event id is passed to user code as `event.idempotency_key` for dedupe.
|
|
29
|
+
*
|
|
30
|
+
* Must be listed AFTER `WebhookDestination` and BEFORE
|
|
31
|
+
* `RegistrationFinalizerDestination` so `registration_completed_at` is only
|
|
32
|
+
* flipped on a pass where every webhook *and* code hook succeeded.
|
|
33
|
+
*
|
|
34
|
+
* Constructed per-request (via `getDestinations(ctx)`) so it can close over
|
|
35
|
+
* `ctx.env.codeExecutor`. The same class is used by the cron `drainOutbox`
|
|
36
|
+
* safety net when a `codeExecutor` is supplied to `createDefaultDestinations`.
|
|
37
|
+
* When no executor is configured, code hooks cannot run (nor be deployed), so
|
|
38
|
+
* `deliver` is a no-op success — matching the inline `handleCodeHook` which
|
|
39
|
+
* returns `null` without an executor.
|
|
40
|
+
*/
|
|
41
|
+
export declare class CodeHookDestination implements EventDestination {
|
|
42
|
+
name: string;
|
|
43
|
+
private data;
|
|
44
|
+
private codeExecutor?;
|
|
45
|
+
constructor(data: CodeHookData, codeExecutor?: CodeExecutor);
|
|
46
|
+
accepts(event: AuditEvent): boolean;
|
|
47
|
+
transform(event: AuditEvent): CodeHookInvocation;
|
|
48
|
+
deliver(invocations: CodeHookInvocation[]): Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* Fetch every hook for the tenant, paging past the adapter's default page
|
|
51
|
+
* size. `hooks.list` returns only the first page by default, so a tenant with
|
|
52
|
+
* more enabled code hooks than one page would silently skip the rest.
|
|
53
|
+
*/
|
|
54
|
+
private listAllHooks;
|
|
55
|
+
}
|
|
56
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { EnrichedClient } from "./client";
|
|
2
|
+
/**
|
|
3
|
+
* Resolve the tenant's database (username/password) connection for a client.
|
|
4
|
+
*
|
|
5
|
+
* The reset-password flows need the real connection name/id because a user's
|
|
6
|
+
* stored `user.connection` may be the hardcoded "Username-Password-Authentication"
|
|
7
|
+
* fallback rather than the tenant's actual connection. Centralised here so the
|
|
8
|
+
* HTML route and the screen handler resolve it identically.
|
|
9
|
+
*
|
|
10
|
+
* @param fallbackConnection connection name to use when the client has no
|
|
11
|
+
* database connection (typically `user.connection`).
|
|
12
|
+
*/
|
|
13
|
+
export declare function resolvePasswordConnection(client: EnrichedClient, fallbackConnection: string): {
|
|
14
|
+
connection: string;
|
|
15
|
+
connectionId?: string;
|
|
16
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DataAdapters } from "@authhero/adapter-interfaces";
|
|
1
|
+
import { CodeExecutor, DataAdapters } from "@authhero/adapter-interfaces";
|
|
2
2
|
import type { WebhookInvoker } from "../types/AuthHeroConfig";
|
|
3
3
|
export interface RunOutboxRelayConfig {
|
|
4
4
|
/** Same `DataAdapters` passed to `init()`. Must include `outbox` to drain. */
|
|
@@ -24,6 +24,13 @@ export interface RunOutboxRelayConfig {
|
|
|
24
24
|
maxRetries?: number;
|
|
25
25
|
/** Webhook HTTP timeout (ms), when the default invoker is used. */
|
|
26
26
|
webhookTimeoutMs?: number;
|
|
27
|
+
/**
|
|
28
|
+
* Optional code executor — same instance passed to `init({ codeExecutor })`.
|
|
29
|
+
* When provided, cron-drained `hook.*` events also run tenant code hooks, so
|
|
30
|
+
* a code hook that failed per-request delivery is retried rather than
|
|
31
|
+
* silently skipped.
|
|
32
|
+
*/
|
|
33
|
+
codeExecutor?: CodeExecutor;
|
|
27
34
|
}
|
|
28
35
|
/**
|
|
29
36
|
* One-call outbox relay for cron / scheduled handlers.
|
|
@@ -1,22 +1,62 @@
|
|
|
1
1
|
import { Context } from "hono";
|
|
2
|
-
import { ActionExecutionResult, CodeExecutionLog, DataAdapters, Hook } from "@authhero/adapter-interfaces";
|
|
2
|
+
import { ActionExecutionResult, CodeExecutionLog, CodeExecutor, DataAdapters, Hook } from "@authhero/adapter-interfaces";
|
|
3
3
|
import { Bindings, Variables } from "../types";
|
|
4
4
|
import { HookEvent, OnExecuteCredentialsExchangeAPI } from "../types/Hooks";
|
|
5
|
+
import { EnrichedClient } from "../helpers/client";
|
|
5
6
|
/**
|
|
6
7
|
* Auth0 uses `post-login` for what we internally call `post-user-login`.
|
|
7
8
|
* Normalize when writing execution records so the public API matches Auth0.
|
|
8
9
|
*/
|
|
9
10
|
export declare function toAuth0TriggerId(internal: string): string;
|
|
11
|
+
/**
|
|
12
|
+
* The subset of `DataAdapters` needed to resolve and run a code hook and to
|
|
13
|
+
* persist its execution record. Narrowed so `CodeHookDestination` and the cron
|
|
14
|
+
* `createDefaultDestinations` helper can construct it without depending on the
|
|
15
|
+
* full adapter surface.
|
|
16
|
+
*/
|
|
17
|
+
export type CodeHookData = Pick<DataAdapters, "hooks" | "actions" | "hookCode" | "actionExecutions" | "multiTenancyConfig">;
|
|
10
18
|
type CodeHook = Extract<Hook, {
|
|
11
19
|
code_id: string;
|
|
12
20
|
}>;
|
|
13
21
|
export declare function isCodeHook(hook: Hook): hook is CodeHook;
|
|
22
|
+
/**
|
|
23
|
+
* Loosened event shape accepted by `buildSerializableEvent` / `executeCodeHook`.
|
|
24
|
+
*
|
|
25
|
+
* The inline hook call sites pass a full `HookEvent`. The `CodeHookDestination`
|
|
26
|
+
* (which runs from the outbox relay, after the request has closed) has no live
|
|
27
|
+
* `ctx` and reconstructs the event from the persisted audit event, so `user`
|
|
28
|
+
* and `request` arrive as already-serialized `unknown` values. Both are
|
|
29
|
+
* assignable to this type.
|
|
30
|
+
*/
|
|
31
|
+
export type CodeHookEventInput = {
|
|
32
|
+
ctx?: unknown;
|
|
33
|
+
client?: Pick<EnrichedClient, "client_id" | "name" | "client_metadata"> | null;
|
|
34
|
+
} & Record<string, unknown>;
|
|
14
35
|
/**
|
|
15
36
|
* Build a serializable event object from a HookEvent.
|
|
16
37
|
* Strips the `ctx` property (Hono context) which cannot be serialized,
|
|
17
38
|
* and returns a plain JSON-compatible object.
|
|
18
39
|
*/
|
|
19
|
-
export declare function buildSerializableEvent(event:
|
|
40
|
+
export declare function buildSerializableEvent(event: CodeHookEventInput, secrets?: Record<string, string>): Record<string, unknown>;
|
|
41
|
+
/**
|
|
42
|
+
* The namespaced API surface exposed to code hooks. User code records calls of
|
|
43
|
+
* the form `<namespace>.<method>(...)` (e.g. `accessToken.setCustomClaim`,
|
|
44
|
+
* `access.deny`), which {@link replayApiCalls} replays against the real
|
|
45
|
+
* namespace objects. Each top-level key is a namespace whose members are the
|
|
46
|
+
* callable methods for that namespace — so the shape is nested (namespace →
|
|
47
|
+
* method → function) rather than a flat `any` surface. Concrete per-trigger API
|
|
48
|
+
* types (`OnExecute*API`) structurally satisfy this.
|
|
49
|
+
*
|
|
50
|
+
* The method args stay permissive (`any[]`): this surface is a dynamic
|
|
51
|
+
* dispatcher — {@link replayApiCalls} looks methods up by string and applies
|
|
52
|
+
* the recorded `unknown[]` args, while call sites register concretely-typed
|
|
53
|
+
* methods (`(key: string, value: unknown) => void`, …). A stricter `unknown[]`
|
|
54
|
+
* args tuple would reject those concrete registrations (parameter
|
|
55
|
+
* contravariance). The return type is still narrowed to `unknown`.
|
|
56
|
+
*/
|
|
57
|
+
export type CodeHookApiMethod = (...args: any[]) => unknown;
|
|
58
|
+
export type CodeHookApiNamespace = Record<string, CodeHookApiMethod>;
|
|
59
|
+
export type CodeHookApi = Record<string, CodeHookApiNamespace>;
|
|
20
60
|
/**
|
|
21
61
|
* Replay recorded API calls from code hook execution against real API objects.
|
|
22
62
|
* Handles calls like "accessToken.setCustomClaim" by navigating the api object.
|
|
@@ -24,22 +64,51 @@ export declare function buildSerializableEvent(event: HookEvent, secrets?: Recor
|
|
|
24
64
|
export declare function replayApiCalls(apiCalls: Array<{
|
|
25
65
|
method: string;
|
|
26
66
|
args: unknown[];
|
|
27
|
-
}>, api:
|
|
67
|
+
}>, api: CodeHookApi): void;
|
|
28
68
|
export type HandleCodeHookOutcome = {
|
|
29
69
|
result: ActionExecutionResult;
|
|
30
70
|
logs: CodeExecutionLog[];
|
|
31
71
|
/** True if api.access.deny was recorded by the executor. */
|
|
32
72
|
denied: boolean;
|
|
33
73
|
};
|
|
74
|
+
/**
|
|
75
|
+
* Core code-hook execution, decoupled from the Hono request `ctx`.
|
|
76
|
+
*
|
|
77
|
+
* Given an explicit executor, data adapter, and tenant, fetches the code,
|
|
78
|
+
* runs it, and replays the recorded API calls against `api`. Shared by the
|
|
79
|
+
* inline `handleCodeHook` wrapper (request-time) and by `CodeHookDestination`
|
|
80
|
+
* (outbox relay, after the request has closed).
|
|
81
|
+
*
|
|
82
|
+
* Always returns an outcome — including a `code_not_found` / `execution_failed`
|
|
83
|
+
* outcome — so the caller can persist an `action_executions` record. It only
|
|
84
|
+
* throws for `api.access.deny`, which surfaces as a thrown `HTTPException` from
|
|
85
|
+
* the replayed API call; callers that must abort the flow catch it.
|
|
86
|
+
*
|
|
87
|
+
* `idempotencyKey`, when set, is exposed to user code as `event.idempotency_key`.
|
|
88
|
+
* The outbox is at-least-once, so a retried hook event re-runs the code; authors
|
|
89
|
+
* performing non-idempotent side effects can dedupe on this key.
|
|
90
|
+
*/
|
|
91
|
+
export declare function executeCodeHook(params: {
|
|
92
|
+
codeExecutor: CodeExecutor;
|
|
93
|
+
data: CodeHookData;
|
|
94
|
+
tenantId: string;
|
|
95
|
+
hook: {
|
|
96
|
+
code_id: string;
|
|
97
|
+
hook_id?: string;
|
|
98
|
+
};
|
|
99
|
+
event: CodeHookEventInput;
|
|
100
|
+
triggerId: string;
|
|
101
|
+
api: CodeHookApi;
|
|
102
|
+
idempotencyKey?: string;
|
|
103
|
+
}): Promise<HandleCodeHookOutcome>;
|
|
34
104
|
/**
|
|
35
105
|
* Execute a code hook by fetching the code from the database, running it
|
|
36
106
|
* through the code executor, and replaying API calls against the real api
|
|
37
107
|
* object.
|
|
38
108
|
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* unavailable — the caller decides whether to surface that.
|
|
109
|
+
* Thin request-time wrapper over `executeCodeHook` that resolves the executor
|
|
110
|
+
* and tenant from `ctx`. Returns `null` when the code executor is unavailable
|
|
111
|
+
* or the tenant can't be resolved — the caller decides whether to surface that.
|
|
43
112
|
*/
|
|
44
113
|
export declare function handleCodeHook(ctx: Context<{
|
|
45
114
|
Bindings: Bindings;
|
|
@@ -47,13 +116,13 @@ export declare function handleCodeHook(ctx: Context<{
|
|
|
47
116
|
}>, data: DataAdapters, hook: {
|
|
48
117
|
code_id: string;
|
|
49
118
|
hook_id: string;
|
|
50
|
-
}, event: HookEvent, triggerId: string, api:
|
|
119
|
+
}, event: HookEvent, triggerId: string, api: CodeHookApi): Promise<HandleCodeHookOutcome | null>;
|
|
51
120
|
/**
|
|
52
121
|
* Aggregate per-action outcomes into an Auth0-shape execution record and
|
|
53
122
|
* persist it via the adapter. Returns the generated execution_id (uuid)
|
|
54
123
|
* so the caller can embed it in the surrounding tenant log.
|
|
55
124
|
*/
|
|
56
|
-
export declare function persistActionExecution(data: DataAdapters, tenant_id: string, triggerId: string, outcomes: HandleCodeHookOutcome[]): Promise<string | null>;
|
|
125
|
+
export declare function persistActionExecution(data: Pick<DataAdapters, "actionExecutions">, tenant_id: string, triggerId: string, outcomes: HandleCodeHookOutcome[]): Promise<string | null>;
|
|
57
126
|
/**
|
|
58
127
|
* Execute code hooks for the credentials-exchange trigger.
|
|
59
128
|
* Filters enabled code hooks from the provided hooks list and executes them.
|