@productcraft/auth 0.5.2 → 0.7.1

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.
package/dist/index.js CHANGED
@@ -763,11 +763,15 @@ function getApiKeyControllerListApiKeysUrl({
763
763
  const res = { method: "GET", url: `/v1/apps/${app_id}/api-keys` };
764
764
  return res;
765
765
  }
766
- async function apiKeyControllerListApiKeys({ appId }, config = {}) {
766
+ async function apiKeyControllerListApiKeys({
767
+ appId,
768
+ params
769
+ }, config = {}) {
767
770
  const { client: request = client, ...requestConfig } = config;
768
771
  const res = await request({
769
772
  method: "GET",
770
773
  url: getApiKeyControllerListApiKeysUrl({ appId }).url.toString(),
774
+ params,
771
775
  ...requestConfig
772
776
  });
773
777
  return res.data;
@@ -1029,7 +1033,9 @@ async function appAuditControllerGetAuditLogs({
1029
1033
  limit: params.limit,
1030
1034
  cursor: params.cursor,
1031
1035
  action: params.action,
1032
- actor_id: params.actorId
1036
+ actor_id: params.actorId,
1037
+ since: params.since,
1038
+ until: params.until
1033
1039
  } : void 0;
1034
1040
  const res = await request({
1035
1041
  method: "GET",
@@ -1359,6 +1365,36 @@ async function consumerAuthControllerRequestPasswordReset({
1359
1365
  return res.data;
1360
1366
  }
1361
1367
 
1368
+ // src/_generated/clients/consumerAuth/consumerAuthControllerSendPasswordResetEmail.ts
1369
+ function getConsumerAuthControllerSendPasswordResetEmailUrl({
1370
+ appSlug
1371
+ }) {
1372
+ const app_slug = appSlug;
1373
+ const res = {
1374
+ method: "POST",
1375
+ url: `/${app_slug}/v1/auth/send-password-reset-email`
1376
+ };
1377
+ return res;
1378
+ }
1379
+ async function consumerAuthControllerSendPasswordResetEmail({
1380
+ appSlug,
1381
+ data,
1382
+ headers
1383
+ }, config = {}) {
1384
+ const { client: request = client, ...requestConfig } = config;
1385
+ const requestData = data;
1386
+ const res = await request({
1387
+ method: "POST",
1388
+ url: getConsumerAuthControllerSendPasswordResetEmailUrl({
1389
+ appSlug
1390
+ }).url.toString(),
1391
+ data: requestData,
1392
+ ...requestConfig,
1393
+ headers: { ...headers, ...requestConfig.headers }
1394
+ });
1395
+ return res.data;
1396
+ }
1397
+
1362
1398
  // src/_generated/clients/consumerAuth/consumerAuthControllerResetPassword.ts
1363
1399
  function getConsumerAuthControllerResetPasswordUrl({
1364
1400
  appSlug
@@ -1525,6 +1561,220 @@ async function consumerIdpControllerNativeSignIn({
1525
1561
  return res.data;
1526
1562
  }
1527
1563
 
1564
+ // src/_generated/clients/consumerAuth/consumerAuthControllerPasskeyOptions.ts
1565
+ function getConsumerAuthControllerPasskeyOptionsUrl({
1566
+ appSlug
1567
+ }) {
1568
+ const app_slug = appSlug;
1569
+ const res = {
1570
+ method: "POST",
1571
+ url: `/${app_slug}/v1/auth/passkey/options`
1572
+ };
1573
+ return res;
1574
+ }
1575
+ async function consumerAuthControllerPasskeyOptions({
1576
+ appSlug,
1577
+ data
1578
+ }, config = {}) {
1579
+ const { client: request = client, ...requestConfig } = config;
1580
+ const requestData = data;
1581
+ const res = await request({
1582
+ method: "POST",
1583
+ url: getConsumerAuthControllerPasskeyOptionsUrl({ appSlug }).url.toString(),
1584
+ data: requestData,
1585
+ ...requestConfig
1586
+ });
1587
+ return res.data;
1588
+ }
1589
+
1590
+ // src/_generated/clients/consumerAuth/consumerAuthControllerPasskeyVerify.ts
1591
+ function getConsumerAuthControllerPasskeyVerifyUrl({
1592
+ appSlug
1593
+ }) {
1594
+ const app_slug = appSlug;
1595
+ const res = {
1596
+ method: "POST",
1597
+ url: `/${app_slug}/v1/auth/passkey/verify`
1598
+ };
1599
+ return res;
1600
+ }
1601
+ async function consumerAuthControllerPasskeyVerify({
1602
+ appSlug,
1603
+ data
1604
+ }, config = {}) {
1605
+ const { client: request = client, ...requestConfig } = config;
1606
+ const requestData = data;
1607
+ const res = await request({
1608
+ method: "POST",
1609
+ url: getConsumerAuthControllerPasskeyVerifyUrl({ appSlug }).url.toString(),
1610
+ data: requestData,
1611
+ ...requestConfig
1612
+ });
1613
+ return res.data;
1614
+ }
1615
+
1616
+ // src/_generated/clients/consumerAuth/consumerAuthControllerMfaWebauthnOptions.ts
1617
+ function getConsumerAuthControllerMfaWebauthnOptionsUrl({
1618
+ appSlug
1619
+ }) {
1620
+ const app_slug = appSlug;
1621
+ const res = {
1622
+ method: "POST",
1623
+ url: `/${app_slug}/v1/auth/mfa/webauthn/options`
1624
+ };
1625
+ return res;
1626
+ }
1627
+ async function consumerAuthControllerMfaWebauthnOptions({
1628
+ appSlug,
1629
+ data
1630
+ }, config = {}) {
1631
+ const { client: request = client, ...requestConfig } = config;
1632
+ const requestData = data;
1633
+ const res = await request({
1634
+ method: "POST",
1635
+ url: getConsumerAuthControllerMfaWebauthnOptionsUrl({
1636
+ appSlug
1637
+ }).url.toString(),
1638
+ data: requestData,
1639
+ ...requestConfig
1640
+ });
1641
+ return res.data;
1642
+ }
1643
+
1644
+ // src/_generated/clients/consumerAuth/consumerAuthControllerMfaVerify.ts
1645
+ function getConsumerAuthControllerMfaVerifyUrl({
1646
+ appSlug
1647
+ }) {
1648
+ const app_slug = appSlug;
1649
+ const res = {
1650
+ method: "POST",
1651
+ url: `/${app_slug}/v1/auth/mfa/verify`
1652
+ };
1653
+ return res;
1654
+ }
1655
+ async function consumerAuthControllerMfaVerify({
1656
+ appSlug,
1657
+ data
1658
+ }, config = {}) {
1659
+ const { client: request = client, ...requestConfig } = config;
1660
+ const requestData = data;
1661
+ const res = await request({
1662
+ method: "POST",
1663
+ url: getConsumerAuthControllerMfaVerifyUrl({ appSlug }).url.toString(),
1664
+ data: requestData,
1665
+ ...requestConfig
1666
+ });
1667
+ return res.data;
1668
+ }
1669
+
1670
+ // src/_generated/clients/consumerMfa/consumerMfaControllerStartEnrollment.ts
1671
+ function getConsumerMfaControllerStartEnrollmentUrl({
1672
+ appSlug
1673
+ }) {
1674
+ const app_slug = appSlug;
1675
+ const res = {
1676
+ method: "POST",
1677
+ url: `/${app_slug}/v1/me/mfa/factors`
1678
+ };
1679
+ return res;
1680
+ }
1681
+ async function consumerMfaControllerStartEnrollment({
1682
+ appSlug,
1683
+ data
1684
+ }, config = {}) {
1685
+ const { client: request = client, ...requestConfig } = config;
1686
+ const requestData = data;
1687
+ const res = await request({
1688
+ method: "POST",
1689
+ url: getConsumerMfaControllerStartEnrollmentUrl({ appSlug }).url.toString(),
1690
+ data: requestData,
1691
+ ...requestConfig
1692
+ });
1693
+ return res.data;
1694
+ }
1695
+
1696
+ // src/_generated/clients/consumerMfa/consumerMfaControllerConfirmEnrollment.ts
1697
+ function getConsumerMfaControllerConfirmEnrollmentUrl({
1698
+ id,
1699
+ appSlug
1700
+ }) {
1701
+ const app_slug = appSlug;
1702
+ const res = {
1703
+ method: "POST",
1704
+ url: `/${app_slug}/v1/me/mfa/factors/${id}/verify`
1705
+ };
1706
+ return res;
1707
+ }
1708
+ async function consumerMfaControllerConfirmEnrollment({
1709
+ id,
1710
+ appSlug,
1711
+ data
1712
+ }, config = {}) {
1713
+ const { client: request = client, ...requestConfig } = config;
1714
+ const requestData = data;
1715
+ const res = await request({
1716
+ method: "POST",
1717
+ url: getConsumerMfaControllerConfirmEnrollmentUrl({
1718
+ id,
1719
+ appSlug
1720
+ }).url.toString(),
1721
+ data: requestData,
1722
+ ...requestConfig
1723
+ });
1724
+ return res.data;
1725
+ }
1726
+
1727
+ // src/_generated/clients/consumerMfa/consumerMfaControllerStepUpWebauthnOptions.ts
1728
+ function getConsumerMfaControllerStepUpWebauthnOptionsUrl({
1729
+ appSlug
1730
+ }) {
1731
+ const app_slug = appSlug;
1732
+ const res = {
1733
+ method: "POST",
1734
+ url: `/${app_slug}/v1/me/mfa/step-up/webauthn/options`
1735
+ };
1736
+ return res;
1737
+ }
1738
+ async function consumerMfaControllerStepUpWebauthnOptions({
1739
+ appSlug
1740
+ }, config = {}) {
1741
+ const { client: request = client, ...requestConfig } = config;
1742
+ const res = await request({
1743
+ method: "POST",
1744
+ url: getConsumerMfaControllerStepUpWebauthnOptionsUrl({
1745
+ appSlug
1746
+ }).url.toString(),
1747
+ ...requestConfig
1748
+ });
1749
+ return res.data;
1750
+ }
1751
+
1752
+ // src/_generated/clients/consumerMfa/consumerMfaControllerStepUp.ts
1753
+ function getConsumerMfaControllerStepUpUrl({
1754
+ appSlug
1755
+ }) {
1756
+ const app_slug = appSlug;
1757
+ const res = {
1758
+ method: "POST",
1759
+ url: `/${app_slug}/v1/me/mfa/step-up`
1760
+ };
1761
+ return res;
1762
+ }
1763
+ async function consumerMfaControllerStepUp({
1764
+ appSlug,
1765
+ data
1766
+ }, config = {}) {
1767
+ const { client: request = client, ...requestConfig } = config;
1768
+ const requestData = data;
1769
+ const res = await request({
1770
+ method: "POST",
1771
+ url: getConsumerMfaControllerStepUpUrl({ appSlug }).url.toString(),
1772
+ data: requestData,
1773
+ ...requestConfig
1774
+ });
1775
+ return res.data;
1776
+ }
1777
+
1528
1778
  // src/_generated/clients/consumerVerify/consumerVerifyControllerVerify.ts
1529
1779
  function getConsumerVerifyControllerVerifyUrl({
1530
1780
  appSlug
@@ -1630,6 +1880,165 @@ async function consumerOAuthControllerClientCredentials({
1630
1880
  return res.data;
1631
1881
  }
1632
1882
 
1883
+ // src/passkeys.ts
1884
+ function toB64u(buf) {
1885
+ const bytes = buf instanceof ArrayBuffer ? new Uint8Array(buf) : new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
1886
+ let bin = "";
1887
+ for (let i = 0; i < bytes.length; i++) bin += String.fromCharCode(bytes[i]);
1888
+ return btoa(bin).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
1889
+ }
1890
+ function fromB64u(s) {
1891
+ const b64 = s.replace(/-/g, "+").replace(/_/g, "/");
1892
+ const bin = atob(b64.padEnd(Math.ceil(b64.length / 4) * 4, "="));
1893
+ return Uint8Array.from(bin, (c) => c.charCodeAt(0));
1894
+ }
1895
+ var snakeToCamel = (k) => k.replace(/_([a-z0-9])/g, (_, c) => c.toUpperCase());
1896
+ function camelizeKeys(value) {
1897
+ if (Array.isArray(value)) return value.map(camelizeKeys);
1898
+ if (value && typeof value === "object" && !(value instanceof Uint8Array)) {
1899
+ const out = {};
1900
+ for (const [k, v] of Object.entries(value)) {
1901
+ out[snakeToCamel(k)] = camelizeKeys(v);
1902
+ }
1903
+ return out;
1904
+ }
1905
+ return value;
1906
+ }
1907
+ function decodeOptions(publicKey) {
1908
+ const pk = camelizeKeys(publicKey);
1909
+ const out = {
1910
+ ...pk,
1911
+ challenge: fromB64u(pk.challenge)
1912
+ };
1913
+ if (pk.user) {
1914
+ out.user = { ...pk.user, id: fromB64u(pk.user.id) };
1915
+ }
1916
+ for (const list of ["excludeCredentials", "allowCredentials"]) {
1917
+ const entries = pk[list];
1918
+ if (entries) {
1919
+ out[list] = entries.map((c) => ({ ...c, id: fromB64u(c.id) }));
1920
+ }
1921
+ }
1922
+ return out;
1923
+ }
1924
+ function encodeCredential(cred) {
1925
+ const r = cred.response;
1926
+ const response = {
1927
+ clientDataJSON: toB64u(r.clientDataJSON)
1928
+ };
1929
+ if (r.attestationObject) response.attestationObject = toB64u(r.attestationObject);
1930
+ if (r.authenticatorData) response.authenticatorData = toB64u(r.authenticatorData);
1931
+ if (r.signature) response.signature = toB64u(r.signature);
1932
+ if (r.userHandle) response.userHandle = toB64u(r.userHandle);
1933
+ return { id: cred.id, response };
1934
+ }
1935
+ var PasskeyError = class extends Error {
1936
+ code;
1937
+ cause;
1938
+ constructor(code, message, cause) {
1939
+ super(message);
1940
+ this.name = "PasskeyError";
1941
+ this.code = code;
1942
+ this.cause = cause;
1943
+ }
1944
+ };
1945
+ function browserCredentials() {
1946
+ const nav = globalThis.navigator;
1947
+ const creds = nav?.credentials;
1948
+ if (!creds || typeof creds.create !== "function" || typeof creds.get !== "function") {
1949
+ return void 0;
1950
+ }
1951
+ return creds;
1952
+ }
1953
+ function isPasskeySupported() {
1954
+ const g = globalThis;
1955
+ if (typeof g.window === "undefined") return false;
1956
+ if (typeof g.PublicKeyCredential !== "function") return false;
1957
+ if (g.isSecureContext === false) return false;
1958
+ return browserCredentials() !== void 0;
1959
+ }
1960
+ function mapDomError(err) {
1961
+ const name = err?.name;
1962
+ const message = err?.message ?? String(err);
1963
+ switch (name) {
1964
+ case "NotAllowedError":
1965
+ return new PasskeyError(
1966
+ "cancelled",
1967
+ `Passkey prompt was cancelled, timed out, or no passkey matched: ${message}`,
1968
+ err
1969
+ );
1970
+ case "InvalidStateError":
1971
+ return new PasskeyError("invalid_state", `Authenticator refused: ${message}`, err);
1972
+ case "SecurityError":
1973
+ return new PasskeyError(
1974
+ "security",
1975
+ `Page origin does not match the app's rp_id: ${message}`,
1976
+ err
1977
+ );
1978
+ case "AbortError":
1979
+ return new PasskeyError("cancelled", `Passkey ceremony aborted: ${message}`, err);
1980
+ case "TimeoutError":
1981
+ return new PasskeyError(
1982
+ "timeout",
1983
+ `Passkey prompt timed out before a credential was produced: ${message}`,
1984
+ err
1985
+ );
1986
+ default:
1987
+ return new PasskeyError("unknown", `navigator.credentials failed: ${message}`, err);
1988
+ }
1989
+ }
1990
+ function resolveCredentials(opts = {}) {
1991
+ const creds = opts.credentials ?? browserCredentials();
1992
+ if (!creds) {
1993
+ throw new PasskeyError(
1994
+ "unsupported",
1995
+ "navigator.credentials is not available \u2014 passkeys need a browser with WebAuthn (check isPasskeySupported())"
1996
+ );
1997
+ }
1998
+ return creds;
1999
+ }
2000
+ function isCredentialLike(value) {
2001
+ if (!value || typeof value !== "object") return false;
2002
+ const v = value;
2003
+ return typeof v.id === "string" && !!v.response && typeof v.response === "object";
2004
+ }
2005
+ async function createPasskeyCredential(publicKey, opts = {}) {
2006
+ const creds = resolveCredentials(opts);
2007
+ let cred;
2008
+ try {
2009
+ cred = await creds.create({ publicKey: decodeOptions(publicKey), signal: opts.signal });
2010
+ } catch (err) {
2011
+ throw mapDomError(err);
2012
+ }
2013
+ if (!isCredentialLike(cred)) {
2014
+ throw new PasskeyError(
2015
+ "no_credential",
2016
+ "navigator.credentials.create() returned no usable credential"
2017
+ );
2018
+ }
2019
+ return encodeCredential(cred);
2020
+ }
2021
+ async function getPasskeyCredential(publicKey, opts = {}) {
2022
+ const creds = resolveCredentials(opts);
2023
+ let cred;
2024
+ try {
2025
+ cred = await creds.get({
2026
+ publicKey: decodeOptions(publicKey),
2027
+ mediation: opts.mediation,
2028
+ signal: opts.signal
2029
+ });
2030
+ } catch (err) {
2031
+ throw mapDomError(err);
2032
+ }
2033
+ if (!isCredentialLike(cred)) {
2034
+ throw new PasskeyError(
2035
+ "no_credential",
2036
+ "navigator.credentials.get() returned no usable credential"
2037
+ );
2038
+ }
2039
+ return encodeCredential(cred);
2040
+ }
2041
+
1633
2042
  // src/jwt/errors.ts
1634
2043
  var JwtVerifyError = class extends Error {
1635
2044
  code;
@@ -1885,7 +2294,17 @@ var ConsumerScope = class {
1885
2294
  { client: this.client }
1886
2295
  ),
1887
2296
  /**
1888
- * PAK-required: caller must instantiate `Auth` with
2297
+ * Mint a 6-digit password-reset code. **Sends no email.** Returns
2298
+ * `{ code, expires_at }` for delivery via your own channel — or
2299
+ * `{}` when the contact doesn't match a verified account (uniform
2300
+ * shape — no account enumeration).
2301
+ *
2302
+ * If you want Mail to deliver the code for you, call
2303
+ * {@link sendPasswordResetEmail} instead. Calling this one and
2304
+ * discarding the `code` means the user never hears anything.
2305
+ *
2306
+ * PAK-required with `auth.user.password-reset.create`: caller must
2307
+ * instantiate `Auth` with
1889
2308
  * `auth: { type: "apiKey", key: "pcft_live_..." }`. The
1890
2309
  * kubb-generated `headers.authorization` slot is a stub — the
1891
2310
  * HTTP client's auth middleware overrides whatever's passed.
@@ -1894,6 +2313,31 @@ var ConsumerScope = class {
1894
2313
  { appSlug: this.appSlug, data, headers: { authorization: "" } },
1895
2314
  { client: this.client }
1896
2315
  ),
2316
+ /**
2317
+ * Mint + dispatch a password-reset email via Mail in one call.
2318
+ * Returns `{ expires_at }` on success; the plaintext code is NOT
2319
+ * returned. Returns `{}` when the contact is missing or unverified
2320
+ * (same enumeration defence as {@link requestReset}).
2321
+ *
2322
+ * This is the counterpart to {@link sendVerificationEmail} for the
2323
+ * reset slot, and the method you want for a plain "forgot
2324
+ * password" flow — {@link requestReset} only mints, it does not
2325
+ * email.
2326
+ *
2327
+ * PAK-required with `auth.user.password-reset.send-email` —
2328
+ * distinct permission from the bare mint so customers can enable
2329
+ * mint without enabling outbound Mail traffic. Surfaces typed 412
2330
+ * precondition errors (e.g. `ENVOI_NOT_ENABLED`,
2331
+ * `ENVOI_TEMPLATE_NOT_CONFIGURED`) rather than failing silently.
2332
+ */
2333
+ sendPasswordResetEmail: (data) => consumerAuthControllerSendPasswordResetEmail(
2334
+ {
2335
+ appSlug: this.appSlug,
2336
+ data,
2337
+ headers: { authorization: "" }
2338
+ },
2339
+ { client: this.client }
2340
+ ),
1897
2341
  resetPassword: (data) => consumerAuthControllerResetPassword(
1898
2342
  { appSlug: this.appSlug, data },
1899
2343
  { client: this.client }
@@ -2049,6 +2493,141 @@ var ConsumerScope = class {
2049
2493
  )
2050
2494
  };
2051
2495
  // ─────────────────────────────────────────────────────────────
2496
+ // Passkeys — WebAuthn ceremonies, one call each. BROWSER ONLY at
2497
+ // call time (they drive navigator.credentials); importing is safe
2498
+ // anywhere. Base64url in both directions is handled here; the
2499
+ // wire stays snake_case except the spec-fixed response members
2500
+ // (clientDataJSON, attestationObject, authenticatorData, signature,
2501
+ // userHandle), which travel verbatim.
2502
+ // ─────────────────────────────────────────────────────────────
2503
+ passkeys = {
2504
+ /**
2505
+ * Enrol a passkey as an MFA factor for the signed-in end-user.
2506
+ * Requires the scope to carry the user's access token
2507
+ * (`new Auth({ auth: { type: "bearer", token } })`).
2508
+ *
2509
+ * `POST /me/mfa/factors { type: "webauthn" }` →
2510
+ * `navigator.credentials.create()` →
2511
+ * `POST /me/mfa/factors/:id/verify { credential }`.
2512
+ *
2513
+ * Resolves with the now-enabled factor and the user's recovery
2514
+ * codes — show those once, they are not retrievable later. The
2515
+ * factor stays disabled until the verify call succeeds, so an
2516
+ * abandoned prompt leaves nothing usable behind.
2517
+ */
2518
+ enroll: async (opts = {}) => {
2519
+ const credentials = resolveCredentials(opts);
2520
+ const start = await consumerMfaControllerStartEnrollment(
2521
+ {
2522
+ appSlug: this.appSlug,
2523
+ data: { type: "webauthn", ...opts.label ? { label: opts.label } : {} }
2524
+ },
2525
+ { client: this.client }
2526
+ );
2527
+ const publicKey = start.enrollment.public_key;
2528
+ const credential = await createPasskeyCredential(publicKey, { ...opts, credentials });
2529
+ return await consumerMfaControllerConfirmEnrollment(
2530
+ { appSlug: this.appSlug, id: start.factor.id, data: { credential } },
2531
+ { client: this.client }
2532
+ );
2533
+ },
2534
+ /**
2535
+ * Passwordless sign-in with a discoverable passkey. No password,
2536
+ * no email address: the authenticator finds its own passkey for
2537
+ * the app's rp_id.
2538
+ *
2539
+ * `POST /auth/passkey/options {}` → `navigator.credentials.get()`
2540
+ * → `POST /auth/passkey/verify { credential }`.
2541
+ *
2542
+ * Resolves with the session (`access_token`, `refresh_token`,
2543
+ * …; `amr: ["webauthn"]`). Rejects with `PasskeyError`
2544
+ * (`code: "cancelled"`) when the user dismisses the prompt or no
2545
+ * passkey matches, and with `AuthHttpError` 401 for a forged,
2546
+ * unknown, replayed or expired assertion — the server answers
2547
+ * those uniformly on purpose.
2548
+ *
2549
+ * The options call deliberately takes no identifier (it would be
2550
+ * an account-existence oracle); `tenant_id` is the only
2551
+ * accepted body member and only matters for multi-tenant apps.
2552
+ * Pass `mediation: "conditional"` for autofill-style UI.
2553
+ */
2554
+ signIn: async (opts = {}) => {
2555
+ const credentials = resolveCredentials(opts);
2556
+ const { public_key } = await consumerAuthControllerPasskeyOptions(
2557
+ {
2558
+ appSlug: this.appSlug,
2559
+ data: opts.tenant_id ? { tenant_id: opts.tenant_id } : {}
2560
+ },
2561
+ { client: this.client }
2562
+ );
2563
+ const credential = await getPasskeyCredential(
2564
+ public_key,
2565
+ { ...opts, credentials }
2566
+ );
2567
+ return await consumerAuthControllerPasskeyVerify(
2568
+ { appSlug: this.appSlug, data: { credential } },
2569
+ { client: this.client }
2570
+ );
2571
+ },
2572
+ /**
2573
+ * Satisfy the MFA step of a password sign-in with a passkey.
2574
+ * Call it when `auth.signin()` answered
2575
+ * `{ mfa_required: true, mfa_token, factors }` and `factors`
2576
+ * contains a `webauthn` entry.
2577
+ *
2578
+ * `POST /auth/mfa/webauthn/options { mfa_token }` →
2579
+ * `navigator.credentials.get()` →
2580
+ * `POST /auth/mfa/verify { mfa_token, credential }`.
2581
+ *
2582
+ * Resolves with the session (`amr: ["pwd", "webauthn"]`, fresh
2583
+ * `mfa_at`). Possession of the `mfa_token` — a correct password
2584
+ * — is the authority for the options call.
2585
+ */
2586
+ completeMfaChallenge: async (args) => {
2587
+ const { mfa_token, ...browserOpts } = args;
2588
+ const credentials = resolveCredentials(browserOpts);
2589
+ const { public_key } = await consumerAuthControllerMfaWebauthnOptions(
2590
+ { appSlug: this.appSlug, data: { mfa_token } },
2591
+ { client: this.client }
2592
+ );
2593
+ const credential = await getPasskeyCredential(
2594
+ public_key,
2595
+ { ...browserOpts, credentials }
2596
+ );
2597
+ return await consumerAuthControllerMfaVerify(
2598
+ { appSlug: this.appSlug, data: { mfa_token, credential } },
2599
+ { client: this.client }
2600
+ );
2601
+ },
2602
+ /**
2603
+ * Re-confirm the signed-in user's identity inside a live session
2604
+ * (before a sensitive action). Requires the scope to carry the
2605
+ * user's access token.
2606
+ *
2607
+ * `POST /me/mfa/step-up/webauthn/options` →
2608
+ * `navigator.credentials.get()` →
2609
+ * `POST /me/mfa/step-up { credential }`.
2610
+ *
2611
+ * Resolves with `{ amr, mfa_at }`. A passkey assertion is never
2612
+ * tried as a recovery code, so a failed step-up never burns one.
2613
+ */
2614
+ stepUp: async (opts = {}) => {
2615
+ const credentials = resolveCredentials(opts);
2616
+ const { public_key } = await consumerMfaControllerStepUpWebauthnOptions(
2617
+ { appSlug: this.appSlug },
2618
+ { client: this.client }
2619
+ );
2620
+ const credential = await getPasskeyCredential(
2621
+ public_key,
2622
+ { ...opts, credentials }
2623
+ );
2624
+ return await consumerMfaControllerStepUp(
2625
+ { appSlug: this.appSlug, data: { credential } },
2626
+ { client: this.client }
2627
+ );
2628
+ }
2629
+ };
2630
+ // ─────────────────────────────────────────────────────────────
2052
2631
  // OAuth M2M — client_credentials grant for service-to-service tokens
2053
2632
  // ─────────────────────────────────────────────────────────────
2054
2633
  oauth = {
@@ -2067,9 +2646,9 @@ function getAppControllerListMyAppsUrl() {
2067
2646
  async function appControllerListMyApps({ params } = {}, config = {}) {
2068
2647
  const { client: request = client, ...requestConfig } = config;
2069
2648
  const mappedParams = params ? {
2649
+ workspace_id: params.workspaceId,
2070
2650
  limit: params.limit,
2071
- cursor: params.cursor,
2072
- workspace_id: params.workspaceId
2651
+ cursor: params.cursor
2073
2652
  } : void 0;
2074
2653
  const res = await request({
2075
2654
  method: "GET",
@@ -2192,6 +2771,6 @@ var Auth = class {
2192
2771
  };
2193
2772
  };
2194
2773
 
2195
- export { AUTH_LEGACY_ISSUER, AppScope, Auth, AuthHttpError, ConsumerScope, JwksCache, JwksFetchError, JwksKeyNotFoundError, JwtAudienceMismatchError, JwtExpiredError, JwtInvalidError, JwtIssuerMismatchError, JwtNotYetValidError, JwtVerifyError, verifyAuthToken };
2774
+ export { AUTH_LEGACY_ISSUER, AppScope, Auth, AuthHttpError, ConsumerScope, JwksCache, JwksFetchError, JwksKeyNotFoundError, JwtAudienceMismatchError, JwtExpiredError, JwtInvalidError, JwtIssuerMismatchError, JwtNotYetValidError, JwtVerifyError, PasskeyError, createPasskeyCredential, decodeOptions, encodeCredential, fromB64u, getPasskeyCredential, isPasskeySupported, toB64u, verifyAuthToken };
2196
2775
  //# sourceMappingURL=index.js.map
2197
2776
  //# sourceMappingURL=index.js.map