cauthy-auth 0.25.0 → 0.27.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.
package/dist/index.mjs CHANGED
@@ -1195,11 +1195,14 @@ function createCauthy(given = {}) {
1195
1195
  "/me/mfa/phone/remove",
1196
1196
  "/sign-in/mfa/methods",
1197
1197
  "/sign-in/mfa/send",
1198
+ "/sign-in/mfa/email",
1198
1199
  "/sign-in/mfa/push",
1199
1200
  "/sign-in/mfa/push/events",
1200
1201
  "/sign-in/mfa/push/finish",
1201
1202
  "/me/sessions",
1202
1203
  "/me/sessions/end",
1204
+ "/me/legal",
1205
+ "/me/legal/accept",
1203
1206
  "/me/email",
1204
1207
  "/me/identities",
1205
1208
  "/me/identities/unlink",
@@ -1258,6 +1261,8 @@ function createCauthy(given = {}) {
1258
1261
  passkeyOnCauthy: place.error ? true : place.data?.on_cauthy === true,
1259
1262
  // A company's sign-in, found by the person's work address.
1260
1263
  sso: Array.isArray(sso.data) && sso.data.some((c) => c?.discoverable === true),
1264
+ // The terms a sign-up accepts and the consents it answers, when the workspace asks any.
1265
+ ...settings.data?.legal ? { legal: legalOf(settings.data.legal) } : {},
1261
1266
  ...settings.data?.captcha_enabled === true && settings.data?.captcha_site_key ? { captchaSiteKey: String(settings.data.captcha_site_key) } : {}
1262
1267
  });
1263
1268
  }
@@ -1418,11 +1423,15 @@ function createCauthy(given = {}) {
1418
1423
  if (res.error) return problem(res.status, res.error.code, res.error.message, void 0, mine.headers);
1419
1424
  return json(factorsOf(res.data), 200, mine.headers);
1420
1425
  }
