@zitadel/components 0.1.0-alpha.14 → 0.1.0-alpha.16

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 (32) hide show
  1. package/README.md +1 -0
  2. package/dist/atoms/index.d.mts +1 -1
  3. package/dist/atoms/index.mjs +1 -1
  4. package/dist/{atoms-BSwVl736.mjs → atoms-C-zXJjaz.mjs} +106 -10
  5. package/dist/{atoms-BSwVl736.mjs.map → atoms-C-zXJjaz.mjs.map} +1 -1
  6. package/dist/default-BoC3JEsO.mjs +6 -0
  7. package/dist/default-BoC3JEsO.mjs.map +1 -0
  8. package/dist/{index-EC-BnGsx.d.mts → index-BniwXaIC.d.mts} +3 -1
  9. package/dist/{index-EC-BnGsx.d.mts.map → index-BniwXaIC.d.mts.map} +1 -1
  10. package/dist/{index-Bypr00UG.d.mts → index-BwQLFs9R.d.mts} +362 -17
  11. package/dist/index-BwQLFs9R.d.mts.map +1 -0
  12. package/dist/{index-BP3l3mje.d.mts → index-D1eMaWbY.d.mts} +52 -5
  13. package/dist/index-D1eMaWbY.d.mts.map +1 -0
  14. package/dist/index.d.mts +4 -4
  15. package/dist/index.mjs +4 -4
  16. package/dist/manifests.mjs +1 -1
  17. package/dist/orchestrator/index.d.mts +2 -2
  18. package/dist/orchestrator/index.mjs +2 -2
  19. package/dist/{orchestrator-qkFBKFgJ.mjs → orchestrator-BN2nT9FZ.mjs} +317 -25
  20. package/dist/orchestrator-BN2nT9FZ.mjs.map +1 -0
  21. package/dist/standalone.mjs +423 -33
  22. package/dist/tokens/index.d.mts +1 -1
  23. package/dist/tokens/index.mjs +1 -1
  24. package/dist/{tokens-C0j4iCrs.mjs → tokens-CbH2s1jV.mjs} +6 -4
  25. package/dist/tokens-CbH2s1jV.mjs.map +1 -0
  26. package/package.json +5 -4
  27. package/dist/default-W5MwYLBc.mjs +0 -6
  28. package/dist/default-W5MwYLBc.mjs.map +0 -1
  29. package/dist/index-BP3l3mje.d.mts.map +0 -1
  30. package/dist/index-Bypr00UG.d.mts.map +0 -1
  31. package/dist/orchestrator-qkFBKFgJ.mjs.map +0 -1
  32. package/dist/tokens-C0j4iCrs.mjs.map +0 -1
package/README.md CHANGED
@@ -191,6 +191,7 @@ renders the bundled `default.liquid`. Tracked as a follow-up.
191
191
  | Property | Type | Notes |
192
192
  | --- | --- | --- |
193
193
  | `purpose` | `'login' \| 'register' \| 'reset_password' \| string` | Which flow purpose to drive |
194
+ | `flowName` / `flow-name` | `string` | Run the flow definition with this `name` instead of the project default |
194
195
  | `project` | `ZitadelProject` | SDK handle from `configureZitadel()`. Object property (not an attribute). When unset, the element falls back to the global handle from `getZitadelConfig()` |
195
196
  | `lang` | `string` | BCP 47 tag (e.g. `"de"`, `"en-US"`). Resolves to a built-in dictionary; falls back to `<html lang>` / `navigator.language` |
196
197
  | `locales` | `Record<string, Locale>` | Custom locale dictionaries keyed by language code; spread over the built-in dictionary so partial overrides work |
