authhero 8.6.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.
@@ -515,7 +515,7 @@ export default function create(config: AuthHeroConfig): OpenAPIHono<{
515
515
  } & {
516
516
  form: {
517
517
  username: string;
518
- login_selection?: "code" | "password" | undefined;
518
+ login_selection?: "password" | "code" | undefined;
519
519
  };
520
520
  };
521
521
  output: {};
@@ -529,7 +529,7 @@ export default function create(config: AuthHeroConfig): OpenAPIHono<{
529
529
  } & {
530
530
  form: {
531
531
  username: string;
532
- login_selection?: "code" | "password" | undefined;
532
+ login_selection?: "password" | "code" | undefined;
533
533
  };
534
534
  };
535
535
  output: {};
@@ -165,7 +165,7 @@ export default function createU2App(config: AuthHeroConfig): OpenAPIHono<{
165
165
  $get: {
166
166
  input: {
167
167
  param: {
168
- screen: "signup" | "login" | "reset-password" | "consent" | "account" | "enter-password" | "impersonate" | "try-connection-result" | "reset-password/request" | "reset-password/code" | "login/identifier" | "login/email-otp-challenge" | "login/sms-otp-challenge" | "login/login-passwordless-identifier" | "mfa/login-options" | "mfa/totp-challenge" | "mfa/totp-enrollment" | "mfa/phone-challenge" | "mfa/phone-enrollment" | "passkey/challenge" | "passkey/enrollment" | "passkey/enrollment-nudge" | "account/profile" | "account/security" | "account/security/totp-enrollment" | "account/security/phone-enrollment" | "account/linked" | "account/delete" | "account/passkeys" | "connect/start" | "connect/select-tenant";
168
+ screen: "login" | "signup" | "reset-password" | "consent" | "account" | "enter-password" | "impersonate" | "reset-password/request" | "reset-password/code" | "try-connection-result" | "login/identifier" | "login/email-otp-challenge" | "login/sms-otp-challenge" | "login/login-passwordless-identifier" | "mfa/login-options" | "mfa/totp-challenge" | "mfa/totp-enrollment" | "mfa/phone-challenge" | "mfa/phone-enrollment" | "passkey/challenge" | "passkey/enrollment" | "passkey/enrollment-nudge" | "account/profile" | "account/security" | "account/security/totp-enrollment" | "account/security/phone-enrollment" | "account/linked" | "account/delete" | "account/passkeys" | "connect/start" | "connect/select-tenant";
169
169
  };
170
170
  } & {
171
171
  query: {
@@ -181,7 +181,7 @@ export default function createU2App(config: AuthHeroConfig): OpenAPIHono<{
181
181
  } | {
182
182
  input: {
183
183
  param: {
184
- screen: "signup" | "login" | "reset-password" | "consent" | "account" | "enter-password" | "impersonate" | "try-connection-result" | "reset-password/request" | "reset-password/code" | "login/identifier" | "login/email-otp-challenge" | "login/sms-otp-challenge" | "login/login-passwordless-identifier" | "mfa/login-options" | "mfa/totp-challenge" | "mfa/totp-enrollment" | "mfa/phone-challenge" | "mfa/phone-enrollment" | "passkey/challenge" | "passkey/enrollment" | "passkey/enrollment-nudge" | "account/profile" | "account/security" | "account/security/totp-enrollment" | "account/security/phone-enrollment" | "account/linked" | "account/delete" | "account/passkeys" | "connect/start" | "connect/select-tenant";
184
+ screen: "login" | "signup" | "reset-password" | "consent" | "account" | "enter-password" | "impersonate" | "reset-password/request" | "reset-password/code" | "try-connection-result" | "login/identifier" | "login/email-otp-challenge" | "login/sms-otp-challenge" | "login/login-passwordless-identifier" | "mfa/login-options" | "mfa/totp-challenge" | "mfa/totp-enrollment" | "mfa/phone-challenge" | "mfa/phone-enrollment" | "passkey/challenge" | "passkey/enrollment" | "passkey/enrollment-nudge" | "account/profile" | "account/security" | "account/security/totp-enrollment" | "account/security/phone-enrollment" | "account/linked" | "account/delete" | "account/passkeys" | "connect/start" | "connect/select-tenant";
185
185
  };
186
186
  } & {
187
187
  query: {
@@ -197,7 +197,7 @@ export default function createU2App(config: AuthHeroConfig): OpenAPIHono<{
197
197
  } | {
198
198
  input: {
199
199
  param: {
200
- screen: "signup" | "login" | "reset-password" | "consent" | "account" | "enter-password" | "impersonate" | "try-connection-result" | "reset-password/request" | "reset-password/code" | "login/identifier" | "login/email-otp-challenge" | "login/sms-otp-challenge" | "login/login-passwordless-identifier" | "mfa/login-options" | "mfa/totp-challenge" | "mfa/totp-enrollment" | "mfa/phone-challenge" | "mfa/phone-enrollment" | "passkey/challenge" | "passkey/enrollment" | "passkey/enrollment-nudge" | "account/profile" | "account/security" | "account/security/totp-enrollment" | "account/security/phone-enrollment" | "account/linked" | "account/delete" | "account/passkeys" | "connect/start" | "connect/select-tenant";
200
+ screen: "login" | "signup" | "reset-password" | "consent" | "account" | "enter-password" | "impersonate" | "reset-password/request" | "reset-password/code" | "try-connection-result" | "login/identifier" | "login/email-otp-challenge" | "login/sms-otp-challenge" | "login/login-passwordless-identifier" | "mfa/login-options" | "mfa/totp-challenge" | "mfa/totp-enrollment" | "mfa/phone-challenge" | "mfa/phone-enrollment" | "passkey/challenge" | "passkey/enrollment" | "passkey/enrollment-nudge" | "account/profile" | "account/security" | "account/security/totp-enrollment" | "account/security/phone-enrollment" | "account/linked" | "account/delete" | "account/passkeys" | "connect/start" | "connect/select-tenant";
201
201
  };
202
202
  } & {
203
203
  query: {
@@ -217,7 +217,7 @@ export default function createU2App(config: AuthHeroConfig): OpenAPIHono<{
217
217
  $post: {
218
218
  input: {
219
219
  param: {
220
- screen: "signup" | "login" | "reset-password" | "consent" | "enter-password" | "impersonate" | "reset-password/request" | "reset-password/code" | "login/identifier" | "login/email-otp-challenge" | "login/sms-otp-challenge" | "login/login-passwordless-identifier" | "mfa/login-options" | "mfa/totp-challenge" | "mfa/totp-enrollment" | "mfa/phone-challenge" | "mfa/phone-enrollment" | "passkey/challenge" | "passkey/enrollment" | "passkey/enrollment-nudge" | "account/profile" | "account/security" | "account/security/totp-enrollment" | "account/security/phone-enrollment" | "account/linked" | "account/delete" | "account/passkeys" | "connect/start" | "connect/select-tenant";
220
+ screen: "login" | "signup" | "reset-password" | "consent" | "enter-password" | "impersonate" | "reset-password/request" | "reset-password/code" | "login/identifier" | "login/email-otp-challenge" | "login/sms-otp-challenge" | "login/login-passwordless-identifier" | "mfa/login-options" | "mfa/totp-challenge" | "mfa/totp-enrollment" | "mfa/phone-challenge" | "mfa/phone-enrollment" | "passkey/challenge" | "passkey/enrollment" | "passkey/enrollment-nudge" | "account/profile" | "account/security" | "account/security/totp-enrollment" | "account/security/phone-enrollment" | "account/linked" | "account/delete" | "account/passkeys" | "connect/start" | "connect/select-tenant";
221
221
  };
222
222
  } & {
223
223
  query: {
@@ -235,7 +235,7 @@ export default function createU2App(config: AuthHeroConfig): OpenAPIHono<{
235
235
  } | {
236
236
  input: {
237
237
  param: {
238
- screen: "signup" | "login" | "reset-password" | "consent" | "enter-password" | "impersonate" | "reset-password/request" | "reset-password/code" | "login/identifier" | "login/email-otp-challenge" | "login/sms-otp-challenge" | "login/login-passwordless-identifier" | "mfa/login-options" | "mfa/totp-challenge" | "mfa/totp-enrollment" | "mfa/phone-challenge" | "mfa/phone-enrollment" | "passkey/challenge" | "passkey/enrollment" | "passkey/enrollment-nudge" | "account/profile" | "account/security" | "account/security/totp-enrollment" | "account/security/phone-enrollment" | "account/linked" | "account/delete" | "account/passkeys" | "connect/start" | "connect/select-tenant";
238
+ screen: "login" | "signup" | "reset-password" | "consent" | "enter-password" | "impersonate" | "reset-password/request" | "reset-password/code" | "login/identifier" | "login/email-otp-challenge" | "login/sms-otp-challenge" | "login/login-passwordless-identifier" | "mfa/login-options" | "mfa/totp-challenge" | "mfa/totp-enrollment" | "mfa/phone-challenge" | "mfa/phone-enrollment" | "passkey/challenge" | "passkey/enrollment" | "passkey/enrollment-nudge" | "account/profile" | "account/security" | "account/security/totp-enrollment" | "account/security/phone-enrollment" | "account/linked" | "account/delete" | "account/passkeys" | "connect/start" | "connect/select-tenant";
239
239
  };
240
240
  } & {
241
241
  query: {
@@ -253,7 +253,7 @@ export default function createU2App(config: AuthHeroConfig): OpenAPIHono<{
253
253
  } | {
254
254
  input: {
255
255
  param: {
256
- screen: "signup" | "login" | "reset-password" | "consent" | "enter-password" | "impersonate" | "reset-password/request" | "reset-password/code" | "login/identifier" | "login/email-otp-challenge" | "login/sms-otp-challenge" | "login/login-passwordless-identifier" | "mfa/login-options" | "mfa/totp-challenge" | "mfa/totp-enrollment" | "mfa/phone-challenge" | "mfa/phone-enrollment" | "passkey/challenge" | "passkey/enrollment" | "passkey/enrollment-nudge" | "account/profile" | "account/security" | "account/security/totp-enrollment" | "account/security/phone-enrollment" | "account/linked" | "account/delete" | "account/passkeys" | "connect/start" | "connect/select-tenant";
256
+ screen: "login" | "signup" | "reset-password" | "consent" | "enter-password" | "impersonate" | "reset-password/request" | "reset-password/code" | "login/identifier" | "login/email-otp-challenge" | "login/sms-otp-challenge" | "login/login-passwordless-identifier" | "mfa/login-options" | "mfa/totp-challenge" | "mfa/totp-enrollment" | "mfa/phone-challenge" | "mfa/phone-enrollment" | "passkey/challenge" | "passkey/enrollment" | "passkey/enrollment-nudge" | "account/profile" | "account/security" | "account/security/totp-enrollment" | "account/security/phone-enrollment" | "account/linked" | "account/delete" | "account/passkeys" | "connect/start" | "connect/select-tenant";
257
257
  };
258
258
  } & {
259
259
  query: {
@@ -170,7 +170,7 @@ export declare const u2Routes: OpenAPIHono<{
170
170
  $get: {
171
171
  input: {
172
172
  param: {
173
- screen: "signup" | "login" | "reset-password" | "consent" | "account" | "enter-password" | "impersonate" | "try-connection-result" | "reset-password/request" | "reset-password/code" | "login/identifier" | "login/email-otp-challenge" | "login/sms-otp-challenge" | "login/login-passwordless-identifier" | "mfa/login-options" | "mfa/totp-challenge" | "mfa/totp-enrollment" | "mfa/phone-challenge" | "mfa/phone-enrollment" | "passkey/challenge" | "passkey/enrollment" | "passkey/enrollment-nudge" | "account/profile" | "account/security" | "account/security/totp-enrollment" | "account/security/phone-enrollment" | "account/linked" | "account/delete" | "account/passkeys" | "connect/start" | "connect/select-tenant";
173
+ screen: "login" | "signup" | "reset-password" | "consent" | "account" | "enter-password" | "impersonate" | "reset-password/request" | "reset-password/code" | "try-connection-result" | "login/identifier" | "login/email-otp-challenge" | "login/sms-otp-challenge" | "login/login-passwordless-identifier" | "mfa/login-options" | "mfa/totp-challenge" | "mfa/totp-enrollment" | "mfa/phone-challenge" | "mfa/phone-enrollment" | "passkey/challenge" | "passkey/enrollment" | "passkey/enrollment-nudge" | "account/profile" | "account/security" | "account/security/totp-enrollment" | "account/security/phone-enrollment" | "account/linked" | "account/delete" | "account/passkeys" | "connect/start" | "connect/select-tenant";
174
174
  };
175
175
  } & {
176
176
  query: {
@@ -186,7 +186,7 @@ export declare const u2Routes: OpenAPIHono<{
186
186
  } | {
187
187
  input: {
188
188
  param: {
189
- screen: "signup" | "login" | "reset-password" | "consent" | "account" | "enter-password" | "impersonate" | "try-connection-result" | "reset-password/request" | "reset-password/code" | "login/identifier" | "login/email-otp-challenge" | "login/sms-otp-challenge" | "login/login-passwordless-identifier" | "mfa/login-options" | "mfa/totp-challenge" | "mfa/totp-enrollment" | "mfa/phone-challenge" | "mfa/phone-enrollment" | "passkey/challenge" | "passkey/enrollment" | "passkey/enrollment-nudge" | "account/profile" | "account/security" | "account/security/totp-enrollment" | "account/security/phone-enrollment" | "account/linked" | "account/delete" | "account/passkeys" | "connect/start" | "connect/select-tenant";
189
+ screen: "login" | "signup" | "reset-password" | "consent" | "account" | "enter-password" | "impersonate" | "reset-password/request" | "reset-password/code" | "try-connection-result" | "login/identifier" | "login/email-otp-challenge" | "login/sms-otp-challenge" | "login/login-passwordless-identifier" | "mfa/login-options" | "mfa/totp-challenge" | "mfa/totp-enrollment" | "mfa/phone-challenge" | "mfa/phone-enrollment" | "passkey/challenge" | "passkey/enrollment" | "passkey/enrollment-nudge" | "account/profile" | "account/security" | "account/security/totp-enrollment" | "account/security/phone-enrollment" | "account/linked" | "account/delete" | "account/passkeys" | "connect/start" | "connect/select-tenant";
190
190
  };
191
191
  } & {
192
192
  query: {
@@ -202,7 +202,7 @@ export declare const u2Routes: OpenAPIHono<{
202
202
  } | {
203
203
  input: {
204
204
  param: {
205
- screen: "signup" | "login" | "reset-password" | "consent" | "account" | "enter-password" | "impersonate" | "try-connection-result" | "reset-password/request" | "reset-password/code" | "login/identifier" | "login/email-otp-challenge" | "login/sms-otp-challenge" | "login/login-passwordless-identifier" | "mfa/login-options" | "mfa/totp-challenge" | "mfa/totp-enrollment" | "mfa/phone-challenge" | "mfa/phone-enrollment" | "passkey/challenge" | "passkey/enrollment" | "passkey/enrollment-nudge" | "account/profile" | "account/security" | "account/security/totp-enrollment" | "account/security/phone-enrollment" | "account/linked" | "account/delete" | "account/passkeys" | "connect/start" | "connect/select-tenant";
205
+ screen: "login" | "signup" | "reset-password" | "consent" | "account" | "enter-password" | "impersonate" | "reset-password/request" | "reset-password/code" | "try-connection-result" | "login/identifier" | "login/email-otp-challenge" | "login/sms-otp-challenge" | "login/login-passwordless-identifier" | "mfa/login-options" | "mfa/totp-challenge" | "mfa/totp-enrollment" | "mfa/phone-challenge" | "mfa/phone-enrollment" | "passkey/challenge" | "passkey/enrollment" | "passkey/enrollment-nudge" | "account/profile" | "account/security" | "account/security/totp-enrollment" | "account/security/phone-enrollment" | "account/linked" | "account/delete" | "account/passkeys" | "connect/start" | "connect/select-tenant";
206
206
  };
207
207
  } & {
208
208
  query: {
@@ -222,7 +222,7 @@ export declare const u2Routes: OpenAPIHono<{
222
222
  $post: {
223
223
  input: {
224
224
  param: {
225
- screen: "signup" | "login" | "reset-password" | "consent" | "enter-password" | "impersonate" | "reset-password/request" | "reset-password/code" | "login/identifier" | "login/email-otp-challenge" | "login/sms-otp-challenge" | "login/login-passwordless-identifier" | "mfa/login-options" | "mfa/totp-challenge" | "mfa/totp-enrollment" | "mfa/phone-challenge" | "mfa/phone-enrollment" | "passkey/challenge" | "passkey/enrollment" | "passkey/enrollment-nudge" | "account/profile" | "account/security" | "account/security/totp-enrollment" | "account/security/phone-enrollment" | "account/linked" | "account/delete" | "account/passkeys" | "connect/start" | "connect/select-tenant";
225
+ screen: "login" | "signup" | "reset-password" | "consent" | "enter-password" | "impersonate" | "reset-password/request" | "reset-password/code" | "login/identifier" | "login/email-otp-challenge" | "login/sms-otp-challenge" | "login/login-passwordless-identifier" | "mfa/login-options" | "mfa/totp-challenge" | "mfa/totp-enrollment" | "mfa/phone-challenge" | "mfa/phone-enrollment" | "passkey/challenge" | "passkey/enrollment" | "passkey/enrollment-nudge" | "account/profile" | "account/security" | "account/security/totp-enrollment" | "account/security/phone-enrollment" | "account/linked" | "account/delete" | "account/passkeys" | "connect/start" | "connect/select-tenant";
226
226
  };
227
227
  } & {
228
228
  query: {
@@ -240,7 +240,7 @@ export declare const u2Routes: OpenAPIHono<{
240
240
  } | {
241
241
  input: {
242
242
  param: {
243
- screen: "signup" | "login" | "reset-password" | "consent" | "enter-password" | "impersonate" | "reset-password/request" | "reset-password/code" | "login/identifier" | "login/email-otp-challenge" | "login/sms-otp-challenge" | "login/login-passwordless-identifier" | "mfa/login-options" | "mfa/totp-challenge" | "mfa/totp-enrollment" | "mfa/phone-challenge" | "mfa/phone-enrollment" | "passkey/challenge" | "passkey/enrollment" | "passkey/enrollment-nudge" | "account/profile" | "account/security" | "account/security/totp-enrollment" | "account/security/phone-enrollment" | "account/linked" | "account/delete" | "account/passkeys" | "connect/start" | "connect/select-tenant";
243
+ screen: "login" | "signup" | "reset-password" | "consent" | "enter-password" | "impersonate" | "reset-password/request" | "reset-password/code" | "login/identifier" | "login/email-otp-challenge" | "login/sms-otp-challenge" | "login/login-passwordless-identifier" | "mfa/login-options" | "mfa/totp-challenge" | "mfa/totp-enrollment" | "mfa/phone-challenge" | "mfa/phone-enrollment" | "passkey/challenge" | "passkey/enrollment" | "passkey/enrollment-nudge" | "account/profile" | "account/security" | "account/security/totp-enrollment" | "account/security/phone-enrollment" | "account/linked" | "account/delete" | "account/passkeys" | "connect/start" | "connect/select-tenant";
244
244
  };
245
245
  } & {
246
246
  query: {
@@ -258,7 +258,7 @@ export declare const u2Routes: OpenAPIHono<{
258
258
  } | {
259
259
  input: {
260
260
  param: {
261
- screen: "signup" | "login" | "reset-password" | "consent" | "enter-password" | "impersonate" | "reset-password/request" | "reset-password/code" | "login/identifier" | "login/email-otp-challenge" | "login/sms-otp-challenge" | "login/login-passwordless-identifier" | "mfa/login-options" | "mfa/totp-challenge" | "mfa/totp-enrollment" | "mfa/phone-challenge" | "mfa/phone-enrollment" | "passkey/challenge" | "passkey/enrollment" | "passkey/enrollment-nudge" | "account/profile" | "account/security" | "account/security/totp-enrollment" | "account/security/phone-enrollment" | "account/linked" | "account/delete" | "account/passkeys" | "connect/start" | "connect/select-tenant";
261
+ screen: "login" | "signup" | "reset-password" | "consent" | "enter-password" | "impersonate" | "reset-password/request" | "reset-password/code" | "login/identifier" | "login/email-otp-challenge" | "login/sms-otp-challenge" | "login/login-passwordless-identifier" | "mfa/login-options" | "mfa/totp-challenge" | "mfa/totp-enrollment" | "mfa/phone-challenge" | "mfa/phone-enrollment" | "passkey/challenge" | "passkey/enrollment" | "passkey/enrollment-nudge" | "account/profile" | "account/security" | "account/security/totp-enrollment" | "account/security/phone-enrollment" | "account/linked" | "account/delete" | "account/passkeys" | "connect/start" | "connect/select-tenant";
262
262
  };
263
263
  } & {
264
264
  query: {
@@ -102,9 +102,20 @@ export type WidgetPageProps = {
102
102
  */
103
103
  customBodyHtml?: string;
104
104
  };
105
- export declare function LogoChip({ logoUrl, clientName, }: {
105
+ /**
106
+ * How a corner chip renders its surface.
107
+ * - "auto" (default): pill when there's a background image, plain text on a
108
+ * solid background — driven by the page-level `data-bg` attribute.
109
+ * - "plain": always text-only, regardless of background.
110
+ * - "pill": always a translucent pill, regardless of background.
111
+ *
112
+ * Templates choose this per slot via `{%- authhero:legal style="plain" -%}`.
113
+ */
114
+ export type ChipStyle = "auto" | "plain" | "pill";
115
+ export declare function LogoChip({ logoUrl, clientName, variant, }: {
106
116
  logoUrl?: string | null;
107
117
  clientName: string;
118
+ variant?: ChipStyle;
108
119
  }): import("hono/jsx/jsx-dev-runtime").JSX.Element;
109
120
  export declare function DarkModeToggle({ darkMode }: {
110
121
  darkMode: DarkModePreference;
@@ -113,21 +124,39 @@ export declare function LanguagePicker({ language, availableLanguages, }: {
113
124
  language?: string;
114
125
  availableLanguages: string[];
115
126
  }): import("hono/jsx/jsx-dev-runtime").JSX.Element | null;
116
- export declare function SettingsChip({ darkMode, language, availableLanguages, }: {
127
+ export declare function SettingsChip({ darkMode, language, availableLanguages, variant, }: {
117
128
  darkMode: DarkModePreference;
118
129
  language?: string;
119
130
  availableLanguages?: string[];
131
+ variant?: ChipStyle;
120
132
  }): import("hono/jsx/jsx-dev-runtime").JSX.Element;
121
- export declare function PoweredByChip({ url, href, alt, height, }: {
133
+ export declare function PoweredByChip({ url, href, alt, height, variant, }: {
122
134
  url: string;
123
135
  href?: string;
124
136
  alt?: string;
125
137
  height?: number;
138
+ variant?: ChipStyle;
126
139
  }): import("hono/jsx/jsx-dev-runtime").JSX.Element | null;
127
- export declare function LegalChip({ termsAndConditionsUrl, language, }: {
140
+ export declare function LegalChip({ termsAndConditionsUrl, language, variant, }: {
128
141
  termsAndConditionsUrl?: string;
129
142
  language?: string;
143
+ variant?: ChipStyle;
130
144
  }): import("hono/jsx/jsx-dev-runtime").JSX.Element | null;
145
+ /**
146
+ * The functional `<head>` contents the page shell injects, as an HTML string.
147
+ *
148
+ * This is what the `{%- auth0:head -%}` slot emits when a tenant uploads a
149
+ * full-document (Auth0-style) template. It carries only the essentials the
150
+ * widget needs to render and theme — the page CSS, fonts, favicon, the widget
151
+ * script, and the dark-mode runtime. Unlike the default body-fragment path,
152
+ * a full-document template owns its own layout/CSS, so the curated chip chrome
153
+ * is not forced on it (the `authhero:*` chip slots remain available if wanted).
154
+ */
155
+ export declare function buildHeadEssentials(opts: {
156
+ clientName: string;
157
+ branding?: WidgetPageProps["branding"];
158
+ theme?: any;
159
+ }): string;
131
160
  export declare function WidgetPage({ widgetHtml, screenId, branding, theme, themePageBackground, clientName, poweredByLogo, language, availableLanguages, termsAndConditionsUrl, darkMode, logoPosition, extraScript, customBodyHtml, }: WidgetPageProps): import("hono/jsx/jsx-dev-runtime").JSX.Element;
132
161
  /**
133
162
  * Reads `theme.page_background.logo_placement` and returns the resolved
@@ -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>;
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.6.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",
85
+ "@authhero/proxy": "0.7.1",
86
86
  "@authhero/saml": "0.4.2",
87
- "@authhero/proxy": "0.7.1"
87
+ "@authhero/adapter-interfaces": "3.1.1"
88
88
  },
89
89
  "peerDependencies": {
90
90
  "@authhero/widget": "^0.1.0",