cauthy-auth 0.24.3 → 0.26.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
@@ -633,6 +633,13 @@ function checkName(value) {
633
633
  if (typeof value !== "string" || value.trim().length > MAX_NAME) return { field: "name", code: "too_long", message: `Use at most ${MAX_NAME} characters.` };
634
634
  return null;
635
635
  }
636
+ var MAX_ORGANIZATION = 120;
637
+ function checkOrganization(value, required = false) {
638
+ const v = typeof value === "string" ? value.trim() : "";
639
+ if (v === "") return required ? { field: "organization", code: "required", message: "Enter your company's name." } : null;
640
+ if (v.length > MAX_ORGANIZATION) return { field: "organization", code: "too_long", message: `Use at most ${MAX_ORGANIZATION} characters.` };
641
+ return null;
642
+ }
636
643
  function checkCode(value) {
637
644
  const v = typeof value === "string" ? value.trim() : "";
638
645
  if (v === "") return { field: "code", code: "required", message: "Enter the code." };
@@ -1188,6 +1195,7 @@ function createCauthy(given = {}) {
1188
1195
  "/me/mfa/phone/remove",
1189
1196
  "/sign-in/mfa/methods",
1190
1197
  "/sign-in/mfa/send",
1198
+ "/sign-in/mfa/email",
1191
1199
  "/sign-in/mfa/push",
1192
1200
  "/sign-in/mfa/push/events",
1193
1201
  "/sign-in/mfa/push/finish",
@@ -1242,6 +1250,8 @@ function createCauthy(given = {}) {
1242
1250
  return json({
1243
1251
  providers: list.map((p) => ({ id: String(p.provider ?? p.id ?? ""), name: String(p.label ?? p.name ?? p.provider ?? "") })).filter((p) => p.id !== ""),
1244
1252
  signUp: settings.data?.allow_signup !== false,
1253
+ // The application's system makes an organization per sign-up: the form asks the company's name.
1254
+ ...settings.data?.signup?.organization?.ask === true ? { organization: { ask: true, required: settings.data.signup.organization.required === true } } : {},
1245
1255
  // A sign-in link needs a page of the application to open.
1246
1256
  magicLink: settings.data?.allow_magic_link === true && pages.signIn !== void 0,
1247
1257
  passkey: place.error ? true : here || place.data?.on_cauthy === true,
@@ -1479,7 +1489,8 @@ function createCauthy(given = {}) {
1479
1489
  if (res.error) return problem(res.status, res.error.code, res.error.message);
1480
1490
  if (res.data?.mfa_required === true) {
1481
1491
  const step = { kind: "mfa", token: String(res.data.mfa_token ?? ""), returnTo: afterSignIn };
1482
- return json({ status: "mfa_required" }, 200, new Headers({ "set-cookie": writeCookie(stepCookie, await seal(step, await key), attrs(request, STEP_SECONDS)) }));
1492
+ const how = res.data.mfa_method === "email" ? { method: "email" } : {};
1493
+ return json({ status: "mfa_required", ...how }, 200, new Headers({ "set-cookie": writeCookie(stepCookie, await seal(step, await key), attrs(request, STEP_SECONDS)) }));
1483
1494
  }
1484
1495
  return signedIn(request, res.data);
1485
1496
  }
@@ -1506,7 +1517,7 @@ function createCauthy(given = {}) {
1506
1517
  if (res.error) return problem(res.status, res.error.code, res.error.message);
1507
1518
  return signedIn(request, res.data, [writeCookie(stepCookie, "", attrs(request, 0))]);
1508
1519
  }
1509
- if (route === "/sign-in/mfa/methods" || route === "/sign-in/mfa/send") {
1520
+ if (route === "/sign-in/mfa/methods" || route === "/sign-in/mfa/send" || route === "/sign-in/mfa/email") {
1510
1521
  const sealed = readCookies(request.headers.get("cookie")).get(stepCookie);
1511
1522
  const step = sealed ? await unseal(sealed, await key) : null;
1512
1523
  if (step === null || step.kind !== "mfa") return problem(400, "step_expired", "Sign in again: the code was asked for too long ago.");
@@ -1515,22 +1526,30 @@ function createCauthy(given = {}) {
1515
1526
  if (res2.error) return problem(res2.status, res2.error.code, res2.error.message);
1516
1527
  const p = res2.data?.phone;
1517
1528
  const push = res2.data?.push;
1529
+ const mail = res2.data?.email;
1518
1530
  return json({
1519
1531
  status: "ok",
1520
1532
  totp: res2.data?.totp === true,
1521
1533
  phone: p ? { number: String(p.number ?? ""), channel: String(p.channel ?? "sms") } : null,
1522
- push: push ? { devices: Number(push.devices ?? 0) } : null
1534
+ push: push ? { devices: Number(push.devices ?? 0) } : null,
1535
+ email: mail ? { to: String(mail.to ?? "") } : null
1523
1536
  });
1524
1537
  }
1538
+ if (route === "/sign-in/mfa/email") {
1539
+ const res2 = await ask(request, "POST", "/v1/auth/mfa/email", { mfa_token: step.token });
1540
+ if (res2.error) return problem(res2.status, res2.error.code, res2.error.message);
1541
+ return json({ status: "sent", sentTo: String(res2.data?.sent_to ?? "") });
1542
+ }
1525
1543
  const res = await ask(request, "POST", "/v1/auth/mfa/send", { mfa_token: step.token });
1526
1544
  if (res.error) return problem(res.status, res.error.code, res.error.message);
1527
1545
  return json({ status: "sent", sentTo: String(res.data?.sent_to ?? ""), channel: String(res.data?.channel ?? "sms") });
1528
1546
  }
1529
1547
  if (route === "/sign-up/email") {
1530
- const bad = firstProblem(checkName(b.name), checkEmail(b.email), checkNewPassword(b.password));
1548
+ const bad = firstProblem(checkName(b.name), checkEmail(b.email), checkNewPassword(b.password), checkOrganization(b.organization));
1531
1549
  if (bad) return invalid(bad);
1532
1550
  const email = String(b.email).trim();
1533
- const made = await ask(request, "POST", "/v1/auth/register", { email, password: b.password, display_name: typeof b.name === "string" ? b.name.trim() : "" }, pages.verifyEmail);
1551
+ const organization = typeof b.organization === "string" && b.organization.trim() !== "" ? { organization: { name: b.organization.trim() } } : {};
1552
+ 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);
1534
1553
  if (made.error) return problem(made.status, made.error.code, made.error.message);
1535
1554
  if (made.data?.verification_required === true) return json({ status: "verification_required", email });
1536
1555
  const res = await ask(request, "POST", "/v1/auth/login", { email, password: b.password });
@@ -1732,6 +1751,7 @@ function createCauthy(given = {}) {
1732
1751
  if (!isToken(b.token)) return badLink();
1733
1752
  const res = await ask(request, "POST", "/v1/auth/email/verify", { token: String(b.token) });
1734
1753
  if (res.error) return problem(res.status, res.error.code, res.error.message);
1754
+ if (res.data?.access_token) return signedIn(request, res.data);
1735
1755
  return json({ status: "verified" });
1736
1756
  }
1737
1757
  if (route === "/sign-in/passkey/begin") {