@@ -1,2 +1,2 @@
1
- import { $t as zlCardManifest, Qt as ZlCard, Xt as ZlCheckboxChangeDetail, Yt as ZlCheckbox, Zt as zlCheckboxManifest, a as ZlPill, an as ZlIcon, c as ZlPasskeyErrorDetail, d as ZlPageShell, en as ZlButton, f as zlPageShellManifest, h as zlFieldManifest, i as zlSelectManifest, in as IconName, l as ZlPasskeyResultDetail, m as ZlFieldType, n as ZlSelectChangeDetail, nn as ZlAlert, o as zlPillManifest, on as zlIconManifest, p as ZlField, r as ZlSelectOption, rn as zlAlertManifest, s as ZlPasskey, t as ZlSelect, tn as zlButtonManifest, u as zlPasskeyManifest } from "../index-Bypr00UG.mjs";
1
+ import { $t as ZlCheckbox, a as ZlPill, an as zlButtonManifest, c as ZlPasskeyErrorDetail, cn as IconName, d as ZlPageShell, en as ZlCheckboxChangeDetail, f as zlPageShellManifest, h as zlFieldManifest, i as zlSelectManifest, in as ZlButton, l as ZlPasskeyResultDetail, ln as ZlIcon, m as ZlFieldType, n as ZlSelectChangeDetail, nn as ZlCard, o as zlPillManifest, on as ZlAlert, p as ZlField, r as ZlSelectOption, rn as zlCardManifest, s as ZlPasskey, sn as zlAlertManifest, t as ZlSelect, tn as zlCheckboxManifest, u as zlPasskeyManifest, un as zlIconManifest } from "../index-BwQLFs9R.mjs";
2
2
  export { IconName, ZlAlert, ZlButton, ZlCard, ZlCheckbox, ZlCheckboxChangeDetail, ZlField, ZlFieldType, ZlIcon, ZlPageShell, ZlPasskey, ZlPasskeyErrorDetail, ZlPasskeyResultDetail, ZlPill, ZlSelect, ZlSelectChangeDetail, ZlSelectOption, zlAlertManifest, zlButtonManifest, zlCardManifest, zlCheckboxManifest, zlFieldManifest, zlIconManifest, zlPageShellManifest, zlPasskeyManifest, zlPillManifest, zlSelectManifest };
@@ -1,2 +1,2 @@
1
- import { _ as ZlAlert, a as ZlPasskey, b as zlIconManifest, c as zlPageShellManifest, d as ZlCheckbox, f as zlCheckboxManifest, g as zlButtonManifest, h as ZlButton, i as zlPillManifest, l as ZlField, m as zlCardManifest, n as zlSelectManifest, o as zlPasskeyManifest, p as ZlCard, r as ZlPill, s as ZlPageShell, t as ZlSelect, u as zlFieldManifest, v as zlAlertManifest, y as ZlIcon } from "../atoms-BSwVl736.mjs";
1
+ import { _ as ZlAlert, a as ZlPasskey, b as zlIconManifest, c as zlPageShellManifest, d as ZlCheckbox, f as zlCheckboxManifest, g as zlButtonManifest, h as ZlButton, i as zlPillManifest, l as ZlField, m as zlCardManifest, n as zlSelectManifest, o as zlPasskeyManifest, p as ZlCard, r as ZlPill, s as ZlPageShell, t as ZlSelect, u as zlFieldManifest, v as zlAlertManifest, y as ZlIcon } from "../atoms-C-zXJjaz.mjs";
2
2
  export { ZlAlert, ZlButton, ZlCard, ZlCheckbox, ZlField, ZlIcon, ZlPageShell, ZlPasskey, ZlPill, ZlSelect, zlAlertManifest, zlButtonManifest, zlCardManifest, zlCheckboxManifest, zlFieldManifest, zlIconManifest, zlPageShellManifest, zlPasskeyManifest, zlPillManifest, zlSelectManifest };
@@ -1,4 +1,4 @@
1
- import { t as cssVars } from "./tokens-C0j4iCrs.mjs";
1
+ import { t as cssVars } from "./tokens-CbH2s1jV.mjs";
2
2
  import { LitElement, css, html, nothing, unsafeCSS } from "lit";
3
3
  import { customElement, property, query, state } from "lit/decorators.js";
4
4
  import { classMap } from "lit/directives/class-map.js";
@@ -1373,6 +1373,13 @@ function base64UrlToBuffer(base64url) {
1373
1373
  }
1374
1374
  //#endregion
1375
1375
  //#region src/atoms/zl-passkey.ts
