cauthy-auth 0.30.0 → 0.32.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/README.md +50 -5
- package/dist/{cauthy-BXgsZ-Um.d.mts → cauthy-2jtP2LVQ.d.mts} +1 -1
- package/dist/{cauthy-CHENs452.d.ts → cauthy-CKfvvv_i.d.ts} +1 -1
- package/dist/cli.js +8 -5
- package/dist/client.d.mts +47 -6
- package/dist/client.d.ts +47 -6
- package/dist/client.js +16 -2
- package/dist/client.js.map +1 -1
- package/dist/client.mjs +16 -2
- 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 +64 -21
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +64 -21
- 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 +339 -31
- package/dist/react.d.ts +339 -31
- package/dist/react.js +616 -225
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +610 -230
- package/dist/react.mjs.map +1 -1
- package/dist/styles.css +8 -0
- package/dist/svelte.d.mts +2 -2
- package/dist/svelte.d.ts +2 -2
- package/dist/svelte.js +16 -2
- package/dist/svelte.js.map +1 -1
- package/dist/svelte.mjs +16 -2
- package/dist/svelte.mjs.map +1 -1
- package/dist/{system-0mHrdAgO.d.mts → system-BrrJsrFW.d.mts} +14 -0
- package/dist/{system-BIYbS7h2.d.ts → system-BvvoNs2y.d.ts} +14 -0
- package/dist/vue.d.mts +2 -2
- package/dist/vue.d.ts +2 -2
- package/dist/vue.js +16 -2
- package/dist/vue.js.map +1 -1
- package/dist/vue.mjs +16 -2
- package/dist/vue.mjs.map +1 -1
- package/package.json +2 -1
package/dist/index.mjs
CHANGED
|
@@ -691,6 +691,8 @@ function createSystem(given = {}) {
|
|
|
691
691
|
const envKey = env("CAUTHY_SYSTEM_KEY");
|
|
692
692
|
const key = given.key ?? (envKey ? { privateKey: envKey, keyId: env("CAUTHY_SYSTEM_KEY_ID") ?? "" } : void 0);
|
|
693
693
|
const ownSystem = given.system ?? env("CAUTHY_SYSTEM") ?? "";
|
|
694
|
+
const acceptInviteUrl = given.acceptInviteUrl ?? env("CAUTHY_ACCEPT_INVITE_URL") ?? "";
|
|
695
|
+
const inviteHeaders = /^https?:\/\//.test(acceptInviteUrl) ? { "x-cauthy-client-id": clientId, "x-cauthy-link-to": acceptInviteUrl } : {};
|
|
694
696
|
const doFetch = (...args) => (given.fetch ?? fetch)(...args);
|
|
695
697
|
const tokenEndpoint = `${issuer}/v1/oauth/token`;
|
|
696
698
|
function configured() {
|
|
@@ -733,10 +735,10 @@ function createSystem(given = {}) {
|
|
|
733
735
|
asking = void 0;
|
|
734
736
|
});
|
|
735
737
|
}
|
|
736
|
-
async function call(method, path, body) {
|
|
738
|
+
async function call(method, path, body, extra = {}) {
|
|
737
739
|
const send = async () => doFetch(`${issuer}${path}`, {
|
|
738
740
|
method,
|
|
739
|
-
headers: { authorization: `Bearer ${await token()}`, ...body === void 0 ? {} : { "content-type": "application/json" } },
|
|
741
|
+
headers: { authorization: `Bearer ${await token()}`, ...extra, ...body === void 0 ? {} : { "content-type": "application/json" } },
|
|
740
742
|
body: body === void 0 ? void 0 : JSON.stringify(body)
|
|
741
743
|
});
|
|
742
744
|
let res = await send();
|
|
@@ -747,7 +749,7 @@ function createSystem(given = {}) {
|
|
|
747
749
|
if (!res.ok) await fail(res, `${method} ${path}`);
|
|
748
750
|
return res.status === 204 ? void 0 : res.json();
|
|
749
751
|
}
|
|
750
|
-
const data = async (method, path, body) => (await call(method, path, body))?.data;
|
|
752
|
+
const data = async (method, path, body, extra) => (await call(method, path, body, extra))?.data;
|
|
751
753
|
const id = encodeURIComponent;
|
|
752
754
|
return {
|
|
753
755
|
token,
|
|
@@ -784,7 +786,8 @@ function createSystem(given = {}) {
|
|
|
784
786
|
return toMember(await data(
|
|
785
787
|
"POST",
|
|
786
788
|
`/v1/organizations/${id(orgId)}/members`,
|
|
787
|
-
{ role: m.role, user_id: m.userId, email: m.email, name: m.name, locale: m.locale, client_id: clientId }
|
|
789
|
+
{ role: m.role, user_id: m.userId, email: m.email, name: m.name, locale: m.locale, client_id: clientId },
|
|
790
|
+
inviteHeaders
|
|
788
791
|
));
|
|
789
792
|
},
|
|
790
793
|
async setRole(orgId, userId, role) {
|
|
@@ -795,7 +798,7 @@ function createSystem(given = {}) {
|
|
|
795
798
|
}
|
|
796
799
|
},
|
|
797
800
|
async invite(person) {
|
|
798
|
-
const u = await data("POST", "/v1/users", { ...person, client_id: clientId });
|
|
801
|
+
const u = await data("POST", "/v1/users", { ...person, client_id: clientId }, inviteHeaders);
|
|
799
802
|
return { id: u.id, email: u.email };
|
|
800
803
|
},
|
|
801
804
|
theme: {
|
|
@@ -1130,13 +1133,16 @@ function createCauthy(given = {}) {
|
|
|
1130
1133
|
const againCookie = `${cookieName}_again`;
|
|
1131
1134
|
const stepCookie = `${cookieName}_step`;
|
|
1132
1135
|
const doFetch = (...args) => (given.fetch ?? fetch)(...args);
|
|
1136
|
+
const iconOf = iconFor(issuer);
|
|
1133
1137
|
const key = keyOf(secret);
|
|
1134
1138
|
const pages = {
|
|
1135
1139
|
signIn: given.pages?.signIn ? localPath(given.pages.signIn, "/") : void 0,
|
|
1136
1140
|
resetPassword: given.pages?.resetPassword ? localPath(given.pages.resetPassword, "/") : void 0,
|
|
1137
|
-
verifyEmail: given.pages?.verifyEmail ? localPath(given.pages.verifyEmail, "/") : void 0
|
|
1141
|
+
verifyEmail: given.pages?.verifyEmail ? localPath(given.pages.verifyEmail, "/") : void 0,
|
|
1142
|
+
acceptInvite: given.pages?.acceptInvite ? localPath(given.pages.acceptInvite, "/") : void 0
|
|
1138
1143
|
};
|
|
1139
|
-
const
|
|
1144
|
+
const acceptInviteUrl = baseURL && pages.acceptInvite ? `${withoutTrailingSlashes(baseURL)}${pages.acceptInvite}` : void 0;
|
|
1145
|
+
const ownSystem = createSystem({ issuer, clientId, clientSecret, key: given.systemKey, system: system || void 0, acceptInviteUrl, fetch: given.fetch });
|
|
1140
1146
|
const originOf = (request) => {
|
|
1141
1147
|
if (baseURL) return withoutTrailingSlashes(baseURL);
|
|
1142
1148
|
const url = new URL(request.url);
|
|
@@ -1563,6 +1569,14 @@ function createCauthy(given = {}) {
|
|
|
1563
1569
|
for (const c of [...await write(request, s, readCookies(request.headers.get("cookie"))), ...extra]) h.append("set-cookie", c);
|
|
1564
1570
|
return json({ status: "signed_in", session: await toPublic(toSession(s)), ...more }, 200, h);
|
|
1565
1571
|
}
|
|
1572
|
+
async function loggedIn(request, data) {
|
|
1573
|
+
if (data?.mfa_required === true) {
|
|
1574
|
+
const step = { kind: "mfa", token: String(data.mfa_token ?? ""), returnTo: afterSignIn };
|
|
1575
|
+
const how = data.mfa_method === "email" ? { method: "email" } : {};
|
|
1576
|
+
return json({ status: "mfa_required", ...how }, 200, new Headers({ "set-cookie": writeCookie(stepCookie, await seal(step, await key), attrs(request, STEP_SECONDS)) }));
|
|
1577
|
+
}
|
|
1578
|
+
return signedIn(request, data);
|
|
1579
|
+
}
|
|
1566
1580
|
let lookCache = null;
|
|
1567
1581
|
let policyCache = null;
|
|
1568
1582
|
const keepPolicy = (settings) => {
|
|
@@ -1636,7 +1650,9 @@ function createCauthy(given = {}) {
|
|
|
1636
1650
|
"/me/organizations/members/invite",
|
|
1637
1651
|
"/me/organizations/rename",
|
|
1638
1652
|
"/me/organizations/archive",
|
|
1639
|
-
"/me/organizations/delete"
|
|
1653
|
+
"/me/organizations/delete",
|
|
1654
|
+
"/invitation",
|
|
1655
|
+
"/invitation/accept"
|
|
1640
1656
|
].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";
|
|
1641
1657
|
if (!own) return null;
|
|
1642
1658
|
if (tenant === "") {
|
|
@@ -1658,17 +1674,21 @@ function createCauthy(given = {}) {
|
|
|
1658
1674
|
]);
|
|
1659
1675
|
const list = Array.isArray(providers.data) ? providers.data : [];
|
|
1660
1676
|
const password = keepPolicy(settings);
|
|
1661
|
-
const
|
|
1677
|
+
const passkeys = settings.data?.allow_passkeys !== false;
|
|
1678
|
+
const here = passkeys && place.data?.here === true;
|
|
1662
1679
|
return json({
|
|
1663
|
-
providers: list.map((p) => ({ id: String(p.provider ?? p.id ?? ""), name: String(p.label ?? p.name ?? p.provider ?? "") })).filter((p) => p.id !== ""),
|
|
1680
|
+
providers: list.map((p) => ({ id: String(p.provider ?? p.id ?? ""), name: String(p.label ?? p.name ?? p.provider ?? ""), ...iconOf(p) })).filter((p) => p.id !== ""),
|
|
1681
|
+
// Whether the workspace signs people in with a password at all. A
|
|
1682
|
+
// Cauthy from before the setting says nothing of it: then it does.
|
|
1683
|
+
passwordSignIn: settings.data?.allow_password !== false,
|
|
1664
1684
|
signUp: settings.data?.allow_signup !== false,
|
|
1665
1685
|
// The application's system makes an organization per sign-up: the form asks the company's name.
|
|
1666
1686
|
...settings.data?.signup?.organization?.ask === true ? { organization: { ask: true, required: settings.data.signup.organization.required === true } } : {},
|
|
1667
1687
|
// A sign-in link needs a page of the application to open.
|
|
1668
1688
|
magicLink: settings.data?.allow_magic_link === true && pages.signIn !== void 0,
|
|
1669
|
-
passkey: place.error ? true : here || place.data?.on_cauthy === true,
|
|
1689
|
+
passkey: passkeys && (place.error ? true : here || place.data?.on_cauthy === true),
|
|
1670
1690
|
passkeyHere: here,
|
|
1671
|
-
passkeyOnCauthy: place.error ? true : place.data?.on_cauthy === true,
|
|
1691
|
+
passkeyOnCauthy: passkeys && (place.error ? true : place.data?.on_cauthy === true),
|
|
1672
1692
|
// A company's sign-in, found by the person's work address.
|
|
1673
1693
|
sso: Array.isArray(sso.data) && sso.data.some((c) => c?.discoverable === true),
|
|
1674
1694
|
// The terms a sign-up accepts and the consents it answers, when the workspace asks any.
|
|
@@ -1678,6 +1698,14 @@ function createCauthy(given = {}) {
|
|
|
1678
1698
|
...password ? { password } : {}
|
|
1679
1699
|
});
|
|
1680
1700
|
}
|
|
1701
|
+
if (route === "/invitation" && !post) {
|
|
1702
|
+
const token2 = (url.searchParams.get("token") ?? "").trim();
|
|
1703
|
+
if (token2 === "" || token2.length > 512) return problem(422, "invalid_token", "This invitation is not valid, or it has expired.");
|
|
1704
|
+
const res = await ask(request, "GET", `/v1/auth/invitation?token=${encodeURIComponent(token2)}`);
|
|
1705
|
+
if (res.error) return problem(res.status, res.error.code, res.error.message);
|
|
1706
|
+
const organization = typeof res.data?.organization === "string" && res.data.organization !== "" ? { organization: res.data.organization } : {};
|
|
1707
|
+
return json({ status: "ok", invitation: { email: String(res.data?.email ?? ""), workspace: String(res.data?.workspace ?? ""), ...organization } });
|
|
1708
|
+
}
|
|
1681
1709
|
if (route === "/sign-in/sso" && !post) {
|
|
1682
1710
|
const returnTo = localPath(url.searchParams.get("return_to"), afterSignIn);
|
|
1683
1711
|
const failed2 = (code) => redirect(`${returnTo}${returnTo.includes("?") ? "&" : "?"}auth_error=${encodeURIComponent(code)}`);
|
|
@@ -1907,12 +1935,7 @@ function createCauthy(given = {}) {
|
|
|
1907
1935
|
if (bad) return invalid(bad);
|
|
1908
1936
|
const res = await ask(request, "POST", "/v1/auth/login", { email: String(b.email).trim(), password: b.password });
|
|
1909
1937
|
if (res.error) return problem(res.status, res.error.code, res.error.message);
|
|
1910
|
-
|
|
1911
|
-
const step = { kind: "mfa", token: String(res.data.mfa_token ?? ""), returnTo: afterSignIn };
|
|
1912
|
-
const how = res.data.mfa_method === "email" ? { method: "email" } : {};
|
|
1913
|
-
return json({ status: "mfa_required", ...how }, 200, new Headers({ "set-cookie": writeCookie(stepCookie, await seal(step, await key), attrs(request, STEP_SECONDS)) }));
|
|
1914
|
-
}
|
|
1915
|
-
return signedIn(request, res.data);
|
|
1938
|
+
return loggedIn(request, res.data);
|
|
1916
1939
|
}
|
|
1917
1940
|
if (route === "/sign-in/mfa") {
|
|
1918
1941
|
const bad = checkCode(b.code);
|
|
@@ -2133,13 +2156,13 @@ function createCauthy(given = {}) {
|
|
|
2133
2156
|
if (bad) return invalid(bad);
|
|
2134
2157
|
const role = typeof b.role === "string" ? b.role : "";
|
|
2135
2158
|
if (role === "") return problem(400, "invalid_role", "Choose a role.", "role", mine.headers);
|
|
2136
|
-
const res = await
|
|
2159
|
+
const res = await ask(request, "POST", base, {
|
|
2137
2160
|
email: String(b.email).trim(),
|
|
2138
2161
|
role,
|
|
2139
2162
|
name: typeof b.name === "string" ? b.name.trim() : "",
|
|
2140
2163
|
client_id: clientId,
|
|
2141
2164
|
...typeof b.locale === "string" && b.locale ? { locale: b.locale } : {}
|
|
2142
|
-
});
|
|
2165
|
+
}, pages.acceptInvite, mine.token);
|
|
2143
2166
|
if (res.error) return refused(res, res.error.code === "unknown_role" ? "role" : "email");
|
|
2144
2167
|
return json({ status: "added", member: orgMemberOf(res.data) }, 200, mine.headers);
|
|
2145
2168
|
}
|
|
@@ -2159,7 +2182,7 @@ function createCauthy(given = {}) {
|
|
|
2159
2182
|
return json({ status: "removed", userId: user }, 200, mine.headers);
|
|
2160
2183
|
}
|
|
2161
2184
|
if (route === "/me/organizations/members/invite") {
|
|
2162
|
-
const res = await
|
|
2185
|
+
const res = await ask(request, "POST", `${base}/${user}/invite`, { client_id: clientId, ...typeof b.locale === "string" && b.locale ? { locale: b.locale } : {} }, pages.acceptInvite, mine.token);
|
|
2163
2186
|
if (res.error) return refused(res);
|
|
2164
2187
|
return json({ status: "sent", userId: user }, 200, mine.headers);
|
|
2165
2188
|
}
|
|
@@ -2198,6 +2221,14 @@ function createCauthy(given = {}) {
|
|
|
2198
2221
|
if (res.data?.access_token) return signedIn(request, res.data);
|
|
2199
2222
|
return json({ status: "verified" });
|
|
2200
2223
|
}
|
|
2224
|
+
if (route === "/invitation/accept") {
|
|
2225
|
+
if (!isToken(b.token)) return problem(422, "invalid_token", "This invitation is not valid, or it has expired.");
|
|
2226
|
+
const bad = await newPasswordProblem(request, b.password);
|
|
2227
|
+
if (bad) return invalid(bad);
|
|
2228
|
+
const res = await ask(request, "POST", "/v1/auth/invitation/accept", { token: String(b.token), password: b.password });
|
|
2229
|
+
if (res.error) return problem(res.status, res.error.code, res.error.message, res.error.code === "weak_password" ? "password" : void 0, void 0, res.error.reasons);
|
|
2230
|
+
return loggedIn(request, res.data);
|
|
2231
|
+
}
|
|
2201
2232
|
if (route === "/sign-in/passkey/begin") {
|
|
2202
2233
|
const email = typeof b.email === "string" && checkEmail(b.email) === null ? b.email.trim() : "";
|
|
2203
2234
|
const res = await ask(request, "POST", "/v1/auth/webauthn/login/begin", email !== "" ? { email } : {});
|
|
@@ -2355,6 +2386,18 @@ function createCauthy(given = {}) {
|
|
|
2355
2386
|
options: { issuer, clientId, basePath, afterSignIn, afterSignOut, cookieName }
|
|
2356
2387
|
};
|
|
2357
2388
|
}
|
|
2389
|
+
function iconFor(issuer) {
|
|
2390
|
+
return (p) => {
|
|
2391
|
+
const raw = typeof p?.icon_url === "string" ? p.icon_url.trim() : "";
|
|
2392
|
+
if (raw === "") return {};
|
|
2393
|
+
try {
|
|
2394
|
+
const url = new URL(raw.startsWith("/") && !raw.startsWith("//") ? `${issuer}${raw}` : raw);
|
|
2395
|
+
return url.protocol === "https:" || url.protocol === "http:" ? { iconUrl: url.href } : {};
|
|
2396
|
+
} catch {
|
|
2397
|
+
return {};
|
|
2398
|
+
}
|
|
2399
|
+
};
|
|
2400
|
+
}
|
|
2358
2401
|
function legalOf(raw) {
|
|
2359
2402
|
const documents = Array.isArray(raw?.documents) ? raw.documents : [];
|
|
2360
2403
|
const purposes = Array.isArray(raw?.consent_purposes) ? raw.consent_purposes : [];
|