# `hb-auth`

**Category:** auth · **Tags:** auth · **Package:** `@htmlbricks/hb-auth`

## Summary

`hb-auth` is a self-contained authentication card for the shadow DOM. It switches between **login**, **register**, **forgot password**, **mail recovery info**, **account activation**, and **password recovery** flows based on the `type` property. It can call optional HTTP endpoints for login and registration, persist session payloads under a configurable storage key, embed **OAuth2** providers via `hb-auth-social-login-button`, and emit **custom events** so the host app can handle credentials, recovery, and OAuth steps. Strings are **internationalized** (Italian and English) when `i18nlang` is set.

## What it does

- **Local auth UI:** email and password fields (with optional HTML `pattern` via `passwordpattern`), “remember me” on login, full-width primary actions, and ghost links to switch modes (register / login / forgot password) according to `disableregister`, `enable_recover_password`, and the active `type`.
- **Server-assisted login/register:** If `loginuri` or `registeruri` is set, the component performs `fetch` with `requestmethod` (default `POST`, normalized to uppercase). **POST** sends JSON (`email`, `password`, and `rememberMe` for login). **GET** omits a body. Optional `appendbodyparams` must be a **JSON object string** merged into the body. On success, the JSON response is stored in **localStorage** (when “remember me” is checked) or **sessionStorage** under `sessionkey` (default `_auth`), then `redirectonlogin` / `redirectoncreate` may run as a full navigation. The **`login`** or **`register`** event is dispatched with the server payload (or a minimal local payload if no URI is configured).
- **Recovery / activation:** For `type` `activate` or `recover`, the user enters recovery code, email, new password, and repeat password; submitting dispatches **`recoverOrActivate`** with `{ password, recoverycode, email }`. **`forgotpassword`** collects email and dispatches **`recoverPassword`**. **`mailrecoverinfo`** shows informational copy and a link back to login.
- **OAuth:** When `oauth2providers` is a non-empty list, a row of **`hb-auth-social-login-button`** instances is rendered. The host receives **`oauthFlowRedirectStart`**, **`oauthFlowInit`**, **`oauthFlowSuccess`**, and **`oauthFlowCustom`** bubbled from the child. While a flow is in progress, an **opaque overlay** matching the card surface covers the card and shows **only a centered CSS spinner** (no copy); after success, a **dismissible success notification** appears above the card (hidden again during a subsequent OAuth load).
- **URL hints:** If `recoverycode`, `email`, or `type` are not set, the component may read `recoverycode=`, `recoveryemail=`, and `recoverytype=` from `location.href` (query segment after each key, up to `&`).
- **OAuth-only layout:** With `disablelocal` true (and providers configured), the divider and “credentials” subtitle are omitted; only social buttons show for supported `type` values.

The `Component` type also allows `type` values **`otp`**, **`2fa_code`**, and **`2fa_config`**, and includes **`activateuri`** and **`recoveruri`**. In the current markup, **only** `login`, `register`, `forgotpassword`, `mailrecoverinfo`, `activate`, and `recover` drive complete titles, fields, and actions. Other `type` strings are accepted at the type level but **do not** map to dedicated UI blocks in `component.wc.svelte`; **`activateuri` / `recoveruri`** are declared on the component but are **not** read by this file’s logic (hosts can still use them in their own layers).

## Appearance and layout

- **Host:** Block-level, full width of the parent, default text color `var(--bulma-text)`.
- **Width:** Inner wrapper `max-width: 24rem`, centered (`margin-inline: auto`).
- **Card:** Main content uses Bulma’s **`box`** on `.hb-auth` with an extra **1px** border using `var(--bulma-border-weak)` for contrast in light and dark schemes.
- **Header:** Default slot fills with a centered logo image when `logouri` is non-empty; consumers can replace the whole header with the **`header`** slot.
- **Titles:** Centered `title is-4` for login, register, forgot password, and recover/activate headings (i18n strings).
- **OAuth row:** Flex-wrapped, centered list of provider tiles. Each **`hb-auth-social-login-button`** is **5rem × 5rem**, bordered, rounded with `var(--bulma-radius)`, background `var(--bulma-scheme-main-ter)`, with hover ring and focus-visible outline using `var(--bulma-link)`.
- **Divider:** When both OAuth and local form are shown, a horizontal rule (`hb-auth__divider`) separates providers from the “credentials” subtitle and fields.
- **Fields:** Bulma `field` / `control` / `input` patterns; validation toggles Bulma **`is-success` / `is-danger`** on inputs after submit attempts.
- **Overlay:** Absolutely positioned over the **card shell** (`inset: 0`), same background as the Bulma **`box`** (`var(--bulma-box-background-color)` with fallback to `var(--bulma-scheme-main)`), matching **border radius** to the card; **no** extra border or shadow on the overlay. Only **`.hb-auth__spinner`** is visible (track from `color-mix` on `var(--bulma-text)`, accent `var(--bulma-link)`). `aria-busy` on `<main>` reflects loading state.
- **Success banner:** Bulma `notification is-success is-light` above the card when OAuth completes successfully (not shown while OAuth loading is active).
- **Icons:** **Bootstrap Icons** are loaded inside the shadow tree from `styles/webcomponent.scss` (required because `<svelte:head>` link tags do not apply inside shadow roots).