1376
+ /**
1377
+ * Slack subtracted from `options.timeout` when classifying a
1378
+ * `NotAllowedError` as a timeout: browsers clamp and fire the deadline
1379
+ * slightly early, so an exact comparison would label real timeouts as
1380
+ * user cancellations.
1381
+ */
1382
+ const TIMEOUT_GRACE_MS = 1e3;
1376
1383
  let ZlPasskey = class ZlPasskey extends LitElement {
1377
1384
  #_ceremony_accessor_storage = "authenticate";
1378
1385
  get ceremony() {
@@ -1409,7 +1416,37 @@ let ZlPasskey = class ZlPasskey extends LitElement {
1409
1416
  set manual(value) {
1410
1417
  this.#_manual_accessor_storage = value;
1411
1418
  }
1419
+ #_pendingLabel_accessor_storage = "Waiting for your passkey…";
1420
+ get pendingLabel() {
1421
+ return this.#_pendingLabel_accessor_storage;
1422
+ }
1423
+ set pendingLabel(value) {
1424
+ this.#_pendingLabel_accessor_storage = value;
1425
+ }
1426
+ #_cancelLabel_accessor_storage = "Cancel";
1427
+ get cancelLabel() {
1428
+ return this.#_cancelLabel_accessor_storage;
1429
+ }
1430
+ set cancelLabel(value) {
1431
+ this.#_cancelLabel_accessor_storage = value;
1432
+ }
1433
+ #_silent_accessor_storage = false;
1434
+ get silent() {
1435
+ return this.#_silent_accessor_storage;
1436
+ }
1437
+ set silent(value) {
1438
+ this.#_silent_accessor_storage = value;
1439
+ }
1440
+ #_pending_accessor_storage = false;
1441
+ get pending() {
1442
+ return this.#_pending_accessor_storage;
1443
+ }
1444
+ set pending(value) {
1445
+ this.#_pending_accessor_storage = value;
1446
+ }
1412
1447
  abortController = null;
1448
+ /** `Date.now()` at ceremony start, for timeout classification on reject. */
1449
+ startedAt = 0;
1413
1450
  connectedCallback() {
1414
1451
  super.connectedCallback();
1415
1452
  if (!this.manual && this.options) this.startCeremony();
@@ -1420,11 +1457,14 @@ let ZlPasskey = class ZlPasskey extends LitElement {
1420
1457
  }
1421
1458
  /**
1422
1459
  * Abort any in-flight WebAuthn ceremony. Called automatically when the
1423
- * component disconnects (step change, page navigation).
1460
+ * component disconnects (step change, page navigation) and by the
1461
+ * pending UI's cancel button. Clears `pending` immediately — the
1462
+ * ceremony's own `finally` no longer owns it (its controller is gone).
1424
1463
  */
1425
1464
  abort() {
1426
1465
  this.abortController?.abort();
1427
1466
  this.abortController = null;
1467
+ this.pending = false;
1428
1468
  }
1429
1469
  /**
1430
1470
  * Trigger the WebAuthn ceremony. Resolves when the ceremony completes
@@ -1440,7 +1480,11 @@ let ZlPasskey = class ZlPasskey extends LitElement {
1440
1480
  return;
1441
1481
  }
1442
1482
  this.abort();
1443
- this.abortController = new AbortController();
1483
+ const controller = new AbortController();
1484
+ this.abortController = controller;
1485
+ this.pending = true;
1486
+ this.startedAt = Date.now();
1487
+ this.emitStarted();
1444
1488
  try {
1445
1489
  const credential = this.ceremony === "register" ? await this.createCredential() : await this.getCredential();
1446
1490
  if (!credential) {
@@ -1451,9 +1495,33 @@ let ZlPasskey = class ZlPasskey extends LitElement {
1451
1495
  this.emitResult(proof);
1452
1496
  } catch (error) {
1453
1497
  const aborted = error instanceof DOMException && (error.name === "AbortError" || error.name === "NotAllowedError");
1454
- this.emitError(error instanceof Error ? error.message : "WebAuthn ceremony failed.", aborted);
1498
+ const timeoutMs = typeof this.options?.timeout === "number" ? this.options.timeout : null;
1499
+ const timedOut = error instanceof DOMException && error.name === "NotAllowedError" && timeoutMs !== null && Date.now() - this.startedAt >= timeoutMs - TIMEOUT_GRACE_MS;
1500
+ this.emitError(error instanceof Error ? error.message : "WebAuthn ceremony failed.", aborted, timedOut);
1501
+ } finally {
1502
+ if (this.abortController === controller) this.pending = false;
1455
1503
  }
1456
1504
  }
1505
+ handleCancelSubmit = (event) => {
1506
+ event.stopPropagation();
1507
+ this.abort();
1508
+ };
1509
+ render() {
1510
+ if (!this.pending || this.silent) return nothing;
1511
+ return html`
1512
+ <div class="zl-passkey-pending" data-testid="zitadel-passkey-pending">
1513
+ <zl-alert severity="info">${this.pendingLabel}</zl-alert>
1514
+ <zl-button
1515
+ hierarchy="secondary"
1516
+ type="button"
1517
+ block
1518
+ data-testid="zitadel-passkey-cancel"
1519
+ label=${this.cancelLabel}
1520
+ @zl-submit=${this.handleCancelSubmit}
1521
+ ></zl-button>
1522
+ </div>
1523
+ `;
1524
+ }
1457
1525
  /**
1458
1526
  * `navigator.credentials.get()` — authentication ceremony.
1459
1527
  */
@@ -1555,11 +1623,12 @@ let ZlPasskey = class ZlPasskey extends LitElement {
1555
1623
  detail
1556
1624
  }));
1557
1625
  }
1558
- emitError(message, aborted) {
1626
+ emitError(message, aborted, timedOut = false) {
1559
1627
  const detail = {
1560
1628
  challenge_id: this.challengeId,
1561
1629
  error: message,
1562
- aborted
1630
+ aborted,
1631
+ timed_out: timedOut
1563
1632
  };
1564
1633
  this.dispatchEvent(new CustomEvent("zl-passkey-error", {
1565
1634
  bubbles: true,
@@ -1567,7 +1636,23 @@ let ZlPasskey = class ZlPasskey extends LitElement {
1567
1636
  detail
1568
1637
  }));
1569
1638
  }
1570
- /** Invisible component — no shadow DOM rendering needed. */
1639
+ emitStarted() {
1640
+ const detail = {
1641
+ challenge_id: this.challengeId,
1642
+ method: this.method
1643
+ };
1644
+ this.dispatchEvent(new CustomEvent("zl-passkey-started", {
1645
+ bubbles: true,
1646
+ composed: true,
1647
+ detail
1648
+ }));
1649
+ }
1650
+ /**
1651
+ * Light DOM on purpose: the pending UI must land inside the
1652
+ * orchestrator's shadow root (where the step's adopted styles apply)
1653
+ * without altering the `unsafeHTML` step markup — runtime children don't
1654
+ * participate in its string comparison, so the ceremony never restarts.
1655
+ */
1571
1656
  createRenderRoot() {
1572
1657
  return this;
1573
1658
  }
@@ -1592,6 +1677,10 @@ __decorate([property({
1592
1677
  })], ZlPasskey.prototype, "options", null);
1593
1678
  __decorate([property({ type: String })], ZlPasskey.prototype, "method", null);
1594
1679
  __decorate([property({ type: Boolean })], ZlPasskey.prototype, "manual", null);
1680
+ __decorate([property({ attribute: "pending-label" })], ZlPasskey.prototype, "pendingLabel", null);
1681
+ __decorate([property({ attribute: "cancel-label" })], ZlPasskey.prototype, "cancelLabel", null);
1682
+ __decorate([property({ type: Boolean })], ZlPasskey.prototype, "silent", null);
1683
+ __decorate([state()], ZlPasskey.prototype, "pending", null);
1595
1684
  ZlPasskey = __decorate([customElement("zl-passkey")], ZlPasskey);
1596
1685
  const zlPasskeyManifest = {
1597
1686
  tag: "zl-passkey",
@@ -1601,11 +1690,18 @@ const zlPasskeyManifest = {
1601
1690
  "method",
1602
1691
  "challenge-id",
1603
1692
  "options",
1604
- "manual"
1693
+ "manual",
1694
+ "pending-label",
1695
+ "cancel-label",
1696
+ "silent"
1605
1697
  ],
1606
1698
  parts: [],
1607
1699
  slots: [],
1608
- events: ["zl-passkey-result", "zl-passkey-error"]
1700
+ events: [
1701
+ "zl-passkey-result",
1702
+ "zl-passkey-error",
1703
+ "zl-passkey-started"
1704
+ ]
1609
1705
  };
1610
1706
  //#endregion
1611
1707
  //#region ../shared-component-styles/src/lit/pill-host.css?inline
@@ -2067,4 +2163,4 @@ const zlSelectManifest = {
2067
2163
  //#endregion
2068
2164
  export { baseHostStyles as C, focusVisibleStyles as S, emit as T, ZlAlert as _, ZlPasskey as a, zlIconManifest as b, zlPageShellManifest as c, ZlCheckbox as d, zlCheckboxManifest as f, zlButtonManifest as g, ZlButton as h, zlPillManifest as i, ZlField as l, zlCardManifest as m, zlSelectManifest as n, zlPasskeyManifest as o, ZlCard as p, ZlPill as r, ZlPageShell as s, ZlSelect as t, zlFieldManifest as u, zlAlertManifest as v, t as w, __decorate as x, ZlIcon as y };
2069
2165
 
2070
- //# sourceMappingURL=atoms-BSwVl736.mjs.map
2166
+ //# sourceMappingURL=atoms-C-zXJjaz.mjs.map