authhero 8.5.0 → 8.7.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 (37) hide show
  1. package/dist/assets/u/widget/authhero-widget.esm.js +1 -1
  2. package/dist/assets/u/widget/{p-5f7b7943.entry.js → p-5a319adc.entry.js} +1 -1
  3. package/dist/authhero.cjs +257 -147
  4. package/dist/authhero.d.ts +412 -266
  5. package/dist/authhero.mjs +43118 -42718
  6. package/dist/stats.html +1 -1
  7. package/dist/tsconfig.types.tsbuildinfo +1 -1
  8. package/dist/types/authentication-flows/passwordless.d.ts +1 -1
  9. package/dist/types/index.d.ts +380 -266
  10. package/dist/types/routes/auth-api/account.d.ts +2 -2
  11. package/dist/types/routes/auth-api/index.d.ts +16 -16
  12. package/dist/types/routes/auth-api/passwordless.d.ts +8 -8
  13. package/dist/types/routes/auth-api/revoke.d.ts +6 -6
  14. package/dist/types/routes/management-api/action-executions.d.ts +1 -1
  15. package/dist/types/routes/management-api/actions.d.ts +1 -1
  16. package/dist/types/routes/management-api/branding-preview.d.ts +41 -0
  17. package/dist/types/routes/management-api/branding.d.ts +123 -9
  18. package/dist/types/routes/management-api/clients.d.ts +7 -7
  19. package/dist/types/routes/management-api/custom-domains.d.ts +8 -8
  20. package/dist/types/routes/management-api/email-templates.d.ts +18 -18
  21. package/dist/types/routes/management-api/failed-events.d.ts +1 -1
  22. package/dist/types/routes/management-api/flows.d.ts +7 -7
  23. package/dist/types/routes/management-api/guardian.d.ts +5 -5
  24. package/dist/types/routes/management-api/index.d.ts +336 -222
  25. package/dist/types/routes/management-api/logs.d.ts +3 -3
  26. package/dist/types/routes/management-api/migration-sources.d.ts +6 -6
  27. package/dist/types/routes/management-api/organizations.d.ts +1 -1
  28. package/dist/types/routes/management-api/prompts.d.ts +4 -4
  29. package/dist/types/routes/management-api/users.d.ts +2 -2
  30. package/dist/types/routes/universal-login/common.d.ts +2 -2
  31. package/dist/types/routes/universal-login/index.d.ts +2 -2
  32. package/dist/types/routes/universal-login/u2-index.d.ts +6 -6
  33. package/dist/types/routes/universal-login/u2-routes.d.ts +6 -6
  34. package/dist/types/routes/universal-login/u2-widget-page.d.ts +33 -4
  35. package/dist/types/routes/universal-login/universal-login-template.d.ts +65 -13
  36. package/dist/types/types/AuthHeroConfig.d.ts +33 -1
  37. package/package.json +4 -4
@@ -1,18 +1,17 @@
1
1
  /**
2
- * Universal Login Template — slot-based body markup.
2
+ * Universal Login Template — Liquid-based slot rendering.
3
3
  *
4
- * Tenants opt into custom chrome by uploading a body fragment that uses these
5
- * slot tokens. The default body (`DEFAULT_UNIVERSAL_LOGIN_TEMPLATE`) is
6
- * what's served when no custom template is stored, and is what tenants
7
- * should copy and edit.
4
+ * Tenants opt into custom chrome by uploading a body fragment. The fragment
5
+ * is rendered with Liquid (the same engine used for email templates), so it
6
+ * supports variables (`{{ branding.logo_url }}`), control flow
7
+ * (`{% if … %}`), and the AuthHero slot tags below.
8
8
  *
9
9
  * The page shell (`<!DOCTYPE>`, `<html>`, `<head>`, body styles, dark-mode
10
10
  * runtime, background tint) is fixed in code — it's not part of the tenant
11
- * template. This keeps tenants out of CSS/runtime authoring and limits
12
- * customization to layout: hide a chip by deleting its token, reorder by
13
- * moving them.
11
+ * template. The template only controls the body layout: which chips render,
12
+ * and any content placed in the in-flow regions around the widget.
14
13
  *
15
- * Slot tokens:
14
+ * Slot tags (rendered by the `auth0` / `authhero` custom tags):
16
15
  * `{%- auth0:widget -%}` — widget container (required)
17
16
  * `{%- authhero:logo -%}` — logo chip (top-left)
18
17
  * `{%- authhero:settings -%}` — settings chip (top-right), wraps the
@@ -21,15 +20,38 @@
21
20
  * `{%- authhero:language-picker -%}` — language picker only
22
21
  * `{%- authhero:powered-by -%}` — powered-by chip (bottom-left)
23
22
  * `{%- authhero:legal -%}` — legal/terms chip (bottom-right)
23
+ *
24
+ * In-flow regions above/below the widget are authored directly in the
25
+ * template using the `.ah-above-widget` / `.ah-below-widget` helper classes
26
+ * (see `DEFAULT_UNIVERSAL_LOGIN_TEMPLATE` for the stacked layout). They live
27
+ * in normal document flow, unlike the fixed-position corner chips, so they're
28
+ * plain markup the tenant writes rather than dedicated tags.
29
+ *
30
+ * Template variables exposed to Liquid:
31
+ * `branding` — the tenant Branding object (logo_url, colors, …)
32
+ * `theme` — the resolved Theme object
33
+ * `client.name` — the application name
34
+ * `prompt.screen.name` — the current screen id (Auth0-compatible)
35
+ * `locale` — the active language code
24
36
  */
