authhero 9.24.1 → 9.26.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.
Files changed (59) hide show
  1. package/dist/assets/u/widget/index.esm.js +1 -1
  2. package/dist/authhero.cjs +155 -155
  3. package/dist/authhero.d.ts +612 -171
  4. package/dist/authhero.mjs +16457 -15581
  5. package/dist/tsconfig.types.tsbuildinfo +1 -1
  6. package/dist/types/adapters/createEncryptedDataAdapter.d.ts +2 -1
  7. package/dist/types/adapters/index.d.ts +1 -1
  8. package/dist/types/authentication-flows/passwordless.d.ts +12 -5
  9. package/dist/types/errors/management-api-error.d.ts +113 -0
  10. package/dist/types/helpers/audit-target-types.d.ts +26 -0
  11. package/dist/types/helpers/client.d.ts +18 -0
  12. package/dist/types/helpers/control-plane-caller.d.ts +15 -0
  13. package/dist/types/helpers/platform-rows.d.ts +27 -0
  14. package/dist/types/helpers/request-data.d.ts +12 -0
  15. package/dist/types/helpers/reserved-claims.d.ts +2 -2
  16. package/dist/types/helpers/synced-rows.d.ts +1 -0
  17. package/dist/types/index.d.ts +499 -167
  18. package/dist/types/routes/auth-api/index.d.ts +10 -10
  19. package/dist/types/routes/auth-api/passwordless.d.ts +10 -10
  20. package/dist/types/routes/management-api/action-executions.d.ts +1 -1
  21. package/dist/types/routes/management-api/action-triggers.d.ts +8 -2
  22. package/dist/types/routes/management-api/actions.d.ts +44 -11
  23. package/dist/types/routes/management-api/authentication-methods.d.ts +1 -1
  24. package/dist/types/routes/management-api/branding.d.ts +13 -1
  25. package/dist/types/routes/management-api/client-grants.d.ts +13 -0
  26. package/dist/types/routes/management-api/clients.d.ts +27 -8
  27. package/dist/types/routes/management-api/connections.d.ts +43 -6
  28. package/dist/types/routes/management-api/custom-domains.d.ts +6 -6
  29. package/dist/types/routes/management-api/email-templates.d.ts +18 -18
  30. package/dist/types/routes/management-api/emails.d.ts +18 -0
  31. package/dist/types/routes/management-api/failed-events.d.ts +24 -0
  32. package/dist/types/routes/management-api/guardian.d.ts +5 -5
  33. package/dist/types/routes/management-api/helpers.d.ts +1 -1
  34. package/dist/types/routes/management-api/hook-code.d.ts +2 -2
  35. package/dist/types/routes/management-api/hooks.d.ts +126 -21
  36. package/dist/types/routes/management-api/index.d.ts +480 -152
  37. package/dist/types/routes/management-api/keys.d.ts +8 -8
  38. package/dist/types/routes/management-api/log-streams.d.ts +6 -6
  39. package/dist/types/routes/management-api/logs.d.ts +4 -4
  40. package/dist/types/routes/management-api/migration-sources.d.ts +6 -6
  41. package/dist/types/routes/management-api/organizations.d.ts +2 -2
  42. package/dist/types/routes/management-api/prompts.d.ts +12 -6
  43. package/dist/types/routes/management-api/resource-servers.d.ts +57 -20
  44. package/dist/types/routes/management-api/rollouts.d.ts +261 -0
  45. package/dist/types/routes/management-api/tenant-operations.d.ts +10 -5
  46. package/dist/types/routes/management-api/tenants.d.ts +24 -8
  47. package/dist/types/routes/management-api/users.d.ts +24 -24
  48. package/dist/types/routes/universal-login/common.d.ts +38 -10
  49. package/dist/types/routes/universal-login/flow-api.d.ts +4 -4
  50. package/dist/types/routes/universal-login/screens/login-partials.d.ts +8 -0
  51. package/dist/types/routes/universal-login/u2-index.d.ts +5 -5
  52. package/dist/types/routes/universal-login/u2-routes.d.ts +5 -5
  53. package/dist/types/state-machines/login-session.d.ts +1 -1
  54. package/dist/types/types/AuthHeroConfig.d.ts +37 -1
  55. package/dist/types/types/Bindings.d.ts +2 -1
  56. package/dist/types/types/Variables.d.ts +8 -0
  57. package/dist/types/utils/field-encryption.d.ts +7 -0
  58. package/dist/types/utils/jwt.d.ts +2 -0
  59. package/package.json +6 -6
