cauthy-auth 0.20.0 → 0.23.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/{cauthy-Bn3iv50y.d.ts → cauthy-DGAy45G2.d.ts} +1 -1
- package/dist/{cauthy-C29HCvag.d.mts → cauthy-XkIbG5gE.d.mts} +1 -1
- package/dist/client.d.mts +133 -3
- package/dist/client.d.ts +133 -3
- package/dist/client.js +54 -0
- package/dist/client.js.map +1 -1
- package/dist/client.mjs +54 -0
- package/dist/client.mjs.map +1 -1
- package/dist/express.d.mts +2 -2
- package/dist/express.d.ts +2 -2
- package/dist/fastify.d.mts +2 -2
- package/dist/fastify.d.ts +2 -2
- package/dist/hono.d.mts +2 -2
- package/dist/hono.d.ts +2 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +178 -5
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +178 -5
- package/dist/index.mjs.map +1 -1
- package/dist/next.d.mts +2 -2
- package/dist/next.d.ts +2 -2
- package/dist/react.d.mts +171 -2
- package/dist/react.d.ts +171 -2
- package/dist/react.js +261 -3
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +260 -3
- package/dist/react.mjs.map +1 -1
- package/dist/svelte.d.mts +2 -2
- package/dist/svelte.d.ts +2 -2
- package/dist/svelte.js +54 -0
- package/dist/svelte.js.map +1 -1
- package/dist/svelte.mjs +54 -0
- package/dist/svelte.mjs.map +1 -1
- package/dist/{system-ZD_Wa8Bm.d.mts → system-BxMsSIu1.d.mts} +2 -0
- package/dist/{system-DhRr_WxR.d.ts → system-DTIeDXDP.d.ts} +2 -0
- package/dist/vue.d.mts +2 -2
- package/dist/vue.d.ts +2 -2
- package/dist/vue.js +54 -0
- package/dist/vue.js.map +1 -1
- package/dist/vue.mjs +54 -0
- package/dist/vue.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -837,7 +837,8 @@ function createCauthy(given = {}) {
|
|
|
837
837
|
emailVerified: b.email_verified === true,
|
|
838
838
|
restricted: b.restricted === true,
|
|
839
839
|
...typeof b.email_verify_by === "string" ? { emailVerifyBy: b.email_verify_by } : {},
|
|
840
|
-
...typeof b.locale === "string" && b.locale !== "" ? { locale: b.locale } : {}
|
|
840
|
+
...typeof b.locale === "string" && b.locale !== "" ? { locale: b.locale } : {},
|
|
841
|
+
...b.anonymous === true ? { isAnonymous: true } : {}
|
|
841
842
|
}
|
|
842
843
|
};
|
|
843
844
|
} catch {
|
|
@@ -1046,6 +1047,32 @@ function createCauthy(given = {}) {
|
|
|
1046
1047
|
createdAt: String(d?.created_at ?? ""),
|
|
1047
1048
|
lastUsedAt: d?.last_used_at ? String(d.last_used_at) : null
|
|
1048
1049
|
});
|
|
1050
|
+
const UUID = /^[0-9a-f-]{36}$/i;
|
|
1051
|
+
const seatOf = (d) => ({
|
|
1052
|
+
id: String(d?.id ?? ""),
|
|
1053
|
+
system: String(d?.system ?? ""),
|
|
1054
|
+
name: String(d?.name ?? ""),
|
|
1055
|
+
kind: String(d?.kind ?? ""),
|
|
1056
|
+
role: String(d?.role ?? ""),
|
|
1057
|
+
can: { readMembers: d?.can?.read_members === true, manageMembers: d?.can?.manage_members === true }
|
|
1058
|
+
});
|
|
1059
|
+
const orgMemberOf = (d) => ({
|
|
1060
|
+
userId: String(d?.user_id ?? ""),
|
|
1061
|
+
email: String(d?.email ?? ""),
|
|
1062
|
+
name: String(d?.name ?? ""),
|
|
1063
|
+
role: String(d?.role ?? ""),
|
|
1064
|
+
status: String(d?.status ?? ""),
|
|
1065
|
+
invited: d?.invited === true,
|
|
1066
|
+
manager: d?.manager === true,
|
|
1067
|
+
you: d?.you === true,
|
|
1068
|
+
since: String(d?.since ?? "")
|
|
1069
|
+
});
|
|
1070
|
+
const orgRoleOf = (d) => ({
|
|
1071
|
+
role: String(d?.role ?? ""),
|
|
1072
|
+
name: String(d?.name ?? ""),
|
|
1073
|
+
description: String(d?.description ?? ""),
|
|
1074
|
+
manager: d?.manager === true
|
|
1075
|
+
});
|
|
1049
1076
|
const agentOf = (d) => ({
|
|
1050
1077
|
id: String(d?.id ?? ""),
|
|
1051
1078
|
name: String(d?.agent?.name ?? ""),
|
|
@@ -1164,6 +1191,9 @@ function createCauthy(given = {}) {
|
|
|
1164
1191
|
"/me/mfa/phone/remove",
|
|
1165
1192
|
"/sign-in/mfa/methods",
|
|
1166
1193
|
"/sign-in/mfa/send",
|
|
1194
|
+
"/sign-in/mfa/push",
|
|
1195
|
+
"/sign-in/mfa/push/events",
|
|
1196
|
+
"/sign-in/mfa/push/finish",
|
|
1167
1197
|
"/me/sessions",
|
|
1168
1198
|
"/me/sessions/end",
|
|
1169
1199
|
"/me/email",
|
|
@@ -1181,8 +1211,17 @@ function createCauthy(given = {}) {
|
|
|
1181
1211
|
"/me/passkeys/add/finish",
|
|
1182
1212
|
"/me/passkeys/remove",
|
|
1183
1213
|
"/me/agents",
|
|
1184
|
-
"/me/agents/disconnect"
|
|
1185
|
-
|
|
1214
|
+
"/me/agents/disconnect",
|
|
1215
|
+
"/sign-in/anonymous",
|
|
1216
|
+
"/me/upgrade",
|
|
1217
|
+
"/me/organizations",
|
|
1218
|
+
"/me/organizations/members",
|
|
1219
|
+
"/me/organizations/roles",
|
|
1220
|
+
"/me/organizations/members/add",
|
|
1221
|
+
"/me/organizations/members/role",
|
|
1222
|
+
"/me/organizations/members/remove",
|
|
1223
|
+
"/me/organizations/members/invite"
|
|
1224
|
+
].includes(route) || route.startsWith("/sign-in/social/") || route.startsWith("/callback/") || route.startsWith("/me/identities/link/") || route.startsWith("/me/upgrade/social/") || route === "/sign-in/sso" || route === "/sign-in/sso/discover" || route === "/sso/callback";
|
|
1186
1225
|
if (!own) return null;
|
|
1187
1226
|
if (tenant === "") {
|
|
1188
1227
|
return problem(500, "not_configured", "cauthy-auth: tenant (CAUTHY_TENANT) is required for the application's own sign-in screens");
|
|
@@ -1270,10 +1309,19 @@ function createCauthy(given = {}) {
|
|
|
1270
1309
|
const clear = writeCookie(stepCookie, "", attrs(request, 0));
|
|
1271
1310
|
const back = step?.returnTo ?? afterSignIn;
|
|
1272
1311
|
const failedTo = (code2) => redirect(`${back}${back.includes("?") ? "&" : "?"}auth_error=${encodeURIComponent(code2)}`, [clear]);
|
|
1273
|
-
if (step === null || step.kind !== "social" && step.kind !== "link" || step.provider !== provider || url.searchParams.get("state") !== step.token) return failedTo("state_mismatch");
|
|
1312
|
+
if (step === null || step.kind !== "social" && step.kind !== "link" && step.kind !== "upgrade" || step.provider !== provider || url.searchParams.get("state") !== step.token) return failedTo("state_mismatch");
|
|
1274
1313
|
const code = url.searchParams.get("code");
|
|
1275
1314
|
if (!code) return failedTo(url.searchParams.get("error") === "access_denied" ? "cancelled" : "provider_refused");
|
|
1276
1315
|
const q = new URLSearchParams({ code, state: step.token, redirect_uri: `${originOf(request)}${basePath}/callback/${provider}` });
|
|
1316
|
+
if (step.kind === "upgrade") {
|
|
1317
|
+
const mine = await signedInAs(request);
|
|
1318
|
+
if ("response" in mine) return failedTo("unauthenticated");
|
|
1319
|
+
const done2 = await ask(request, "GET", `/v1/auth/anonymous/upgrade/${provider}/callback?${q}`, void 0, void 0, mine.token);
|
|
1320
|
+
if (done2.error) return failedTo(done2.error.code);
|
|
1321
|
+
const s2 = await stored(done2.data);
|
|
1322
|
+
if (s2 === null) return failedTo("unavailable");
|
|
1323
|
+
return redirect(back, [...await write(request, s2, readCookies(request.headers.get("cookie"))), clear]);
|
|
1324
|
+
}
|
|
1277
1325
|
if (step.kind === "link") {
|
|
1278
1326
|
const mine = await signedInAs(request);
|
|
1279
1327
|
if ("response" in mine) return failedTo("unauthenticated");
|
|
@@ -1289,6 +1337,19 @@ function createCauthy(given = {}) {
|
|
|
1289
1337
|
if (s === null) return failedTo("unavailable");
|
|
1290
1338
|
return redirect(back, [...await write(request, s, readCookies(request.headers.get("cookie"))), clear]);
|
|
1291
1339
|
}
|
|
1340
|
+
if (route.startsWith("/me/upgrade/social/") && !post) {
|
|
1341
|
+
const provider = providerIn(route.slice("/me/upgrade/social/".length));
|
|
1342
|
+
if (!PROVIDER_ID.test(provider)) return new Response("Not found", { status: 404 });
|
|
1343
|
+
const returnTo = localPath(url.searchParams.get("return_to"), afterSignIn);
|
|
1344
|
+
const failed2 = (code) => redirect(`${returnTo}${returnTo.includes("?") ? "&" : "?"}auth_error=${encodeURIComponent(code)}`);
|
|
1345
|
+
const mine = await signedInAs(request);
|
|
1346
|
+
if ("response" in mine) return failed2("unauthenticated");
|
|
1347
|
+
const callback2 = `${basePath}/callback/${provider}`;
|
|
1348
|
+
const started = await ask(request, "GET", `/v1/auth/anonymous/upgrade/${provider}?redirect_uri=${encodeURIComponent(`${originOf(request)}${callback2}`)}`, void 0, callback2, mine.token);
|
|
1349
|
+
if (started.error || typeof started.data?.redirect_url !== "string") return failed2(started.error?.code ?? "provider_unavailable");
|
|
1350
|
+
const step = { kind: "upgrade", token: String(started.data.state ?? ""), provider, returnTo };
|
|
1351
|
+
return redirect(started.data.redirect_url, [...mine.headers.getSetCookie(), writeCookie(stepCookie, await seal(step, await key), attrs(request, STEP_SECONDS))]);
|
|
1352
|
+
}
|
|
1292
1353
|
if (route.startsWith("/me/identities/link/") && !post) {
|
|
1293
1354
|
const provider = providerIn(route.slice("/me/identities/link/".length));
|
|
1294
1355
|
if (!PROVIDER_ID.test(provider)) return new Response("Not found", { status: 404 });
|
|
@@ -1326,6 +1387,24 @@ function createCauthy(given = {}) {
|
|
|
1326
1387
|
const list = Array.isArray(res.data) ? res.data : [];
|
|
1327
1388
|
return json({ agents: list.map(agentOf) }, 200, mine.headers);
|
|
1328
1389
|
}
|
|
1390
|
+
if ((route === "/me/organizations" || route === "/me/organizations/members" || route === "/me/organizations/roles") && !post) {
|
|
1391
|
+
const mine = await signedInAs(request);
|
|
1392
|
+
if ("response" in mine) return mine.response;
|
|
1393
|
+
let path = "/v1/auth/me/organizations";
|
|
1394
|
+
if (route !== "/me/organizations") {
|
|
1395
|
+
const id = url.searchParams.get("id") ?? "";
|
|
1396
|
+
if (!UUID.test(id)) return problem(400, "invalid_organization", "Say which organization.", void 0, mine.headers);
|
|
1397
|
+
path += `/${id}/${route.endsWith("/roles") ? "roles" : "members"}`;
|
|
1398
|
+
} else if (url.searchParams.get("system")) {
|
|
1399
|
+
path += `?system=${encodeURIComponent(url.searchParams.get("system"))}`;
|
|
1400
|
+
}
|
|
1401
|
+
const res = await ask(request, "GET", path, void 0, void 0, mine.token);
|
|
1402
|
+
if (res.error) return problem(res.status, res.error.code, res.error.message, void 0, mine.headers);
|
|
1403
|
+
const list = Array.isArray(res.data) ? res.data : [];
|
|
1404
|
+
if (route === "/me/organizations") return json({ organizations: list.map(seatOf) }, 200, mine.headers);
|
|
1405
|
+
if (route === "/me/organizations/roles") return json({ roles: list.map(orgRoleOf) }, 200, mine.headers);
|
|
1406
|
+
return json({ members: list.map(orgMemberOf) }, 200, mine.headers);
|
|
1407
|
+
}
|
|
1329
1408
|
if (route === "/me/mfa/factors" && !post) {
|
|
1330
1409
|
const mine = await signedInAs(request);
|
|
1331
1410
|
if ("response" in mine) return mine.response;
|
|
@@ -1344,6 +1423,28 @@ function createCauthy(given = {}) {
|
|
|
1344
1423
|
}
|
|
1345
1424
|
return json({ account: accountOf(res.data) }, 200, mine.headers);
|
|
1346
1425
|
}
|
|
1426
|
+
if (route === "/sign-in/mfa/push/events" && !post) {
|
|
1427
|
+
const sealed = readCookies(request.headers.get("cookie")).get(stepCookie);
|
|
1428
|
+
const step = sealed ? await unseal(sealed, await key) : null;
|
|
1429
|
+
if (step === null || step.kind !== "mfa") return problem(400, "step_expired", "Sign in again: the code was asked for too long ago.");
|
|
1430
|
+
let upstream;
|
|
1431
|
+
try {
|
|
1432
|
+
upstream = await doFetch(`${issuer}/v1/auth/mfa/push/events`, {
|
|
1433
|
+
headers: { "x-tenant-key": tenant, "x-mfa-token": step.token, accept: "text/event-stream" },
|
|
1434
|
+
signal: request.signal
|
|
1435
|
+
});
|
|
1436
|
+
} catch {
|
|
1437
|
+
return problem(503, "unavailable", "Cauthy could not be reached.");
|
|
1438
|
+
}
|
|
1439
|
+
if (!upstream.ok || !upstream.body) {
|
|
1440
|
+
const b2 = await upstream.json().catch(() => null);
|
|
1441
|
+
return problem(upstream.status, String(b2?.errors?.[0]?.code ?? "error"), String(b2?.errors?.[0]?.message ?? "The request could not be completed."));
|
|
1442
|
+
}
|
|
1443
|
+
return new Response(upstream.body, {
|
|
1444
|
+
status: 200,
|
|
1445
|
+
headers: { "content-type": "text/event-stream", "cache-control": "no-cache, no-store", "x-accel-buffering": "no" }
|
|
1446
|
+
});
|
|
1447
|
+
}
|
|
1347
1448
|
if (!post) return new Response("Method not allowed", { status: 405, headers: { allow: "POST" } });
|
|
1348
1449
|
if (!ownRequest(request)) return problem(403, "cross_site", "This request did not come from this application.");
|
|
1349
1450
|
if (route === "/sign-out") {
|
|
@@ -1368,6 +1469,12 @@ function createCauthy(given = {}) {
|
|
|
1368
1469
|
const c = res.data?.connection;
|
|
1369
1470
|
return json(c ? { status: "found", connection: { id: String(c.slug ?? ""), name: String(c.display_name ?? ""), enforced: c.enforced === true } } : { status: "none" });
|
|
1370
1471
|
}
|
|
1472
|
+
if (route === "/sign-in/anonymous") {
|
|
1473
|
+
if (!post) return new Response("Method not allowed", { status: 405, headers: { allow: "POST" } });
|
|
1474
|
+
const res = await ask(request, "POST", "/v1/auth/anonymous", {});
|
|
1475
|
+
if (res.error) return problem(res.status, res.error.code, res.error.message);
|
|
1476
|
+
return signedIn(request, res.data);
|
|
1477
|
+
}
|
|
1371
1478
|
if (route === "/sign-in/email") {
|
|
1372
1479
|
const bad = firstProblem(checkEmail(b.email), checkPassword(b.password));
|
|
1373
1480
|
if (bad) return invalid(bad);
|
|
@@ -1389,6 +1496,19 @@ function createCauthy(given = {}) {
|
|
|
1389
1496
|
if (res.error) return problem(res.status, res.error.code, res.error.message, "code");
|
|
1390
1497
|
return signedIn(request, res.data, [writeCookie(stepCookie, "", attrs(request, 0))]);
|
|
1391
1498
|
}
|
|
1499
|
+
if (route === "/sign-in/mfa/push" || route === "/sign-in/mfa/push/finish") {
|
|
1500
|
+
const sealed = readCookies(request.headers.get("cookie")).get(stepCookie);
|
|
1501
|
+
const step = sealed ? await unseal(sealed, await key) : null;
|
|
1502
|
+
if (step === null || step.kind !== "mfa") return problem(400, "step_expired", "Sign in again: the code was asked for too long ago.");
|
|
1503
|
+
if (route === "/sign-in/mfa/push") {
|
|
1504
|
+
const res2 = await ask(request, "POST", "/v1/auth/mfa/push", { mfa_token: step.token });
|
|
1505
|
+
if (res2.error) return problem(res2.status, res2.error.code, res2.error.message);
|
|
1506
|
+
return json({ status: "sent", number: Number(res2.data?.number ?? 0) });
|
|
1507
|
+
}
|
|
1508
|
+
const res = await ask(request, "POST", "/v1/auth/mfa/challenge", { mfa_token: step.token, push: true });
|
|
1509
|
+
if (res.error) return problem(res.status, res.error.code, res.error.message);
|
|
1510
|
+
return signedIn(request, res.data, [writeCookie(stepCookie, "", attrs(request, 0))]);
|
|
1511
|
+
}
|
|
1392
1512
|
if (route === "/sign-in/mfa/methods" || route === "/sign-in/mfa/send") {
|
|
1393
1513
|
const sealed = readCookies(request.headers.get("cookie")).get(stepCookie);
|
|
1394
1514
|
const step = sealed ? await unseal(sealed, await key) : null;
|
|
@@ -1397,7 +1517,13 @@ function createCauthy(given = {}) {
|
|
|
1397
1517
|
const res2 = await ask(request, "POST", "/v1/auth/mfa/methods", { mfa_token: step.token });
|
|
1398
1518
|
if (res2.error) return problem(res2.status, res2.error.code, res2.error.message);
|
|
1399
1519
|
const p = res2.data?.phone;
|
|
1400
|
-
|
|
1520
|
+
const push = res2.data?.push;
|
|
1521
|
+
return json({
|
|
1522
|
+
status: "ok",
|
|
1523
|
+
totp: res2.data?.totp === true,
|
|
1524
|
+
phone: p ? { number: String(p.number ?? ""), channel: String(p.channel ?? "sms") } : null,
|
|
1525
|
+
push: push ? { devices: Number(push.devices ?? 0) } : null
|
|
1526
|
+
});
|
|
1401
1527
|
}
|
|
1402
1528
|
const res = await ask(request, "POST", "/v1/auth/mfa/send", { mfa_token: step.token });
|
|
1403
1529
|
if (res.error) return problem(res.status, res.error.code, res.error.message);
|
|
@@ -1531,6 +1657,53 @@ function createCauthy(given = {}) {
|
|
|
1531
1657
|
if (res.error) return refused(res);
|
|
1532
1658
|
return json({ status: "removed", id }, 200, mine.headers);
|
|
1533
1659
|
}
|
|
1660
|
+
if (route === "/me/upgrade") {
|
|
1661
|
+
const bad = firstProblem(checkName(b.name), checkEmail(b.email), checkNewPassword(b.password));
|
|
1662
|
+
if (bad) return invalid(bad);
|
|
1663
|
+
const res = await as("/v1/auth/anonymous/upgrade", { email: String(b.email).trim(), password: b.password, display_name: typeof b.name === "string" ? b.name.trim() : "" });
|
|
1664
|
+
if (res.error) return refused(res, res.error.code === "weak_password" ? "password" : "email");
|
|
1665
|
+
return signedIn(request, res.data);
|
|
1666
|
+
}
|
|
1667
|
+
if (route.startsWith("/me/organizations/members/")) {
|
|
1668
|
+
const org = typeof b.organizationId === "string" ? b.organizationId : "";
|
|
1669
|
+
if (!UUID.test(org)) return problem(400, "invalid_organization", "Say which organization.", void 0, mine.headers);
|
|
1670
|
+
const base = `/v1/auth/me/organizations/${org}/members`;
|
|
1671
|
+
if (route === "/me/organizations/members/add") {
|
|
1672
|
+
const bad = checkEmail(b.email);
|
|
1673
|
+
if (bad) return invalid(bad);
|
|
1674
|
+
const role = typeof b.role === "string" ? b.role : "";
|
|
1675
|
+
if (role === "") return problem(400, "invalid_role", "Choose a role.", "role", mine.headers);
|
|
1676
|
+
const res = await as(base, {
|
|
1677
|
+
email: String(b.email).trim(),
|
|
1678
|
+
role,
|
|
1679
|
+
name: typeof b.name === "string" ? b.name.trim() : "",
|
|
1680
|
+
client_id: clientId,
|
|
1681
|
+
...typeof b.locale === "string" && b.locale ? { locale: b.locale } : {}
|
|
1682
|
+
});
|
|
1683
|
+
if (res.error) return refused(res, res.error.code === "unknown_role" ? "role" : "email");
|
|
1684
|
+
return json({ status: "added", member: orgMemberOf(res.data) }, 200, mine.headers);
|
|
1685
|
+
}
|
|
1686
|
+
const user = typeof b.userId === "string" ? b.userId : "";
|
|
1687
|
+
if (!UUID.test(user)) return problem(400, "invalid_member", "Say which member.", void 0, mine.headers);
|
|
1688
|
+
if (route === "/me/organizations/members/role") {
|
|
1689
|
+
const role = typeof b.role === "string" ? b.role : "";
|
|
1690
|
+
if (role === "") return problem(400, "invalid_role", "Choose a role.", "role", mine.headers);
|
|
1691
|
+
const res = await as(`${base}/${user}`, { role }, "PUT");
|
|
1692
|
+
if (res.error) return refused(res, "role");
|
|
1693
|
+
return json({ status: "changed", userId: user, role }, 200, mine.headers);
|
|
1694
|
+
}
|
|
1695
|
+
if (route === "/me/organizations/members/remove") {
|
|
1696
|
+
const res = await as(`${base}/${user}`, void 0, "DELETE");
|
|
1697
|
+
if (res.error) return refused(res);
|
|
1698
|
+
orgCache.delete(mine.token);
|
|
1699
|
+
return json({ status: "removed", userId: user }, 200, mine.headers);
|
|
1700
|
+
}
|
|
1701
|
+
if (route === "/me/organizations/members/invite") {
|
|
1702
|
+
const res = await as(`${base}/${user}/invite`, { client_id: clientId, ...typeof b.locale === "string" && b.locale ? { locale: b.locale } : {} });
|
|
1703
|
+
if (res.error) return refused(res);
|
|
1704
|
+
return json({ status: "sent", userId: user }, 200, mine.headers);
|
|
1705
|
+
}
|
|
1706
|
+
}
|
|
1534
1707
|
if (route === "/me/agents/disconnect") {
|
|
1535
1708
|
const id = typeof b.id === "string" ? b.id : "";
|
|
1536
1709
|
if (!/^[0-9a-f-]{36}$/i.test(id)) return problem(400, "invalid_agent", "Say which agent to disconnect.", void 0, mine.headers);
|