## Logic (sign-in and related flows)

| Mode | Primary action | Event / side effects |
| --- | --- | --- |
| `login` | Validates email/password (length and simple email shape). | With `loginuri`: `fetch`, then storage + optional `redirectonlogin`, then **`login`**. Without `loginuri`: **`login`** with `{ email, password, rememberMe }` only. |
| `register` | Same base validation as login. | With `registeruri`: `fetch`, augments answer with `requestSent`, optional `redirectoncreate`, **`register`**. Without: **`register`** with `{ email, password }`. |
| `forgotpassword` | Email validation. | **`recoverPassword`** with `{ email }`. |
| `activate` / `recover` | Requires `recoverycode`, valid email, password, matching repeat password. | **`recoverOrActivate`** with `{ password, recoverycode, email }`. Recovery code or email read from URL may lock those inputs as disabled. |
| `mailrecoverinfo` | Navigation via footer link. | Switches `type` to `login` in UI only (no dispatch listed for that click beyond user changing mode). |

**Query/body extras:** `appendqueryparams` is appended to `loginuri` and `registeruri` when set (as `?` or `&` depending on whether the path already contains `?`). If unset internally, it becomes `undefined` after the effect.

**Booleans from attributes:** For web components, use string **`yes`** / **`no`** where applicable. `enable_recover_password` is also treated as true when the string is **`true`** or **empty** (`""`) in the effect’s coercion.

**OAuth list:** `oauth2providers` may arrive as a **JSON string** (from attributes); it is parsed and normalized (default scopes for named providers when `url` is empty and `params` exist; `redirect_url` may get a `provider=` query suffix).

**Enter key:** Inside the card, **Enter** triggers the primary action for `login`, `register`, `forgotpassword`, `activate`, and `recover`.

## Custom element

| Item | Value |
| --- | --- |
| Tag name | **`hb-auth`** |
| Svelte option | `customElement="hb-auth"` |
| Dependency | Registers **`hb-auth-social-login-button`** at runtime (`addComponent`) for OAuth tiles. |

## Attributes

All reflected / HTML-facing names use **snake_case**. Complex values (`oauth2providers`, `appendbodyparams`) are **JSON strings** in markup. Booleans follow project convention **`yes`** / **`no`** unless noted.

| Attribute | Purpose |
| --- | --- |
| `id` | Optional host element id. |
| `style` | Optional inline style on the host (standard HTML). |
| `type` | Screen mode: `login` \| `register` \| `activate` \| `recover` \| `forgotpassword` \| `mailrecoverinfo` \| `otp` \| `2fa_code` \| `2fa_config` (see note above on UI coverage). Defaults to `login` when omitted and not taken from URL. |
| `email` | Initial or bound email; may be filled from `recoveryemail=` in the URL. |
| `i18nlang` | Language code (e.g. `en`, `it`) for built-in strings. |
| `sessionkey` | Storage key for persisted auth JSON (default `_auth`). Passed to social login as `auth_cookie_name`. |
| `social_auth_server_url` | Optional base URL forwarded to each **`hb-auth-social-login-button`**. |
| `redirectonlogin` | Optional full navigation after successful stored login; also passed to social buttons. |
| `redirectoncreate` | Optional full navigation after successful registration. |
| `loginuri` | Login API URL for `fetch`. |
| `registeruri` | Register API URL for `fetch`. |
| `activateuri` | Declared on the component type; not used by `component.wc.svelte` logic in this version. |
| `recoveruri` | Declared on the component type; not used by `component.wc.svelte` logic in this version. |
| `requestmethod` | HTTP verb for login/register `fetch` (default `POST`). |
| `appendqueryparams` | String appended to `loginuri` and `registeruri` as query parameters. |
| `appendbodyparams` | JSON object string merged into POST bodies for login/register. |
| `logouri` | Logo image URL for the default header. |
| `oauth2providers` | JSON array of provider objects (`name`, optional `url`, optional `params`) compatible with **`hb-auth-social-login-button`** expectations. |
| `disableregister` | When enabled, hides registration entry points and related UI. |
| `enable_recover_password` | When enabled, shows “forgot password” on the login screen. |
| `passwordpattern` | Optional HTML `pattern` on password inputs. |
| `recoverycode` | Recovery/activation code; may be locked if present in URL. |
| `disablelocal` | When `yes`, hides local email/password block when OAuth providers are present (OAuth-only card). |