37
+ import type { Branding, Theme } from "@authhero/adapter-interfaces";
25
38
  import { type DarkModePreference } from "./u2-widget-page";
39
+ /**
40
+ * Exact default-form widget token. Kept for the default template body and as
41
+ * a convenience export. Use {@link templateMountsWidget} for validation —
42
+ * it accepts every valid Liquid spelling of the widget tag, not just this one.
43
+ */
26
44
  export declare const REQUIRED_SLOT = "{%- auth0:widget -%}";
27
45
  /**
28
46
  * Canonical default body. Mirrors the layout the JSX `WidgetPage` emits.
29
47
  * Tenants who want to hide a chip should copy this, delete a slot, and PUT
30
48
  * it back via `PUT /api/v2/branding/templates/universal-login`.
49
+ *
50
+ * The widget is wrapped in a centered `.ah-widget-stack` so tenants can drop
51
+ * content into the `.ah-above-widget` / `.ah-below-widget` regions; both are
52
+ * empty (and collapse to nothing) by default.
31
53
  */
32
- export declare const DEFAULT_UNIVERSAL_LOGIN_TEMPLATE = "{%- auth0:widget -%}\n{%- authhero:logo -%}\n{%- authhero:settings -%}\n{%- authhero:powered-by -%}\n{%- authhero:legal -%}\n";
54
+ export declare const DEFAULT_UNIVERSAL_LOGIN_TEMPLATE = "<div class=\"ah-widget-stack\">\n <div class=\"ah-above-widget\" data-ah-slot=\"above-widget\"></div>\n {%- auth0:widget -%}\n <div class=\"ah-below-widget\" data-ah-slot=\"below-widget\"></div>\n</div>\n{%- authhero:logo -%}\n{%- authhero:settings -%}\n{%- authhero:powered-by -%}\n{%- authhero:legal -%}\n";
33
55
  export type TemplateSlotOptions = {
34
56
  widgetHtml: string;
35
57
  logoUrl?: string | null;
@@ -44,12 +66,42 @@ export type TemplateSlotOptions = {
44
66
  height?: number;
45
67
  };
46
68
  termsAndConditionsUrl?: string;
69
+ /** Full branding/theme objects, exposed to the template as Liquid variables. */
70
+ branding?: Branding | null;
71
+ theme?: Theme | null;
72
+ /**
73
+ * HTML emitted by the `{%- auth0:head -%}` slot. Only set on the
74
+ * full-document (Auth0-compatible) render path; in the body-fragment path
75
+ * the slot renders empty because the shell owns the `<head>`.
76
+ */
77
+ headHtml?: string;
78
+ };
79
+ /** True when `body` mounts the widget in any valid Liquid spelling. */
80
+ export declare function templateMountsWidget(body: string): boolean;
81
+ /**
82
+ * True when the template is a full HTML document (Auth0-style) rather than a
83
+ * body fragment. Full documents own their own `<html>`/`<head>`/`<body>` and
84
+ * are rendered as the whole page, with `{%- auth0:head -%}` injecting the head
85
+ * essentials. Body fragments are wrapped in AuthHero's fixed page shell.
86
+ */
87
+ export declare function templateIsFullDocument(body: string): boolean;
88
+ /**
89
+ * Validate a tenant template before storing it: it must mount the widget and
90
+ * must be syntactically valid Liquid (so a save can't break the login page).
91
+ */
92
+ export declare function validateUniversalLoginTemplate(body: string): {
93
+ valid: true;
94
+ } | {
95
+ valid: false;
96
+ error: string;
47
97
  };
