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.mjs
CHANGED
|
@@ -789,7 +789,8 @@ function createCauthy(given = {}) {
|
|
|
789
789
|
emailVerified: b.email_verified === true,
|
|
790
790
|
restricted: b.restricted === true,
|
|
791
791
|
...typeof b.email_verify_by === "string" ? { emailVerifyBy: b.email_verify_by } : {},
|
|
792
|
-
...typeof b.locale === "string" && b.locale !== "" ? { locale: b.locale } : {}
|
|
792
|
+
...typeof b.locale === "string" && b.locale !== "" ? { locale: b.locale } : {},
|
|
793
|
+
...b.anonymous === true ? { isAnonymous: true } : {}
|
|
793
794
|
}
|
|
794
795
|
};
|
|
795
796
|
} catch {
|
|
@@ -998,6 +999,32 @@ function createCauthy(given = {}) {
|
|
|
998
999
|
createdAt: String(d?.created_at ?? ""),
|
|
999
1000
|
lastUsedAt: d?.last_used_at ? String(d.last_used_at) : null
|
|
1000
1001
|
});
|
|
1002
|
+
const UUID = /^[0-9a-f-]{36}$/i;
|
|
1003
|
+
const seatOf = (d) => ({
|
|
1004
|
+
id: String(d?.id ?? ""),
|
|
1005
|
+
system: String(d?.system ?? ""),
|
|
1006
|
+
name: String(d?.name ?? ""),
|
|
1007
|
+
kind: String(d?.kind ?? ""),
|
|
1008
|
+
role: String(d?.role ?? ""),
|
|
1009
|
+
can: { readMembers: d?.can?.read_members === true, manageMembers: d?.can?.manage_members === true }
|
|
1010
|
+
});
|
|
1011
|
+
const orgMemberOf = (d) => ({
|
|
1012
|
+
userId: String(d?.user_id ?? ""),
|
|
1013
|
+
email: String(d?.email ?? ""),
|
|
1014
|
+
name: String(d?.name ?? ""),
|
|
1015
|
+
role: String(d?.role ?? ""),
|
|
1016
|
+
status: String(d?.status ?? ""),
|
|
1017
|
+
invited: d?.invited === true,
|
|
1018
|
+
manager: d?.manager === true,
|
|
1019
|
+
you: d?.you === true,
|
|
1020
|
+
since: String(d?.since ?? "")
|
|
1021
|
+
});
|
|
1022
|
+
const orgRoleOf = (d) => ({
|
|
1023
|
+
role: String(d?.role ?? ""),
|
|
1024
|
+
name: String(d?.name ?? ""),
|
|
1025
|
+
description: String(d?.description ?? ""),
|
|
1026
|
+
manager: d?.manager === true
|
|
1027
|
+
});
|
|
1001
1028
|
const agentOf = (d) => ({
|
|
1002
1029
|
id: String(d?.id ?? ""),
|
|
1003
1030
|
name: String(d?.agent?.name ?? ""),
|
|
@@ -1116,6 +1143,9 @@ function createCauthy(given = {}) {
|
|
|
1116
1143
|
"/me/mfa/phone/remove",
|
|
1117
1144
|
"/sign-in/mfa/methods",
|
|
1118
1145
|
"/sign-in/mfa/send",
|
|
1146
|
+
"/sign-in/mfa/push",
|
|
1147
|
+
"/sign-in/mfa/push/events",
|
|
1148
|
+
"/sign-in/mfa/push/finish",
|
|
1119
1149
|
"/me/sessions",
|
|
1120
1150
|
"/me/sessions/end",
|
|
1121
1151
|
"/me/email",
|
|
@@ -1133,8 +1163,17 @@ function createCauthy(given = {}) {
|
|
|
1133
1163
|
"/me/passkeys/add/finish",
|
|
1134
1164
|
"/me/passkeys/remove",
|
|
1135
1165
|
"/me/agents",
|
|
1136
|
-
"/me/agents/disconnect"
|
|
1137
|
-
|
|
1166
|
+
"/me/agents/disconnect",
|
|
1167
|
+
"/sign-in/anonymous",
|
|
1168
|
+
"/me/upgrade",
|
|
1169
|
+
"/me/organizations",
|
|
1170
|
+
"/me/organizations/members",
|
|
1171
|
+
"/me/organizations/roles",
|
|
1172
|
+
"/me/organizations/members/add",
|
|
1173
|
+
"/me/organizations/members/role",
|
|
1174
|
+
"/me/organizations/members/remove",
|
|
1175
|
+
"/me/organizations/members/invite"
|
|
1176
|
+
].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";
|
|
1138
1177
|
if (!own) return null;
|
|
1139
1178
|
if (tenant === "") {
|
|
1140
1179
|
return problem(500, "not_configured", "cauthy-auth: tenant (CAUTHY_TENANT) is required for the application's own sign-in screens");
|
|
@@ -1222,10 +1261,19 @@ function createCauthy(given = {}) {
|
|
|
1222
1261
|
const clear = writeCookie(stepCookie, "", attrs(request, 0));
|
|
1223
1262
|
const back = step?.returnTo ?? afterSignIn;
|
|
1224
1263
|
const failedTo = (code2) => redirect(`${back}${back.includes("?") ? "&" : "?"}auth_error=${encodeURIComponent(code2)}`, [clear]);
|
|
1225
|
-
if (step === null || step.kind !== "social" && step.kind !== "link" || step.provider !== provider || url.searchParams.get("state") !== step.token) return failedTo("state_mismatch");
|
|
1264
|
+
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");
|
|
1226
1265
|
const code = url.searchParams.get("code");
|
|
1227
1266
|
if (!code) return failedTo(url.searchParams.get("error") === "access_denied" ? "cancelled" : "provider_refused");
|
|
1228
1267
|
const q = new URLSearchParams({ code, state: step.token, redirect_uri: `${originOf(request)}${basePath}/callback/${provider}` });
|
|
1268
|
+
if (step.kind === "upgrade") {
|
|
1269
|
+
const mine = await signedInAs(request);
|
|
1270
|
+
if ("response" in mine) return failedTo("unauthenticated");
|
|
1271
|
+
const done2 = await ask(request, "GET", `/v1/auth/anonymous/upgrade/${provider}/callback?${q}`, void 0, void 0, mine.token);
|
|
1272
|
+
if (done2.error) return failedTo(done2.error.code);
|
|
1273
|
+
const s2 = await stored(done2.data);
|
|
1274
|
+
if (s2 === null) return failedTo("unavailable");
|
|
1275
|
+
return redirect(back, [...await write(request, s2, readCookies(request.headers.get("cookie"))), clear]);
|
|
1276
|
+
}
|
|
1229
1277
|
if (step.kind === "link") {
|
|
1230
1278
|
const mine = await signedInAs(request);
|
|
1231
1279
|
if ("response" in mine) return failedTo("unauthenticated");
|
|
@@ -1241,6 +1289,19 @@ function createCauthy(given = {}) {
|
|
|
1241
1289
|
if (s === null) return failedTo("unavailable");
|
|
1242
1290
|
return redirect(back, [...await write(request, s, readCookies(request.headers.get("cookie"))), clear]);
|
|
1243
1291
|
}
|
|
1292
|
+
if (route.startsWith("/me/upgrade/social/") && !post) {
|
|
1293
|
+
const provider = providerIn(route.slice("/me/upgrade/social/".length));
|
|
1294
|
+
if (!PROVIDER_ID.test(provider)) return new Response("Not found", { status: 404 });
|
|
1295
|
+
const returnTo = localPath(url.searchParams.get("return_to"), afterSignIn);
|
|
1296
|
+
const failed2 = (code) => redirect(`${returnTo}${returnTo.includes("?") ? "&" : "?"}auth_error=${encodeURIComponent(code)}`);
|
|
1297
|
+
const mine = await signedInAs(request);
|
|
1298
|
+
if ("response" in mine) return failed2("unauthenticated");
|
|
1299
|
+
const callback2 = `${basePath}/callback/${provider}`;
|
|
1300
|
+
const started = await ask(request, "GET", `/v1/auth/anonymous/upgrade/${provider}?redirect_uri=${encodeURIComponent(`${originOf(request)}${callback2}`)}`, void 0, callback2, mine.token);
|
|
1301
|
+
if (started.error || typeof started.data?.redirect_url !== "string") return failed2(started.error?.code ?? "provider_unavailable");
|
|
1302
|
+
const step = { kind: "upgrade", token: String(started.data.state ?? ""), provider, returnTo };
|
|
1303
|
+
return redirect(started.data.redirect_url, [...mine.headers.getSetCookie(), writeCookie(stepCookie, await seal(step, await key), attrs(request, STEP_SECONDS))]);
|
|
1304
|
+
}
|
|
1244
1305
|
if (route.startsWith("/me/identities/link/") && !post) {
|
|
1245
1306
|
const provider = providerIn(route.slice("/me/identities/link/".length));
|
|
1246
1307
|
if (!PROVIDER_ID.test(provider)) return new Response("Not found", { status: 404 });
|
|
@@ -1278,6 +1339,24 @@ function createCauthy(given = {}) {
|
|
|
1278
1339
|
const list = Array.isArray(res.data) ? res.data : [];
|
|
1279
1340
|
return json({ agents: list.map(agentOf) }, 200, mine.headers);
|
|
1280
1341
|
}
|
|
1342
|
+
if ((route === "/me/organizations" || route === "/me/organizations/members" || route === "/me/organizations/roles") && !post) {
|
|
1343
|
+
const mine = await signedInAs(request);
|
|
1344
|
+
if ("response" in mine) return mine.response;
|
|
1345
|
+
let path = "/v1/auth/me/organizations";
|
|
1346
|
+
if (route !== "/me/organizations") {
|
|
1347
|
+
const id = url.searchParams.get("id") ?? "";
|
|
1348
|
+
if (!UUID.test(id)) return problem(400, "invalid_organization", "Say which organization.", void 0, mine.headers);
|
|
1349
|
+
path += `/${id}/${route.endsWith("/roles") ? "roles" : "members"}`;
|
|
1350
|
+
} else if (url.searchParams.get("system")) {
|
|
1351
|
+
path += `?system=${encodeURIComponent(url.searchParams.get("system"))}`;
|
|
1352
|
+
}
|
|
1353
|
+
const res = await ask(request, "GET", path, void 0, void 0, mine.token);
|
|
1354
|
+
if (res.error) return problem(res.status, res.error.code, res.error.message, void 0, mine.headers);
|
|
1355
|
+
const list = Array.isArray(res.data) ? res.data : [];
|
|
1356
|
+
if (route === "/me/organizations") return json({ organizations: list.map(seatOf) }, 200, mine.headers);
|
|
1357
|
+
if (route === "/me/organizations/roles") return json({ roles: list.map(orgRoleOf) }, 200, mine.headers);
|
|
1358
|
+
return json({ members: list.map(orgMemberOf) }, 200, mine.headers);
|
|
1359
|
+
}
|
|
1281
1360
|
if (route === "/me/mfa/factors" && !post) {
|
|
1282
1361
|
const mine = await signedInAs(request);
|
|
1283
1362
|
if ("response" in mine) return mine.response;
|
|
@@ -1296,6 +1375,28 @@ function createCauthy(given = {}) {
|
|
|
1296
1375
|
}
|
|
1297
1376
|
return json({ account: accountOf(res.data) }, 200, mine.headers);
|
|
1298
1377
|
}
|
|
1378
|
+
if (route === "/sign-in/mfa/push/events" && !post) {
|
|
1379
|
+
const sealed = readCookies(request.headers.get("cookie")).get(stepCookie);
|
|
1380
|
+
const step = sealed ? await unseal(sealed, await key) : null;
|
|
1381
|
+
if (step === null || step.kind !== "mfa") return problem(400, "step_expired", "Sign in again: the code was asked for too long ago.");
|
|
1382
|
+
let upstream;
|
|
1383
|
+
try {
|
|
1384
|
+
upstream = await doFetch(`${issuer}/v1/auth/mfa/push/events`, {
|
|
1385
|
+
headers: { "x-tenant-key": tenant, "x-mfa-token": step.token, accept: "text/event-stream" },
|
|
1386
|
+
signal: request.signal
|
|
1387
|
+
});
|
|
1388
|
+
} catch {
|
|
1389
|
+
return problem(503, "unavailable", "Cauthy could not be reached.");
|
|
1390
|
+
}
|
|
1391
|
+
if (!upstream.ok || !upstream.body) {
|
|
1392
|
+
const b2 = await upstream.json().catch(() => null);
|
|
1393
|
+
return problem(upstream.status, String(b2?.errors?.[0]?.code ?? "error"), String(b2?.errors?.[0]?.message ?? "The request could not be completed."));
|
|
1394
|
+
}
|
|
1395
|
+
return new Response(upstream.body, {
|
|
1396
|
+
status: 200,
|
|
1397
|
+
headers: { "content-type": "text/event-stream", "cache-control": "no-cache, no-store", "x-accel-buffering": "no" }
|
|
1398
|
+
});
|
|
1399
|
+
}
|
|
1299
1400
|
if (!post) return new Response("Method not allowed", { status: 405, headers: { allow: "POST" } });
|
|
1300
1401
|
if (!ownRequest(request)) return problem(403, "cross_site", "This request did not come from this application.");
|
|
1301
1402
|
if (route === "/sign-out") {
|
|
@@ -1320,6 +1421,12 @@ function createCauthy(given = {}) {
|
|
|
1320
1421
|
const c = res.data?.connection;
|
|
1321
1422
|
return json(c ? { status: "found", connection: { id: String(c.slug ?? ""), name: String(c.display_name ?? ""), enforced: c.enforced === true } } : { status: "none" });
|
|
1322
1423
|
}
|
|
1424
|
+
if (route === "/sign-in/anonymous") {
|
|
1425
|
+
if (!post) return new Response("Method not allowed", { status: 405, headers: { allow: "POST" } });
|
|
1426
|
+
const res = await ask(request, "POST", "/v1/auth/anonymous", {});
|
|
1427
|
+
if (res.error) return problem(res.status, res.error.code, res.error.message);
|
|
1428
|
+
return signedIn(request, res.data);
|
|
1429
|
+
}
|
|
1323
1430
|
if (route === "/sign-in/email") {
|
|
1324
1431
|
const bad = firstProblem(checkEmail(b.email), checkPassword(b.password));
|
|
1325
1432
|
if (bad) return invalid(bad);
|
|
@@ -1341,6 +1448,19 @@ function createCauthy(given = {}) {
|
|
|
1341
1448
|
if (res.error) return problem(res.status, res.error.code, res.error.message, "code");
|
|
1342
1449
|
return signedIn(request, res.data, [writeCookie(stepCookie, "", attrs(request, 0))]);
|
|
1343
1450
|
}
|
|
1451
|
+
if (route === "/sign-in/mfa/push" || route === "/sign-in/mfa/push/finish") {
|
|
1452
|
+
const sealed = readCookies(request.headers.get("cookie")).get(stepCookie);
|
|
1453
|
+
const step = sealed ? await unseal(sealed, await key) : null;
|
|
1454
|
+
if (step === null || step.kind !== "mfa") return problem(400, "step_expired", "Sign in again: the code was asked for too long ago.");
|
|
1455
|
+
if (route === "/sign-in/mfa/push") {
|
|
1456
|
+
const res2 = await ask(request, "POST", "/v1/auth/mfa/push", { mfa_token: step.token });
|
|
1457
|
+
if (res2.error) return problem(res2.status, res2.error.code, res2.error.message);
|
|
1458
|
+
return json({ status: "sent", number: Number(res2.data?.number ?? 0) });
|
|
1459
|
+
}
|
|
1460
|
+
const res = await ask(request, "POST", "/v1/auth/mfa/challenge", { mfa_token: step.token, push: true });
|
|
1461
|
+
if (res.error) return problem(res.status, res.error.code, res.error.message);
|
|
1462
|
+
return signedIn(request, res.data, [writeCookie(stepCookie, "", attrs(request, 0))]);
|
|
1463
|
+
}
|
|
1344
1464
|
if (route === "/sign-in/mfa/methods" || route === "/sign-in/mfa/send") {
|
|
1345
1465
|
const sealed = readCookies(request.headers.get("cookie")).get(stepCookie);
|
|
1346
1466
|
const step = sealed ? await unseal(sealed, await key) : null;
|
|
@@ -1349,7 +1469,13 @@ function createCauthy(given = {}) {
|
|
|
1349
1469
|
const res2 = await ask(request, "POST", "/v1/auth/mfa/methods", { mfa_token: step.token });
|
|
1350
1470
|
if (res2.error) return problem(res2.status, res2.error.code, res2.error.message);
|
|
1351
1471
|
const p = res2.data?.phone;
|
|
1352
|
-
|
|
1472
|
+
const push = res2.data?.push;
|
|
1473
|
+
return json({
|
|
1474
|
+
status: "ok",
|
|
1475
|
+
totp: res2.data?.totp === true,
|
|
1476
|
+
phone: p ? { number: String(p.number ?? ""), channel: String(p.channel ?? "sms") } : null,
|
|
1477
|
+
push: push ? { devices: Number(push.devices ?? 0) } : null
|
|
1478
|
+
});
|
|
1353
1479
|
}
|
|
1354
1480
|
const res = await ask(request, "POST", "/v1/auth/mfa/send", { mfa_token: step.token });
|
|
1355
1481
|
if (res.error) return problem(res.status, res.error.code, res.error.message);
|
|
@@ -1483,6 +1609,53 @@ function createCauthy(given = {}) {
|
|
|
1483
1609
|
if (res.error) return refused(res);
|
|
1484
1610
|
return json({ status: "removed", id }, 200, mine.headers);
|
|
1485
1611
|
}
|
|
1612
|
+
if (route === "/me/upgrade") {
|
|
1613
|
+
const bad = firstProblem(checkName(b.name), checkEmail(b.email), checkNewPassword(b.password));
|
|
1614
|
+
if (bad) return invalid(bad);
|
|
1615
|
+
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() : "" });
|
|
1616
|
+
if (res.error) return refused(res, res.error.code === "weak_password" ? "password" : "email");
|
|
1617
|
+
return signedIn(request, res.data);
|
|
1618
|
+
}
|
|
1619
|
+
if (route.startsWith("/me/organizations/members/")) {
|
|
1620
|
+
const org = typeof b.organizationId === "string" ? b.organizationId : "";
|
|
1621
|
+
if (!UUID.test(org)) return problem(400, "invalid_organization", "Say which organization.", void 0, mine.headers);
|
|
1622
|
+
const base = `/v1/auth/me/organizations/${org}/members`;
|
|
1623
|
+
if (route === "/me/organizations/members/add") {
|
|
1624
|
+
const bad = checkEmail(b.email);
|
|
1625
|
+
if (bad) return invalid(bad);
|
|
1626
|
+
const role = typeof b.role === "string" ? b.role : "";
|
|
1627
|
+
if (role === "") return problem(400, "invalid_role", "Choose a role.", "role", mine.headers);
|
|
1628
|
+
const res = await as(base, {
|
|
1629
|
+
email: String(b.email).trim(),
|
|
1630
|
+
role,
|
|
1631
|
+
name: typeof b.name === "string" ? b.name.trim() : "",
|
|
1632
|
+
client_id: clientId,
|
|
1633
|
+
...typeof b.locale === "string" && b.locale ? { locale: b.locale } : {}
|
|
1634
|
+
});
|
|
1635
|
+
if (res.error) return refused(res, res.error.code === "unknown_role" ? "role" : "email");
|
|
1636
|
+
return json({ status: "added", member: orgMemberOf(res.data) }, 200, mine.headers);
|
|
1637
|
+
}
|
|
1638
|
+
const user = typeof b.userId === "string" ? b.userId : "";
|
|
1639
|
+
if (!UUID.test(user)) return problem(400, "invalid_member", "Say which member.", void 0, mine.headers);
|
|
1640
|
+
if (route === "/me/organizations/members/role") {
|
|
1641
|
+
const role = typeof b.role === "string" ? b.role : "";
|
|
1642
|
+
if (role === "") return problem(400, "invalid_role", "Choose a role.", "role", mine.headers);
|
|
1643
|
+
const res = await as(`${base}/${user}`, { role }, "PUT");
|
|
1644
|
+
if (res.error) return refused(res, "role");
|
|
1645
|
+
return json({ status: "changed", userId: user, role }, 200, mine.headers);
|
|
1646
|
+
}
|
|
1647
|
+
if (route === "/me/organizations/members/remove") {
|
|
1648
|
+
const res = await as(`${base}/${user}`, void 0, "DELETE");
|
|
1649
|
+
if (res.error) return refused(res);
|
|
1650
|
+
orgCache.delete(mine.token);
|
|
1651
|
+
return json({ status: "removed", userId: user }, 200, mine.headers);
|
|
1652
|
+
}
|
|
1653
|
+
if (route === "/me/organizations/members/invite") {
|
|
1654
|
+
const res = await as(`${base}/${user}/invite`, { client_id: clientId, ...typeof b.locale === "string" && b.locale ? { locale: b.locale } : {} });
|
|
1655
|
+
if (res.error) return refused(res);
|
|
1656
|
+
return json({ status: "sent", userId: user }, 200, mine.headers);
|
|
1657
|
+
}
|
|
1658
|
+
}
|
|
1486
1659
|
if (route === "/me/agents/disconnect") {
|
|
1487
1660
|
const id = typeof b.id === "string" ? b.id : "";
|
|
1488
1661
|
if (!/^[0-9a-f-]{36}$/i.test(id)) return problem(400, "invalid_agent", "Say which agent to disconnect.", void 0, mine.headers);
|