## Events

Listen with `addEventListener` or framework bindings; names are **exactly** as below. **`detail`** shapes match `types/webcomponent.type.d.ts` (`Events`).

| Event | `detail` (TypeScript shape) |
| --- | --- |
| `login` | `{ token?: string; email?: string; password?: string; rememberMe?: boolean }` — server response fields when `loginuri` succeeds; otherwise credential payload. |
| `register` | `Record<string, unknown> & { email?: string; password?: string; requestSent?: { email: string; password: string } }` — server JSON when `registeruri` succeeds (component adds `requestSent`); `{ email, password }` when no `registeruri`. |
| `recoverOrActivate` | `{ password: string; recoverycode: string; email: string }` |
| `recoverPassword` | `{ email: string }` |
| `oauthFlowInit` | `{ token?: string; provider: "facebook" \| "google" \| "gitlab" \| "github" \| "authentik"; tmpCode?: string; redirect_uri?: string }` |
| `oauthFlowRedirectStart` | `{ provider: "facebook" \| "google" \| "gitlab" \| "github" \| "authentik" }` |
| `oauthFlowSuccess` | `{ token: string }` |
| `oauthFlowCustom` | `{ provider: "facebook" \| "google" \| "gitlab" \| "github" \| "authentik" }` |

The `provider` literals match `auth-social-login-button`’s `types/webcomponent.type.d.ts` (`IProvider`), which the auth `Events` type reuses for these fields.

## Styling

### CSS custom properties (`:host` / theme)

Documented in `extra/docs.ts` (`styleSetup.vars`). They align with **Bulma 1** tokens; see [Bulma CSS variables](https://bulma.io/documentation/features/css-variables/).

| Variable | Role |
| --- | --- |
| `--bulma-scheme-main` | Card surface; fallback for OAuth overlay fill when box vars are unavailable. |
| `--bulma-box-background-color` | OAuth overlay fill (matches Bulma `box` when defined on the theme). |
| `--bulma-box-radius` | OAuth overlay corner radius (matches Bulma `box` when defined). |
| `--bulma-scheme-main-ter` | OAuth tile background. |
| `--bulma-border-weak` | Card, tiles, divider. |
| `--bulma-radius` | Social tiles and related rounding. |
| `--bulma-shadow` | Bulma `box` elevation on the card. |
| `--bulma-text` | Default text on `:host`; spinner track tint (`color-mix`). |
| `--bulma-text-strong` | Headings. |
| `--bulma-link` | Ghost links, tile hover ring, focus-visible outlines, spinner accent. |

**Light / dark:** `styles/bulma.scss` installs Bulma light theme on `:host`, dark theme under `prefers-color-scheme: dark`, and overrides when `html` / `body` use `data-theme` / `.theme-light` / `.theme-dark`, or when the host element sets `data-theme`.

### CSS parts

None (`cssParts` is empty in `extra/docs.ts`).

### Slots

| Slot | Description |
| --- | --- |
| `header` | Optional branding above the form; **replaces** the default logo block when content is provided. |

## Typings

Authoring types for consumers and wrappers:

`src/wc/auth/types/webcomponent.type.d.ts`

- **`Component`** — props interface.  
- **`Events`** — custom event name → `detail` map.

## Minimal HTML example

```html
<hb-auth
  type="login"
  i18nlang="en"
  logouri="https://example.com/logo.svg"
  loginuri="https://api.example.com/auth/login"
  sessionkey="_auth"
  enable_recover_password="yes"
  disableregister="no"
></hb-auth>
```

OAuth-only example (attributes as strings):

```html
<hb-auth
  type="login"
  disablelocal="yes"
  oauth2providers='[{"name":"google","url":"https://accounts.google.com/o/oauth2/v2/auth?..."}]'
  sessionkey="_auth"
></hb-auth>
```
