authhero 8.2.1 → 8.4.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 (48) hide show
  1. package/dist/assets/u/js/client.js +3 -3
  2. package/dist/authhero.cjs +105 -105
  3. package/dist/authhero.d.ts +349 -238
  4. package/dist/authhero.mjs +6422 -6355
  5. package/dist/client.js +3 -3
  6. package/dist/stats.html +1 -1
  7. package/dist/tsconfig.types.tsbuildinfo +1 -1
  8. package/dist/types/adapters/createEncryptedDataAdapter.d.ts +40 -0
  9. package/dist/types/adapters/index.d.ts +4 -2
  10. package/dist/types/authentication-flows/passwordless.d.ts +3 -3
  11. package/dist/types/client/client-bundle.d.ts +1 -1
  12. package/dist/types/client/loading-link-handler.d.ts +14 -0
  13. package/dist/types/components/Button.d.ts +2 -1
  14. package/dist/types/helpers/dcr/metadata-mapping.d.ts +1 -1
  15. package/dist/types/index.d.ts +218 -218
  16. package/dist/types/middlewares/authentication.d.ts +17 -0
  17. package/dist/types/routes/auth-api/index.d.ts +21 -21
  18. package/dist/types/routes/auth-api/passwordless.d.ts +18 -18
  19. package/dist/types/routes/auth-api/register/index.d.ts +2 -2
  20. package/dist/types/routes/auth-api/well-known.d.ts +1 -1
  21. package/dist/types/routes/management-api/action-executions.d.ts +1 -1
  22. package/dist/types/routes/management-api/actions.d.ts +1 -1
  23. package/dist/types/routes/management-api/authentication-methods.d.ts +1 -1
  24. package/dist/types/routes/management-api/branding.d.ts +6 -6
  25. package/dist/types/routes/management-api/client-grants.d.ts +8 -8
  26. package/dist/types/routes/management-api/clients.d.ts +7 -7
  27. package/dist/types/routes/management-api/connections.d.ts +1 -1
  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/forms.d.ts +119 -119
  31. package/dist/types/routes/management-api/guardian.d.ts +5 -5
  32. package/dist/types/routes/management-api/index.d.ts +190 -190
  33. package/dist/types/routes/management-api/log-streams.d.ts +6 -6
  34. package/dist/types/routes/management-api/logs.d.ts +3 -3
  35. package/dist/types/routes/management-api/organizations.d.ts +2 -2
  36. package/dist/types/routes/management-api/prompts.d.ts +4 -4
  37. package/dist/types/routes/management-api/themes.d.ts +3 -3
  38. package/dist/types/routes/management-api/users.d.ts +2 -2
  39. package/dist/types/routes/universal-login/common.d.ts +6 -6
  40. package/dist/types/routes/universal-login/flow-api.d.ts +12 -12
  41. package/dist/types/routes/universal-login/u2-index.d.ts +6 -6
  42. package/dist/types/routes/universal-login/u2-routes.d.ts +6 -6
  43. package/dist/types/types/AuthHeroConfig.d.ts +26 -1
  44. package/dist/types/types/IdToken.d.ts +2 -2
  45. package/dist/types/utils/field-encryption.d.ts +30 -0
  46. package/dist/types/utils/jwks.d.ts +2 -2
  47. package/dist/types/utils/jwt.d.ts +9 -0
  48. package/package.json +5 -5
@@ -3,7 +3,7 @@ import type { RolePermissionHooks, Hooks } from "./Hooks";
3
3
  import type { SamlSigner } from "@authhero/saml/core";
4
4
  import type { OpenAPIHono } from "@hono/zod-openapi";
5
5
  import type { Handler } from "hono";
6
- import type { ManagementAudienceResolver } from "../middlewares/authentication";
6
+ import type { ManagementAudienceResolver, IssuerResolver } from "../middlewares/authentication";
7
7
  import { EntityHooks } from "./Hooks";
8
8
  /**
9
9
  * Parameters passed to a custom webhook invoker function.
@@ -495,4 +495,29 @@ export interface AuthHeroConfig {
495
495
  * ```
496
496
  */
