cauthy-auth 0.18.0 → 0.20.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/client.d.mts +59 -1
- package/dist/client.d.ts +59 -1
- package/dist/client.js +13 -3
- package/dist/client.js.map +1 -1
- package/dist/client.mjs +13 -3
- package/dist/client.mjs.map +1 -1
- package/dist/index.js +52 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +52 -4
- package/dist/index.mjs.map +1 -1
- package/dist/react.d.mts +64 -1
- package/dist/react.d.ts +64 -1
- package/dist/react.js +92 -26
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +92 -26
- package/dist/react.mjs.map +1 -1
- package/dist/svelte.d.mts +1 -1
- package/dist/svelte.d.ts +1 -1
- package/dist/svelte.js +13 -3
- package/dist/svelte.js.map +1 -1
- package/dist/svelte.mjs +13 -3
- package/dist/svelte.mjs.map +1 -1
- package/dist/vue.d.mts +1 -1
- package/dist/vue.d.ts +1 -1
- package/dist/vue.js +13 -3
- package/dist/vue.js.map +1 -1
- package/dist/vue.mjs +13 -3
- package/dist/vue.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -994,6 +994,7 @@ function createCauthy(given = {}) {
|
|
|
994
994
|
const passkeyOf = (d) => ({
|
|
995
995
|
id: String(d?.id ?? ""),
|
|
996
996
|
name: String(d?.nickname ?? ""),
|
|
997
|
+
kind: ["security_key", "synced", "device"].includes(d?.kind) ? d.kind : "unknown",
|
|
997
998
|
createdAt: String(d?.created_at ?? ""),
|
|
998
999
|
lastUsedAt: d?.last_used_at ? String(d.last_used_at) : null
|
|
999
1000
|
});
|
|
@@ -1133,7 +1134,7 @@ function createCauthy(given = {}) {
|
|
|
1133
1134
|
"/me/passkeys/remove",
|
|
1134
1135
|
"/me/agents",
|
|
1135
1136
|
"/me/agents/disconnect"
|
|
1136
|
-
].includes(route) || route.startsWith("/sign-in/social/") || route.startsWith("/callback/") || route.startsWith("/me/identities/link/");
|
|
1137
|
+
].includes(route) || route.startsWith("/sign-in/social/") || route.startsWith("/callback/") || route.startsWith("/me/identities/link/") || route === "/sign-in/sso" || route === "/sign-in/sso/discover" || route === "/sso/callback";
|
|
1137
1138
|
if (!own) return null;
|
|
1138
1139
|
if (tenant === "") {
|
|
1139
1140
|
return problem(500, "not_configured", "cauthy-auth: tenant (CAUTHY_TENANT) is required for the application's own sign-in screens");
|
|
@@ -1146,10 +1147,11 @@ function createCauthy(given = {}) {
|
|
|
1146
1147
|
return json(lookCache.look);
|
|
1147
1148
|
}
|
|
1148
1149
|
if (route === "/methods" && !post) {
|
|
1149
|
-
const [providers, settings, place] = await Promise.all([
|
|
1150
|
+
const [providers, settings, place, sso] = await Promise.all([
|
|
1150
1151
|
ask(request, "GET", "/v1/auth/social/providers"),
|
|
1151
1152
|
ask(request, "GET", "/v1/auth/settings"),
|
|
1152
|
-
ask(request, "GET", `/v1/auth/webauthn/place?origin=${encodeURIComponent(originOf(request))}`)
|
|
1153
|
+
ask(request, "GET", `/v1/auth/webauthn/place?origin=${encodeURIComponent(originOf(request))}`),
|
|
1154
|
+
ask(request, "GET", "/v1/auth/sso/connections")
|
|
1153
1155
|
]);
|
|
1154
1156
|
const list = Array.isArray(providers.data) ? providers.data : [];
|
|
1155
1157
|
const here = place.data?.here === true;
|
|
@@ -1161,9 +1163,46 @@ function createCauthy(given = {}) {
|
|
|
1161
1163
|
passkey: place.error ? true : here || place.data?.on_cauthy === true,
|
|
1162
1164
|
passkeyHere: here,
|
|
1163
1165
|
passkeyOnCauthy: place.error ? true : place.data?.on_cauthy === true,
|
|
1166
|
+
// A company's sign-in, found by the person's work address.
|
|
1167
|
+
sso: Array.isArray(sso.data) && sso.data.some((c) => c?.discoverable === true),
|
|
1164
1168
|
...settings.data?.captcha_enabled === true && settings.data?.captcha_site_key ? { captchaSiteKey: String(settings.data.captcha_site_key) } : {}
|
|
1165
1169
|
});
|
|
1166
1170
|
}
|
|
1171
|
+
if (route === "/sign-in/sso" && !post) {
|
|
1172
|
+
const returnTo = localPath(url.searchParams.get("return_to"), afterSignIn);
|
|
1173
|
+
const failed2 = (code) => redirect(`${returnTo}${returnTo.includes("?") ? "&" : "?"}auth_error=${encodeURIComponent(code)}`);
|
|
1174
|
+
const email = (url.searchParams.get("email") ?? "").trim();
|
|
1175
|
+
const connection = (url.searchParams.get("connection") ?? "").trim();
|
|
1176
|
+
if (email === "" && connection === "") return failed2("sso_not_found");
|
|
1177
|
+
const verifier = random(48);
|
|
1178
|
+
const challenge = b64url(new Uint8Array(await crypto.subtle.digest("SHA-256", new TextEncoder().encode(verifier))));
|
|
1179
|
+
const callback2 = `${basePath}/sso/callback`;
|
|
1180
|
+
const started = await ask(request, "POST", "/v1/auth/sso/start", {
|
|
1181
|
+
...connection ? { connection } : { email },
|
|
1182
|
+
redirect_uri: `${originOf(request)}${callback2}`,
|
|
1183
|
+
code_challenge: challenge
|
|
1184
|
+
}, callback2);
|
|
1185
|
+
if (started.error || typeof started.data?.redirect_url !== "string") return failed2(started.error?.code ?? "sso_unavailable");
|
|
1186
|
+
const step = { kind: "sso", token: verifier, returnTo };
|
|
1187
|
+
return redirect(started.data.redirect_url, [writeCookie(stepCookie, await seal(step, await key), attrs(request, STEP_SECONDS))]);
|
|
1188
|
+
}
|
|
1189
|
+
if (route === "/sso/callback" && !post) {
|
|
1190
|
+
const sealed = readCookies(request.headers.get("cookie")).get(stepCookie);
|
|
1191
|
+
const step = sealed ? await unseal(sealed, await key) : null;
|
|
1192
|
+
const clear = writeCookie(stepCookie, "", attrs(request, 0));
|
|
1193
|
+
const back = step?.returnTo ?? afterSignIn;
|
|
1194
|
+
const failedTo = (code2) => redirect(`${back}${back.includes("?") ? "&" : "?"}auth_error=${encodeURIComponent(code2)}`, [clear]);
|
|
1195
|
+
if (step === null || step.kind !== "sso") return failedTo("state_mismatch");
|
|
1196
|
+
const refused = url.searchParams.get("error");
|
|
1197
|
+
if (refused) return failedTo(refused);
|
|
1198
|
+
const code = url.searchParams.get("code");
|
|
1199
|
+
if (!code) return failedTo("sso_failed");
|
|
1200
|
+
const done = await ask(request, "POST", "/v1/auth/sso/token", { code, redirect_uri: `${originOf(request)}${basePath}/sso/callback`, code_verifier: step.token });
|
|
1201
|
+
if (done.error) return failedTo(done.error.code);
|
|
1202
|
+
const s = await stored(done.data);
|
|
1203
|
+
if (s === null) return failedTo("unavailable");
|
|
1204
|
+
return redirect(back, [...await write(request, s, readCookies(request.headers.get("cookie"))), clear]);
|
|
1205
|
+
}
|
|
1167
1206
|
if (route.startsWith("/sign-in/social/") && !post) {
|
|
1168
1207
|
const provider = providerIn(route.slice("/sign-in/social/".length));
|
|
1169
1208
|
if (!PROVIDER_ID.test(provider)) return new Response("Not found", { status: 404 });
|
|
@@ -1273,6 +1312,14 @@ function createCauthy(given = {}) {
|
|
|
1273
1312
|
}
|
|
1274
1313
|
const b = await body(request);
|
|
1275
1314
|
if (b === null) return problem(400, "bad_request", "Send the form as JSON.");
|
|
1315
|
+
if (route === "/sign-in/sso/discover") {
|
|
1316
|
+
const bad = checkEmail(b.email);
|
|
1317
|
+
if (bad) return invalid(bad);
|
|
1318
|
+
const res = await ask(request, "POST", "/v1/auth/sso/discover", { email: String(b.email).trim() });
|
|
1319
|
+
if (res.error) return problem(res.status, res.error.code, res.error.message);
|
|
1320
|
+
const c = res.data?.connection;
|
|
1321
|
+
return json(c ? { status: "found", connection: { id: String(c.slug ?? ""), name: String(c.display_name ?? ""), enforced: c.enforced === true } } : { status: "none" });
|
|
1322
|
+
}
|
|
1276
1323
|
if (route === "/sign-in/email") {
|
|
1277
1324
|
const bad = firstProblem(checkEmail(b.email), checkPassword(b.password));
|
|
1278
1325
|
if (bad) return invalid(bad);
|
|
@@ -1409,7 +1456,8 @@ function createCauthy(given = {}) {
|
|
|
1409
1456
|
return json({ status: "unlinked", provider }, 200, mine.headers);
|
|
1410
1457
|
}
|
|
1411
1458
|
if (route === "/me/passkeys/add/begin") {
|
|
1412
|
-
const
|
|
1459
|
+
const kind = b.kind === "device" || b.kind === "security_key" ? b.kind : "";
|
|
1460
|
+
const res = await as("/v1/auth/webauthn/register/begin", { password, ...kind ? { kind } : {} });
|
|
1413
1461
|
if (res.error) return refused(res, res.error.code === "step_up_required" ? "password" : void 0);
|
|
1414
1462
|
const step = { kind: "enrol", token: String(res.data?.session_id ?? ""), returnTo: afterSignIn };
|
|
1415
1463
|
const h = new Headers(mine.headers);
|