@@ -22,7 +22,8 @@ interface EncryptionOptions {
22
22
  * Encrypted columns: clients.client_secret, connections.options
23
23
  * (client_secret/app_secret/twilio_token/configuration.client_secret),
24
24
  * email_providers.credentials, authentication_methods.totp_secret,
25
- * migration_sources.credentials.client_secret.
25
+ * migration_sources.credentials.client_secret, actions.secrets[].value,
26
+ * action_versions.secrets[].value, hook_code.secrets values.
26
27
  *
27
28
  * clientConnections.listByClient is also wrapped so its returned Connection
28
29
  * objects are decrypted — getEnrichedClient uses this path to load connections
@@ -1,5 +1,5 @@
1
1
  export * from "./cache";
2
2
  export { createEncryptedDataAdapter, createEncryptedDataAdapterWithKeyRing, } from "./createEncryptedDataAdapter";
3
3
  export type { EncryptKeyIdResolver } from "./createEncryptedDataAdapter";
4
- export { loadEncryptionKey, encryptField, decryptField, encryptFieldWithRing, decryptFieldWithRing, parseKeyId, isEncrypted, } from "../utils/field-encryption";
4
+ export { loadEncryptionKey, encryptField, decryptField, encryptFieldWithRing, decryptFieldWithRing, parseKeyId, isEncrypted, canDecrypt, } from "../utils/field-encryption";
5
5
  export type { KeyRing } from "../utils/field-encryption";
@@ -136,6 +136,10 @@ export declare function passwordlessGrantUser(ctx: Context<{
136
136
  updated_at: string;
137
137
  friendly_name: string;
138
138
  id: string;
139
+ parent_tenant_id?: string | null | undefined;
140
+ config_sync?: "inherit-on-read" | "synced" | null | undefined;
141
+ config_sync_hash?: string | null | undefined;
142
+ config_synced_at?: string | null | undefined;
139
143
  audience?: string | undefined;
140
144
  picture_url?: string | undefined;
141
145
  support_email?: string | undefined;
@@ -239,7 +243,7 @@ export declare function passwordlessGrantUser(ctx: Context<{
239
243
  pushed_authorization_requests_supported?: boolean | undefined;
240
244
  authorization_response_iss_parameter_supported?: boolean | undefined;
241
245
  deployment_type?: "shared" | "wfp" | undefined;
242
- provisioning_state?: "pending" | "failed" | "ready" | undefined;
246
+ provisioning_state?: "pending" | "ready" | "failed" | undefined;
243
247
  provisioning_error?: string | undefined;
244
248
  provisioning_state_changed_at?: string | undefined;
245
249
  bundle_configuration?: string | undefined;
@@ -287,7 +291,7 @@ export declare function passwordlessGrantUser(ctx: Context<{
287
291
  } | undefined;
288
292
  } | undefined;
289
293
  mfa?: {
290
- policy?: "always" | "never" | undefined;
294
+ policy?: "never" | "always" | undefined;
291
295
  factors?: {
292
296
  sms: boolean;
293
297
  otp: boolean;
@@ -386,7 +390,7 @@ export declare function passwordlessGrantUser(ctx: Context<{
386
390
  } | undefined;
387
391
  unique?: boolean | undefined;
388
392
  profile_required?: boolean | undefined;
389
- verification_method?: "link" | "code" | undefined;
393
+ verification_method?: "code" | "link" | undefined;
390
394
  } | undefined;
391
395
  username?: {
392
396
  identifier?: {
@@ -436,6 +440,9 @@ export declare function passwordlessGrantUser(ctx: Context<{
436
440
  } | undefined;
437
441
  set_user_root_attributes?: "on_each_login" | "on_first_login" | "never_on_login" | undefined;
438
442
  };
443
+ scope?: "local" | "shared" | "platform" | undefined;
444
+ override?: "secrets" | "none" | "fields" | undefined;
445
+ enforce?: boolean | undefined;
439
446
  id?: string | undefined;
440
447
  display_name?: string | undefined;
441
448
  enabled_clients?: string[] | undefined;
@@ -561,8 +568,8 @@ export declare function passwordlessGrantUser(ctx: Context<{
561
568
  } | undefined;
562
569
  authenticated_at?: string | undefined;
563
570
  };
564
- connectionType: "username" | "email" | "sms";
565
- authConnection: "username" | "email" | "sms";
571
+ connectionType: "email" | "username" | "sms";
572
+ authConnection: "email" | "username" | "sms";
566
573
  session_id: string | undefined;
567
574
  authParams: {
568
575
  audience?: string | undefined;
@@ -0,0 +1,113 @@
1
+ import { Context } from "hono";
2
+ import { ContentfulStatusCode } from "hono/utils/http-status";
3
+ import { JSONHTTPException } from "./json-http-exception";
4
+ /**
5
+ * Management API errors in Auth0's wire shape. Auth0 SDKs (go-auth0, the
6
+ * Terraform provider, node-auth0) parse `{ statusCode, error, message,
7
+ * errorCode }` and branch on `errorCode`.
8
+ *
9
+ * The bodies below are a superset of Auth0's: where Auth0 returns a message or
10
+ * errorCode we return the same bytes (captured from a live tenant, see
11
+ * apps/docs/api/error-codes.md), and where Auth0 omits `errorCode` we add one.
12
+ * Every added code is listed under "AuthHero extensions" in that doc page —
13
+ * keep the two in sync.
14
+ */
15
+ export declare const ERROR_TEXT_BY_STATUS: Record<number, string>;
16
+ export interface ManagementErrorBody {
17
+ statusCode: number;
18
+ error: string;
19
+ message: string;
20
+ errorCode?: string;
21
+ }
22
+ export declare function managementErrorBody(status: number, message: string, errorCode?: string): ManagementErrorBody;
23
+ export declare function managementError(status: ContentfulStatusCode, message: string, errorCode?: string): JSONHTTPException;
24
+ /**
25
+ * 404s per resource. Messages marked "auth0" are byte-identical to Auth0
26
+ * (including its inconsistent trailing periods); the rest are AuthHero
27
+ * resources or Auth0 resources without an errorCode, and follow the
28
+ * `The <resource> does not exist.` / `inexistent_<resource>` convention.
29
+ */
30
+ export declare const notFound: {
31
+ user: () => JSONHTTPException;
32
+ users: () => JSONHTTPException;
33
+ client: () => JSONHTTPException;
34
+ clientOnUpdate: () => JSONHTTPException;
35
+ connection: () => JSONHTTPException;
36
+ resourceServer: () => JSONHTTPException;
37
+ resourceServerByIdentifier: (identifier: string) => JSONHTTPException;
38
+ clientGrant: () => JSONHTTPException;
39
+ log: () => JSONHTTPException;
40
+ job: () => JSONHTTPException;
41
+ customDomain: (id: string) => JSONHTTPException;
42
+ key: (kid: string) => JSONHTTPException;
43
+ hook: () => JSONHTTPException;
44
+ enrollment: () => JSONHTTPException;
45
+ role: () => JSONHTTPException;
46
+ roleOnUpdate: () => JSONHTTPException;
47
+ organization: () => JSONHTTPException;
48
+ action: () => JSONHTTPException;
49
+ tenant: () => JSONHTTPException;
50
+ invitation: () => JSONHTTPException;
51
+ member: () => JSONHTTPException;
52
+ identity: () => JSONHTTPException;
53
+ session: () => JSONHTTPException;
54
+ refreshToken: () => JSONHTTPException;
55
+ grant: () => JSONHTTPException;
56
+ logStream: () => JSONHTTPException;
57
+ form: () => JSONHTTPException;
58
+ flow: () => JSONHTTPException;
59
+ emailTemplate: () => JSONHTTPException;
60
+ emailProvider: () => JSONHTTPException;
61
+ authenticationMethod: () => JSONHTTPException;
62
+ actionExecution: () => JSONHTTPException;
63
+ actionVersion: () => JSONHTTPException;
64
+ hookCode: () => JSONHTTPException;
65
+ failedEvent: () => JSONHTTPException;
66
+ migrationSource: () => JSONHTTPException;
67
+ proxyRoute: () => JSONHTTPException;
68
+ scimConfiguration: () => JSONHTTPException;
69
+ scimToken: () => JSONHTTPException;
70
+ tenantOperation: () => JSONHTTPException;
71
+ rollout: () => JSONHTTPException;
72
+ tokenExchangeProfile: () => JSONHTTPException;
73
+ };
74
+ /**
75
+ * 409s. `userExists`, `resourceServer` and `organizationName` are Auth0's
76
+ * bodies (the "identifer" typo is Auth0's, kept byte-identical); the
77
+ * organization errorCode is added.
78
+ */
79
+ export declare const conflict: {
80
+ userExists: () => JSONHTTPException;
81
+ resourceServer: (identifier: string) => JSONHTTPException;
82
+ organizationName: () => JSONHTTPException;
83
+ /** Any other AuthHero conflict: own message, shared code. */
84
+ other: (message: string) => JSONHTTPException;
85
+ };
86
+ export declare const authErrors: {
87
+ missingAuthentication: () => JSONHTTPException;
88
+ invalidToken: (message?: string) => JSONHTTPException;
89
+ insufficientScope: (expected: string[]) => JSONHTTPException;
90
+ };
91
+ /**
92
+ * Formats zod issues the way Auth0 does:
93
+ * `Payload validation error: 'Missing required property: name'.`, joined with
94
+ * ` (also) ` when there are several. Auth0 also appends each property's
95
+ * schema description, which we don't have at this layer.
96
+ */
97
+ export declare function formatValidationMessage(target: string, issues: unknown[], data: unknown): ManagementErrorBody;
98
+ /**
99
+ * `defaultHook` for every management-api OpenAPIHono app. The hook is the only
100
+ * place zod-openapi exposes which part of the request failed, which is what
101
+ * picks Auth0's invalid_body / invalid_query_string / invalid_uri code.
102
+ */
103
+ export declare function managementValidationHook(result: {
104
+ success: boolean;
105
+ target: string;
106
+ data?: unknown;
107
+ error?: unknown;
108
+ }, ctx: Context): (Response & import("hono").TypedResponse<{
109
+ statusCode: number;
110
+ error: string;
111
+ message: string;
112
+ errorCode?: string | undefined;
113
+ }, 400, "json">) | undefined;
@@ -4,3 +4,29 @@
4
4
  * Shared by `helpers/logging.ts` (write path) and
5
5
  * `outbox-destinations/logs.ts` (outbox transform) so the two never drift. */
6
6
  export declare const USER_TARGET_TYPES: Set<string>;
7
+ /** The flat log's `user_id` for an audit event: the target for user-scoped
8
+ * operations, otherwise the actor. The caller of a management operation is
9
+ * carried separately in `request.auth`. */
10
+ export declare function logSubjectUserId(event: {
11
+ actor: {
12
+ id?: string;
13
+ };
14
+ target?: {
15
+ type: string;
16
+ id: string;
17
+ };
18
+ }): string;
19
+ /** The flat log's `user_name` for an audit event. `actor.email` only names the
20
+ * actor, so it is used only when the log subject is the actor — a user-scoped
21
+ * operation by an admin must not pair the target's `user_id` with the admin's
22
+ * email. */
23
+ export declare function logSubjectUserName(event: {
24
+ actor: {
25
+ id?: string;
26
+ email?: string;
27
+ };
28
+ target?: {
29
+ type: string;
30
+ id: string;
31
+ };
32
+ }): string | undefined;
@@ -145,6 +145,13 @@ export declare const enrichedClientSchema: z.ZodObject<{
145
145
  tenant: z.ZodObject<{
146
146
  created_at: z.ZodPipe<z.ZodNullable<z.ZodString>, z.ZodTransform<string, string | null>>;
147
147
  updated_at: z.ZodPipe<z.ZodNullable<z.ZodString>, z.ZodTransform<string, string | null>>;
148
+ parent_tenant_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
149
+ config_sync: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
150
+ "inherit-on-read": "inherit-on-read";
151
+ synced: "synced";
152
+ }>>>;
153
+ config_sync_hash: z.ZodOptional<z.ZodNullable<z.ZodString>>;
154
+ config_synced_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
148
155
  audience: z.ZodOptional<z.ZodString>;
149
156
  friendly_name: z.ZodString;
150
157
  picture_url: z.ZodOptional<z.ZodString>;
@@ -352,6 +359,17 @@ export declare const enrichedClientSchema: z.ZodObject<{
352
359
  connections: z.ZodArray<z.ZodObject<{
353
360
  created_at: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
354
361
  updated_at: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
362
+ scope: z.ZodOptional<z.ZodEnum<{
363
+ local: "local";
364
+ shared: "shared";
365
+ platform: "platform";
366
+ }>>;
367
+ override: z.ZodOptional<z.ZodEnum<{
368
+ none: "none";
369
+ secrets: "secrets";
370
+ fields: "fields";
371
+ }>>;
372
+ enforce: z.ZodOptional<z.ZodBoolean>;
355
373
  id: z.ZodOptional<z.ZodString>;
356
374
  name: z.ZodString;
357
375
  display_name: z.ZodOptional<z.ZodString>;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * True when the caller's token comes from the control plane (or the deployment
3
+ * is single-tenant, which is effectively a control plane). Organization-scoped
4
+ * tokens are tenant-level credentials and do not count.
5
+ */
6
+ export declare function callerIsControlPlane(ctx: {
7
+ env: {
8
+ data: {
9
+ multiTenancyConfig?: {
10
+ controlPlaneTenantId?: string;
11
+ };
12
+ };
13
+ };
14
+ var: object;
15
+ }): boolean;
@@ -0,0 +1,27 @@
1
+ import { DataAdapters } from "@authhero/adapter-interfaces";
2
+ /**
3
+ * Hides `scope: "platform"` rows that a config sync delivered into a tenant
4
+ * from that tenant's own management API. Such rows must run (the code-hook
5
+ * executor reads them through other adapters) but their code and secrets are
6
+ * never shown, listed, edited or referenced by the tenant's admins.
7
+ *
8
+ * A row is hidden when it is platform-scoped **and** has a synced id. The
9
+ * control plane's own origin rows are platform-scoped too, but they are
10
+ * owned by the tenant that publishes them and stay visible there. Operators
11
+ * (control-plane credentials) see everything.
12
+ *
13
+ * A hidden row behaves as if it did not exist: `get` returns `null`, lists omit
14
+ * it, and writes against it are refused as not found. List totals and
15
+ * checkpoint cursors are not adjusted for hidden rows.
16
+ *
17
+ * Limit: this protects against the tenant's management API. The code and
18
+ * (encrypted) secrets are still stored in the tenant's database, so anyone
19
+ * with access to the database or the worker environment can read them.
20
+ */
21
+ export interface PlatformRowsOptions {
22
+ /** The tenant whose management API is being served. */
23
+ tenantId: string;
24
+ /** Control-plane credentials see platform rows. */
25
+ isOperator: boolean;
26
+ }
27
+ export declare function withPlatformRowsHidden(data: DataAdapters, options: PlatformRowsOptions): DataAdapters;
@@ -13,6 +13,18 @@ export declare function setRequestData(ctx: Context<{
13
13
  Bindings: Bindings;
14
14
  Variables: Variables;
15
15
  }>, data: DataAdapters): void;
16
+ /**
17
+ * The adapter stack code-hook and webhook execution reads.
18
+ *
19
+ * The management API hides platform-scoped rows that a config sync delivered
20
+ * from `ctx.var.data`, but hooks that run inline inside a management request
21
+ * (pre-registration, pre-deletion, ...) must still see and run them. Where no
22
+ * separate stack was installed this is the request's own stack.
23
+ */
24
+ export declare function getExecutorData(ctx: Context<{
25
+ Bindings: Bindings;
26
+ Variables: Variables;
27
+ }>): DataAdapters;
16
28
  /**
17
29
  * The raw adapter a route group composes its per-request stack on: the base
18
30
  * an earlier middleware installed on `ctx.var.baseData` (per-tenant database
@@ -14,9 +14,9 @@ export declare const USERINFO_RESERVED_CLAIMS: readonly ["iss", "sub", "aud", "e
14
14
  * vendor/tenant for downstream APIs while `sub` stays `auth-service`.
15
15
  * Client-bound mints keep `azp` locked (see below).
16
16
  */
17
- export declare const SERVICE_TOKEN_RESERVED_CLAIMS: ("sub" | "tenant_id" | "client_id" | "org_name" | "scope" | "permissions" | "org_id" | "sid" | "exp" | "iat" | "iss" | "aud" | "auth_time" | "acr" | "amr" | "nbf" | "jti" | "act" | "requested_userinfo_claims" | "gty")[];
17
+ export declare const SERVICE_TOKEN_RESERVED_CLAIMS: ("tenant_id" | "client_id" | "org_name" | "sub" | "scope" | "sid" | "permissions" | "jti" | "org_id" | "iat" | "exp" | "iss" | "aud" | "auth_time" | "acr" | "amr" | "gty" | "nbf" | "act" | "requested_userinfo_claims")[];
18
18
  /** Client-bound mints: `azp` must stay the registered client id. */
19
- export declare const CLIENT_SERVICE_TOKEN_RESERVED_CLAIMS: ("sub" | "tenant_id" | "client_id" | "org_name" | "scope" | "permissions" | "org_id" | "sid" | "exp" | "iat" | "iss" | "aud" | "auth_time" | "acr" | "amr" | "azp" | "nbf" | "jti" | "act" | "requested_userinfo_claims" | "gty")[];
19
+ export declare const CLIENT_SERVICE_TOKEN_RESERVED_CLAIMS: ("tenant_id" | "client_id" | "org_name" | "sub" | "scope" | "sid" | "permissions" | "jti" | "org_id" | "iat" | "exp" | "iss" | "aud" | "auth_time" | "acr" | "amr" | "azp" | "gty" | "nbf" | "act" | "requested_userinfo_claims")[];
20
20
  export type AccessTokenReservedClaim = (typeof ACCESS_TOKEN_RESERVED_CLAIMS)[number];
21
21
  export type IdTokenReservedClaim = (typeof ID_TOKEN_RESERVED_CLAIMS)[number];
22
22
  /**
@@ -0,0 +1 @@
1
+ export declare function isSyncedRowId(id: string | undefined | null): boolean;