497
497
  additionalManagementAudiences?: ManagementAudienceResolver;
498
+ /**
499
+ * Resolver returning the list of issuers accepted by the bearer-JWT issuer
500
+ * check **in addition to** the deployment's own
501
+ * `getIssuer(env, custom_domain)`. The token's `tenant_id` is passed in, so a
502
+ * per-tenant or control-plane issuer can be constructed at request time.
503
+ *
504
+ * This is needed when control-plane-minted admin tokens are forwarded to a
505
+ * per-tenant worker: the token's `iss` is the control-plane issuer while the
506
+ * worker's `env.ISSUER` is per-tenant, so the strict single-issuer check
507
+ * would otherwise reject it. The signature is still verified normally; this
508
+ * only widens which `iss` values are accepted.
509
+ *
510
+ * authhero stays generic — it never derives or hardcodes any issuer. Scoping
511
+ * (e.g. only accepting the control-plane issuer for control-plane tokens) is
512
+ * the host app's job: the resolver receives `tenant_id` and can return `[]`
513
+ * to refuse. The default issuer is always accepted; the resolver is purely
514
+ * additive.
515
+ *
516
+ * @example
517
+ * ```ts
518
+ * additionalIssuers: ({ tenant_id }) =>
519
+ * tenant_id ? ["https://token.example.com/"] : [];
520
+ * ```
521
+ */
522
+ additionalIssuers?: IssuerResolver;
498
523
  }
@@ -19,10 +19,10 @@ export declare const idTokenSchema: z.ZodObject<{
19
19
  }, z.core.$loose>;