48
98
  /**
49
- * Expand slot tokens in a template body. Unknown tokens are left in place
50
- * (so tenants can spot typos in their templates).
99
+ * Render a tenant template body to HTML, expanding slot tags and Liquid
100
+ * variables. Falls back to the known-good default template (and finally to
101
+ * the bare widget) if rendering throws, so a malformed template can never
102
+ * take the login page down.
51
103
  */
52
104
  export declare function applyUniversalLoginTemplate(template: string, opts: TemplateSlotOptions & {
53
105
  screenId: string;
54
106
  widgetContainerStyle?: string;
55
- }): string;
107
+ }): Promise<string>;
@@ -2,7 +2,7 @@ import { CodeExecutor, Connection, ConnectionInsert, CreateTenantParams, DataAda
2
2
  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
- import type { Handler } from "hono";
5
+ import type { Handler, MiddlewareHandler } from "hono";
6
6
  import type { ManagementAudienceResolver, IssuerResolver } from "../middlewares/authentication";
7
7
  import { EntityHooks } from "./Hooks";
8
8
  /**
@@ -327,6 +327,38 @@ export interface AuthHeroConfig {
327
327
  /** Per-request timeout for the sync POST (default: 10_000ms). */
328
328
  timeoutMs?: number;
329
329
  };
330
+ /**
331
+ * Optional middleware that dispatches a management-API request to its
332
+ * tenant's own worker instead of serving it from this (control-plane)
333
+ * instance — the inbound twin of the control-plane defaults projection.
334
+ *
335
+ * It is mounted inside the management API **after** the CORS middleware and
336
+ * **before** the auth/data chain, so:
337
+ * - when it forwards (returns the tenant worker's `Response`), the central
338
+ * CORS middleware applies the `Access-Control-Allow-*` headers to that
339
+ * response — no manual CORS handling needed in the host app;
340
+ * - when it calls `next()` (control-plane tenant, non-`wfp` tenant, tenant
341
+ * not yet provisioned, or no dispatch binding), the request is served
342
+ * locally as usual.
343
+ *
344
+ * Provide the implementation from `@authhero/cloudflare-adapter`'s
345
+ * `createWfpForwardMiddleware`, which dispatches over a Workers-for-Platforms
346
+ * dispatch namespace. Kept as a generic Hono `MiddlewareHandler` so authhero
347
+ * core carries no dispatch-namespace dependency.
348
+ *
349
+ * @example
350
+ * ```typescript
351
+ * const { app } = init({
352
+ * dataAdapter,
353
+ * allowedOrigins: ["https://admin.example.com"],
354
+ * tenantDispatch: createWfpForwardMiddleware({
355
+ * tenants: managementAdapter.tenants,
356
+ * controlPlaneTenantId: "main",
357
+ * }),
358
+ * });
359
+ * ```
360
+ */
361
+ tenantDispatch?: MiddlewareHandler;
330
362
  /**
331
363
  * Optional powered-by logo to display at the bottom left of the login widget.
332
364
  * This is only configurable in code, not stored in the database.
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.5.0",
14
+ "version": "8.7.0",
15
15
  "files": [
16
16
  "dist"
17
17
  ],
@@ -64,7 +64,7 @@
64
64
  "vite-plugin-dts": "^4.5.4",
65
65
  "vitest": "^4.1.7",
66
66
  "@authhero/kysely-adapter": "11.8.9",
67
- "@authhero/widget": "0.32.42"
67
+ "@authhero/widget": "0.33.0"
68
68
  },
69
69
  "dependencies": {
70
70
  "@peculiar/x509": "^1.14.0",
@@ -82,9 +82,9 @@
82
82
  "qrcode": "^1.5.4",
83
83
  "sanitize-html": "^2.17.4",
84
84
  "xstate": "^5.31.1",
85
- "@authhero/adapter-interfaces": "3.1.1",
86
85
  "@authhero/proxy": "0.7.1",
87
- "@authhero/saml": "0.4.2"
86
+ "@authhero/saml": "0.4.2",
87
+ "@authhero/adapter-interfaces": "3.1.1"
88
88
  },
89
89
  "peerDependencies": {
90
90
  "@authhero/widget": "^0.1.0",