1421
- if ((route === "/me" || route === "/me/sessions") && !post) {
1426
+ if ((route === "/me" || route === "/me/sessions" || route === "/me/legal") && !post) {
1422
1427
  const mine = await signedInAs(request);
1423
1428
  if ("response" in mine) return mine.response;
1424
- const res = await ask(request, "GET", route === "/me" ? "/v1/auth/me" : "/v1/auth/me/sessions", void 0, void 0, mine.token);
1429
+ const res = await ask(request, "GET", route === "/me" ? "/v1/auth/me" : route === "/me/legal" ? "/v1/auth/me/legal" : "/v1/auth/me/sessions", void 0, void 0, mine.token);
1425
1430
  if (res.error) return problem(res.status, res.error.code, res.error.message, void 0, mine.headers);
1431
+ if (route === "/me/legal") {
1432
+ const list = Array.isArray(res.data?.pending) ? res.data.pending : [];
1433
+ return json({ pending: list.map((d) => ({ kind: String(d.kind ?? ""), version: String(d.version ?? ""), url: String(d.url ?? "") })) }, 200, mine.headers);
1434
+ }
1426
1435
  if (route === "/me/sessions") {
1427
1436
  const list = Array.isArray(res.data) ? res.data : [];
1428
1437
  return json({ sessions: list.map((x) => ({ device: String(x.device ?? ""), ip: String(x.ip ?? ""), createdAt: String(x.created_at ?? ""), expiresAt: String(x.expires_at ?? "") })) }, 200, mine.headers);
@@ -1488,7 +1497,8 @@ function createCauthy(given = {}) {
1488
1497
  if (res.error) return problem(res.status, res.error.code, res.error.message);
1489
1498
  if (res.data?.mfa_required === true) {
1490
1499
  const step = { kind: "mfa", token: String(res.data.mfa_token ?? ""), returnTo: afterSignIn };
1491
- return json({ status: "mfa_required" }, 200, new Headers({ "set-cookie": writeCookie(stepCookie, await seal(step, await key), attrs(request, STEP_SECONDS)) }));
1500
+ const how = res.data.mfa_method === "email" ? { method: "email" } : {};
1501
+ return json({ status: "mfa_required", ...how }, 200, new Headers({ "set-cookie": writeCookie(stepCookie, await seal(step, await key), attrs(request, STEP_SECONDS)) }));
1492
1502
  }
1493
1503
  return signedIn(request, res.data);
1494
1504
  }
@@ -1515,7 +1525,7 @@ function createCauthy(given = {}) {
1515
1525
  if (res.error) return problem(res.status, res.error.code, res.error.message);
1516
1526
  return signedIn(request, res.data, [writeCookie(stepCookie, "", attrs(request, 0))]);
1517
1527
  }
1518
- if (route === "/sign-in/mfa/methods" || route === "/sign-in/mfa/send") {
1528
+ if (route === "/sign-in/mfa/methods" || route === "/sign-in/mfa/send" || route === "/sign-in/mfa/email") {
1519
1529
  const sealed = readCookies(request.headers.get("cookie")).get(stepCookie);
1520
1530
  const step = sealed ? await unseal(sealed, await key) : null;
1521
1531
  if (step === null || step.kind !== "mfa") return problem(400, "step_expired", "Sign in again: the code was asked for too long ago.");
@@ -1524,13 +1534,20 @@ function createCauthy(given = {}) {
1524
1534
  if (res2.error) return problem(res2.status, res2.error.code, res2.error.message);
1525
1535
  const p = res2.data?.phone;
1526
1536
  const push = res2.data?.push;
1537
+ const mail = res2.data?.email;
1527
1538
  return json({
1528
1539
  status: "ok",
1529
1540
  totp: res2.data?.totp === true,
1530
1541
  phone: p ? { number: String(p.number ?? ""), channel: String(p.channel ?? "sms") } : null,
1531
- push: push ? { devices: Number(push.devices ?? 0) } : null
1542
+ push: push ? { devices: Number(push.devices ?? 0) } : null,
1543
+ email: mail ? { to: String(mail.to ?? "") } : null
1532
1544
  });
1533
1545
  }
1546
+ if (route === "/sign-in/mfa/email") {
1547
+ const res2 = await ask(request, "POST", "/v1/auth/mfa/email", { mfa_token: step.token });
1548
+ if (res2.error) return problem(res2.status, res2.error.code, res2.error.message);
1549
+ return json({ status: "sent", sentTo: String(res2.data?.sent_to ?? "") });
1550
+ }
1534
1551
  const res = await ask(request, "POST", "/v1/auth/mfa/send", { mfa_token: step.token });
1535
1552
  if (res.error) return problem(res.status, res.error.code, res.error.message);
1536
1553
  return json({ status: "sent", sentTo: String(res.data?.sent_to ?? ""), channel: String(res.data?.channel ?? "sms") });
@@ -1540,7 +1557,8 @@ function createCauthy(given = {}) {
1540
1557
  if (bad) return invalid(bad);
1541
1558
  const email = String(b.email).trim();
1542
1559
  const organization = typeof b.organization === "string" && b.organization.trim() !== "" ? { organization: { name: b.organization.trim() } } : {};
1543
- const made = await ask(request, "POST", "/v1/auth/register", { email, password: b.password, display_name: typeof b.name === "string" ? b.name.trim() : "", ...organization }, pages.verifyEmail);
1560
+ const legal = { ...b.acceptLegal === true ? { accept_legal: true } : {}, ...b.consents && typeof b.consents === "object" ? { consents: b.consents } : {} };
1561
+ const made = await ask(request, "POST", "/v1/auth/register", { email, password: b.password, display_name: typeof b.name === "string" ? b.name.trim() : "", ...organization, ...legal }, pages.verifyEmail);
1544
1562
  if (made.error) return problem(made.status, made.error.code, made.error.message);
1545
1563
  if (made.data?.verification_required === true) return json({ status: "verification_required", email });
1546
1564
  const res = await ask(request, "POST", "/v1/auth/login", { email, password: b.password });
@@ -1571,6 +1589,12 @@ function createCauthy(given = {}) {
1571
1589
  }
1572
1590
  return json({ status: "saved", account: accountOf(res.data) }, 200, h);
1573
1591
  }
1592
+ if (route === "/me/legal/accept") {
1593
+ const kinds = Array.isArray(b.kinds) ? b.kinds.filter((k) => typeof k === "string") : [];
1594
+ const res = await as("/v1/auth/me/legal/accept", { kinds });
1595
+ if (res.error) return refused(res);
1596
+ return json({ status: "accepted" }, 200, mine.headers);
1597
+ }
1574
1598
  if (route === "/me/password") {
1575
1599
  const bad = checkNewPassword(b.newPassword);
1576
1600
  if (bad) return problem(400, bad.code, bad.message, "newPassword");
@@ -1870,6 +1894,14 @@ function createCauthy(given = {}) {
1870
1894
  options: { issuer, clientId, basePath, afterSignIn, afterSignOut, cookieName }
1871
1895
  };
1872
1896
  }
1897
+ function legalOf(raw) {
1898
+ const documents = Array.isArray(raw?.documents) ? raw.documents : [];
1899
+ const purposes = Array.isArray(raw?.consent_purposes) ? raw.consent_purposes : [];
1900
+ return {
1901
+ documents: documents.map((d) => ({ kind: String(d.kind ?? ""), version: String(d.version ?? ""), url: String(d.url ?? "") })),
1902
+ consentPurposes: purposes.map((p) => ({ key: String(p.key ?? ""), label: String(p.label ?? ""), required: p.required === true }))
1903
+ };
1904
+ }
1873
1905
 
1874
1906
  // src/permissions.ts
1875
1907
  function matches(entry, resource, action) {