20
20
  export declare const userInfoSchema: z.ZodObject<{
21
21
  name: z.ZodOptional<z.ZodString>;
22
- given_name: z.ZodOptional<z.ZodString>;
23
- family_name: z.ZodOptional<z.ZodString>;
24
22
  email: z.ZodOptional<z.ZodString>;
25
23
  sub: z.ZodString;
24
+ given_name: z.ZodOptional<z.ZodString>;
25
+ family_name: z.ZodOptional<z.ZodString>;
26
26
  iss: z.ZodString;
27
27
  aud: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>;
28
28
  exp: z.ZodNumber;
@@ -1,6 +1,24 @@
1
1
  declare const PREFIX = "enc:v1:";
2
2
  export type EncryptedField = `${typeof PREFIX}${string}`;
3
3
  export declare function isEncrypted(value: string): value is EncryptedField;
4
+ /**
5
+ * A set of AES-256-GCM keys addressable by id. `default` decrypts (and by
6
+ * default encrypts) legacy unkeyed `enc:v1:` values; `keys[id]` handles values
7
+ * tagged with that id (`enc:v1:<id>:`).
8
+ *
9
+ * This is what lets a single database hold ciphertext under more than one key —
10
+ * e.g. a WFP tenant's own secrets under the tenant key and inherited control
11
+ * plane secrets under a control-plane-only key the tenant operator never holds.
12
+ */
13
+ export interface KeyRing {
14
+ default: CryptoKey;
15
+ keys?: Record<string, CryptoKey>;
16
+ }
17
+ /**
18
+ * The key id a keyed value was encrypted under, or `undefined` for a legacy
19
+ * unkeyed value (or a non-encrypted plaintext).
20
+ */
21
+ export declare function parseKeyId(value: string): string | undefined;
4
22
  /**
5
23
  * Imports a base64-encoded 32-byte key as an AES-256-GCM CryptoKey. Throws if
6
24
  * the decoded key is not exactly 32 bytes so a misconfigured secret fails loudly
@@ -18,4 +36,16 @@ export declare function encryptField(plaintext: string, key: CryptoKey): Promise
18
36
  * prefixed value cannot be decrypted (wrong key or corrupted ciphertext).
19
37
  */
20
38
  export declare function decryptField(value: string, key: CryptoKey): Promise<string>;
39
+ /**
40
+ * Encrypts a value using a key ring, optionally tagging it with `keyId` so the
41
+ * same key is selected on read. With no `keyId` the value is encrypted under the
42
+ * ring's default key and is byte-compatible with `encryptField` (legacy form).
43
+ */
44
+ export declare function encryptFieldWithRing(plaintext: string, ring: KeyRing, keyId?: string): Promise<EncryptedField>;
45
+ /**
46
+ * Decrypts a value using a key ring, selecting the key from the id embedded in
47
+ * the ciphertext (or the default key for legacy unkeyed values). Plaintext
48
+ * values (no `enc:v1:` prefix) are returned unchanged.
49
+ */
50
+ export declare function decryptFieldWithRing(value: string, ring: KeyRing): Promise<string>;
21
51
  export {};
@@ -8,7 +8,7 @@ import { SigningKeyModeOption } from "../types/AuthHeroConfig";
8
8
  */
9
9
  export declare function getJwksForPublication(data: DataAdapters, tenantId: string, modeOption: SigningKeyModeOption | undefined): Promise<{
10
10
  alg: "RS256" | "RS384" | "RS512" | "ES256" | "ES384" | "ES512" | "HS256" | "HS384" | "HS512";
11
- kty: "EC" | "RSA" | "oct";
11
+ kty: "RSA" | "EC" | "oct";
12
12
  kid?: string | undefined;
13
13
  use?: "sig" | "enc" | undefined;
14
14
  n?: string | undefined;
@@ -27,7 +27,7 @@ export declare function getJwksForPublication(data: DataAdapters, tenantId: stri
27
27
  */
28
28
  export declare function getJwksForVerification(data: DataAdapters, tenantId: string | undefined, modeOption: SigningKeyModeOption | undefined): Promise<{
29
29
  alg: "RS256" | "RS384" | "RS512" | "ES256" | "ES384" | "ES512" | "HS256" | "HS384" | "HS512";
30
- kty: "EC" | "RSA" | "oct";
30
+ kty: "RSA" | "EC" | "oct";
31
31
  kid?: string | undefined;
32
32
  use?: "sig" | "enc" | undefined;
33
33
  n?: string | undefined;
@@ -25,6 +25,15 @@ export interface ValidateJwtTokenOptions {
25
25
  * for iss mismatch rather than the 401 this function would raise.
26
26
  */
27
27
  skipIssuerCheck?: boolean;
28
+ /**
29
+ * Additional issuers accepted **in addition to**
30
+ * `getIssuer(env, custom_domain)`. A token whose `iss` matches the expected
31
+ * issuer OR any value in this list passes the issuer check. The host app
32
+ * resolves this list (e.g. from a control-plane issuer) and threads it in;
33
+ * authhero never derives or hardcodes any issuer itself. Defaults to the
34
+ * strict single-issuer check when omitted.
35
+ */
36
+ additionalIssuers?: string[];
28
37
  }
29
38
  /**
30
39
  * Raised when the subject JWT carried a past `exp`. Extends JSONHTTPException
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "type": "git",
12
12
  "url": "https://github.com/markusahlstrand/authhero"
13
13
  },
14
- "version": "8.2.1",
14
+ "version": "8.4.0",
15
15
  "files": [
16
16
  "dist"
17
17
  ],
@@ -63,8 +63,8 @@
63
63
  "vite": "^8.0.14",
64
64
  "vite-plugin-dts": "^4.5.4",
65
65
  "vitest": "^4.1.7",
66
- "@authhero/kysely-adapter": "11.8.9",
67
- "@authhero/widget": "0.32.41"
66
+ "@authhero/widget": "0.32.41",
67
+ "@authhero/kysely-adapter": "11.8.9"
68
68
  },
69
69
  "dependencies": {
70
70
  "@peculiar/x509": "^1.14.0",
@@ -83,8 +83,8 @@
83
83
  "sanitize-html": "^2.17.4",
84
84
  "xstate": "^5.31.1",
85
85
  "@authhero/adapter-interfaces": "3.1.1",
86
- "@authhero/saml": "0.4.2",
87
- "@authhero/proxy": "0.7.1"
86
+ "@authhero/proxy": "0.7.1",
87
+ "@authhero/saml": "0.4.2"
88
88
  },
89
89
  "peerDependencies": {
90
90
  "@authhero/widget": "^0.1.0",