@protobase/server 0.48.0 → 0.49.1
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/admin-options.d.ts +2 -2
- package/dist/app-identity.d.ts +2 -2
- package/dist/app-name.d.ts +2 -0
- package/dist/better-auth/auth-settings.d.ts +8773 -0
- package/dist/better-auth/auth-settings.js +43 -0
- package/dist/better-auth/authenticate-settings.d.ts +15 -0
- package/dist/better-auth/authenticate-settings.js +12 -0
- package/dist/better-auth/create-auth.d.ts +51 -11
- package/dist/better-auth/create-auth.js +33 -11
- package/dist/better-auth/mcp/mcp-auth-plugins.d.ts +2719 -0
- package/dist/better-auth/mcp/mcp-auth-plugins.js +68 -0
- package/dist/better-auth/mcp/mcp-plugins.d.ts +7 -2
- package/dist/better-auth/mcp/mcp-plugins.js +3 -68
- package/dist/better-auth/mcp/mcp-token-claims.js +1 -1
- package/dist/better-auth/organizations/store.d.ts +1 -0
- package/dist/better-auth/saml-plugin.d.ts +993 -0
- package/dist/better-auth/saml-plugin.js +36 -0
- package/dist/better-auth/saml-sign-in.d.ts +27 -1
- package/dist/better-auth/saml-sign-in.js +1 -33
- package/dist/better-auth/secret-versions.d.ts +7 -0
- package/dist/better-auth/secret-versions.js +21 -0
- package/dist/better-auth/signing-keys.js +86 -0
- package/dist/better-auth/tokens.js +1 -0
- package/dist/better-auth/user-table.js +1 -1
- package/dist/better-auth/users.d.ts +1 -1
- package/dist/create-admin.d.ts +5 -3
- package/dist/create-admin.js +3 -1
- package/dist/encryption/keyring.js +1 -1
- package/dist/files/options.d.ts +5 -8
- package/dist/files/provider-settings.d.ts +16 -0
- package/dist/files/provider-settings.js +17 -0
- package/dist/files/runtime.js +4 -4
- package/dist/forms/runtime.js +3 -3
- package/dist/gotrue/sessions-plugin.js +3 -9
- package/dist/index.d.ts +16 -15
- package/dist/index.js +8 -10
- package/dist/internal.d.ts +13 -0
- package/dist/internal.js +13 -0
- package/dist/jobs/declared-job.d.ts +24 -0
- package/dist/jobs/declared-job.js +26 -0
- package/dist/jobs/job-types.d.ts +1 -1
- package/dist/mcp/mcp-authenticator.js +3 -3
- package/dist/notifications/device-store-of.d.ts +1 -1
- package/dist/notifications/device-store-of.js +1 -1
- package/dist/notifications/device-store.d.ts +1 -1
- package/dist/notifications/device-store.js +1 -1
- package/dist/notifications/history-store-of.d.ts +1 -1
- package/dist/notifications/history-store-of.js +1 -1
- package/dist/notifications/history-store.d.ts +1 -1
- package/dist/notifications/history-store.js +1 -1
- package/dist/notifications/options.d.ts +3 -1
- package/dist/notifications/options.js +1 -1
- package/dist/notifications/schema.d.ts +2 -2
- package/dist/notifications/schema.js +7 -7
- package/dist/notifications/send-notification.js +1 -1
- package/dist/notifications/sender.d.ts +1 -1
- package/dist/notifications/sender.js +2 -2
- package/dist/notifications/senders-of.d.ts +1 -1
- package/dist/notifications/senders-of.js +1 -1
- package/dist/package.js +1 -1
- package/dist/webhooks/subscription.d.ts +1 -0
- package/dist/webhooks/table/options.d.ts +1 -1
- package/dist/webhooks/table/schema.d.ts +2 -2
- package/dist/webhooks/table/schema.js +2 -2
- package/dist/webhooks/table/webhook-table.js +2 -2
- package/dist/webhooks/table/webhooks-module.d.ts +108 -0
- package/dist/webhooks/table/webhooks-module.js +11 -0
- package/package.json +6 -5
- package/dist/notifications/plugin.d.ts +0 -13
- package/dist/notifications/plugin.js +0 -16
- package/dist/project-config.d.ts +0 -54
- package/dist/project-config.js +0 -182
- package/dist/webhooks/table/plugin.d.ts +0 -10
- package/dist/webhooks/table/plugin.js +0 -18
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { samlEntityId } from "./saml-sign-in.js";
|
|
2
|
+
import { sso } from "@better-auth/sso";
|
|
3
|
+
//#region src/better-auth/saml-plugin.ts
|
|
4
|
+
/** The provider as one of the SSO plugin's configured providers (`defaultSSO`). */
|
|
5
|
+
const defaultSsoEntry = (provider, baseURL) => {
|
|
6
|
+
const { idp, attributes = {} } = provider;
|
|
7
|
+
const mapping = Object.fromEntries(Object.entries(attributes).filter(([, name]) => name !== void 0));
|
|
8
|
+
return {
|
|
9
|
+
providerId: provider.id,
|
|
10
|
+
domain: provider.domains.join(","),
|
|
11
|
+
samlConfig: {
|
|
12
|
+
issuer: samlEntityId(baseURL, provider.id),
|
|
13
|
+
entryPoint: "ssoUrl" in idp ? idp.ssoUrl : "",
|
|
14
|
+
idpMetadata: "metadata" in idp ? { metadata: idp.metadata } : {
|
|
15
|
+
entityID: idp.entityId,
|
|
16
|
+
cert: idp.certificate
|
|
17
|
+
},
|
|
18
|
+
...Object.keys(mapping).length > 0 && { mapping }
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Better Auth's SSO plugin with the configured providers. Their domains are trusted, so an address there links to the
|
|
24
|
+
* account that has it; organizations are not assigned by provider, and nobody registers providers.
|
|
25
|
+
*/
|
|
26
|
+
const samlPlugin = (providers, baseURL) => {
|
|
27
|
+
const { schema: _schema, ...plugin } = sso({
|
|
28
|
+
defaultSSO: providers.map((provider) => defaultSsoEntry(provider, baseURL)),
|
|
29
|
+
domainVerification: { enabled: true },
|
|
30
|
+
organizationProvisioning: { disabled: true },
|
|
31
|
+
providersLimit: 0
|
|
32
|
+
});
|
|
33
|
+
return plugin;
|
|
34
|
+
};
|
|
35
|
+
//#endregion
|
|
36
|
+
export { defaultSsoEntry, samlPlugin };
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import "@better-auth/sso";
|
|
2
1
|
//#region src/better-auth/saml-sign-in.d.ts
|
|
3
2
|
/**
|
|
4
3
|
* A SAML 2.0 identity provider people of the app sign in with, for example the company's Okta, Entra ID or Google
|
|
@@ -34,4 +33,31 @@ export type SamlProvider = {
|
|
|
34
33
|
export type SsoOptions = {
|
|
35
34
|
saml: SamlProvider[];
|
|
36
35
|
};
|
|
36
|
+
/**
|
|
37
|
+
* The providers with their defaults filled in: the name `SSO`, and the domains trimmed and lowercased. A malformed id,
|
|
38
|
+
* an id used twice or by another sign-in provider (`takenIds`), no domains or a domain that is not a host name, and IdP
|
|
39
|
+
* settings that are missing or not a URL are errors.
|
|
40
|
+
*/
|
|
41
|
+
export declare const resolveSamlProviders: (saml: SamlProvider[], takenIds: string[]) => {
|
|
42
|
+
name: string;
|
|
43
|
+
domains: string[];
|
|
44
|
+
/** The id: the button's `?sign-in=` link, the provider's paths and the namespace of its accounts. Lowercase letters, digits or "-". */
|
|
45
|
+
id: string;
|
|
46
|
+
/** The provider's metadata XML, or its entity ID, sign-in URL and signing certificate(s) (PEM; several while one rotates). */
|
|
47
|
+
idp: {
|
|
48
|
+
metadata: string;
|
|
49
|
+
} | {
|
|
50
|
+
entityId: string;
|
|
51
|
+
ssoUrl: string;
|
|
52
|
+
certificate: string | string[];
|
|
53
|
+
};
|
|
54
|
+
/** The assertion's attribute names, when they are not `email`, `givenName`, `surname` and `displayName`. */
|
|
55
|
+
attributes?: {
|
|
56
|
+
email?: string;
|
|
57
|
+
name?: string;
|
|
58
|
+
firstName?: string;
|
|
59
|
+
lastName?: string;
|
|
60
|
+
};
|
|
61
|
+
}[];
|
|
62
|
+
export type ResolvedSamlProvider = ReturnType<typeof resolveSamlProviders>[number];
|
|
37
63
|
//#endregion
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { authBasePath } from "./auth-base-path.js";
|
|
2
2
|
import { providerIdPattern } from "./platform-sign-in.js";
|
|
3
3
|
import { APIError, createAuthMiddleware } from "better-auth/api";
|
|
4
|
-
import { sso } from "@better-auth/sso";
|
|
5
4
|
//#region src/better-auth/saml-sign-in.ts
|
|
6
5
|
const domainPattern = /^[a-z0-9-]+(\.[a-z0-9-]+)*$/;
|
|
7
6
|
const checkIdp = (id, idp) => {
|
|
@@ -37,37 +36,6 @@ const resolveSamlProviders = (saml, takenIds) => {
|
|
|
37
36
|
};
|
|
38
37
|
/** The app's SP entity ID for a provider: its metadata URL on `baseURL`, the same on every origin. */
|
|
39
38
|
const samlEntityId = (baseURL, id) => `${baseURL.replace(/\/$/, "")}${authBasePath}/sso/saml2/sp/metadata?providerId=${encodeURIComponent(id)}`;
|
|
40
|
-
/** The provider as one of the SSO plugin's configured providers (`defaultSSO`). */
|
|
41
|
-
const defaultSsoEntry = (provider, baseURL) => {
|
|
42
|
-
const { idp, attributes = {} } = provider;
|
|
43
|
-
const mapping = Object.fromEntries(Object.entries(attributes).filter(([, name]) => name !== void 0));
|
|
44
|
-
return {
|
|
45
|
-
providerId: provider.id,
|
|
46
|
-
domain: provider.domains.join(","),
|
|
47
|
-
samlConfig: {
|
|
48
|
-
issuer: samlEntityId(baseURL, provider.id),
|
|
49
|
-
entryPoint: "ssoUrl" in idp ? idp.ssoUrl : "",
|
|
50
|
-
idpMetadata: "metadata" in idp ? { metadata: idp.metadata } : {
|
|
51
|
-
entityID: idp.entityId,
|
|
52
|
-
cert: idp.certificate
|
|
53
|
-
},
|
|
54
|
-
...Object.keys(mapping).length > 0 && { mapping }
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
|
-
};
|
|
58
|
-
/**
|
|
59
|
-
* Better Auth's SSO plugin with the configured providers. Their domains are trusted, so an address there links to the
|
|
60
|
-
* account that has it; organizations are not assigned by provider, and nobody registers providers.
|
|
61
|
-
*/
|
|
62
|
-
const samlPlugin = (providers, baseURL) => {
|
|
63
|
-
const { schema: _schema, ...plugin } = sso({
|
|
64
|
-
defaultSSO: providers.map((provider) => defaultSsoEntry(provider, baseURL)),
|
|
65
|
-
domainVerification: { enabled: true },
|
|
66
|
-
organizationProvisioning: { disabled: true },
|
|
67
|
-
providersLimit: 0
|
|
68
|
-
});
|
|
69
|
-
return plugin;
|
|
70
|
-
};
|
|
71
39
|
/** The SSO plugin's endpoints for providers kept in its table, and its OIDC callback, which Protobase does not serve. */
|
|
72
40
|
const samlDisabledPaths = [
|
|
73
41
|
"/sso/register",
|
|
@@ -130,4 +98,4 @@ const emailInDomains = (email, domains) => {
|
|
|
130
98
|
return domains.some((allowed) => domain === allowed || domain.endsWith(`.${allowed}`));
|
|
131
99
|
};
|
|
132
100
|
//#endregion
|
|
133
|
-
export {
|
|
101
|
+
export { emailInDomains, isSamlPath, resolveSamlProviders, samlDisabledPaths, samlEntityId, samlGuardPlugin, samlRefusal };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
//#region src/better-auth/secret-versions.ts
|
|
3
|
+
const versionOf = (secret) => Number.parseInt(createHash("sha256").update(`protobase-secret-version:${secret}`).digest("hex").slice(0, 7), 16);
|
|
4
|
+
/**
|
|
5
|
+
* Better Auth's options for the app's `secret` and its `previousSecrets`: `secrets`, which encrypt with the current
|
|
6
|
+
* one and decrypt with any of them, and `secret`, which Better Auth keeps for what was encrypted before secrets had
|
|
7
|
+
* versions. That is the oldest secret listed: the one in use when the app last ran without versions, unless it was
|
|
8
|
+
* changed since without being listed.
|
|
9
|
+
*/
|
|
10
|
+
const versionedSecrets = (secret, previousSecrets = []) => {
|
|
11
|
+
const all = [.../* @__PURE__ */ new Set([secret, ...previousSecrets])];
|
|
12
|
+
return {
|
|
13
|
+
secrets: all.map((value) => ({
|
|
14
|
+
version: versionOf(value),
|
|
15
|
+
value
|
|
16
|
+
})),
|
|
17
|
+
legacySecret: all.at(-1)
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
//#endregion
|
|
21
|
+
export { versionedSecrets };
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { createAuthEndpoint, createAuthMiddleware } from "better-auth/api";
|
|
2
|
+
import { createJwk } from "better-auth/plugins";
|
|
3
|
+
const daySeconds = 86400;
|
|
4
|
+
/** The JWT plugin's rotation for `options`: `rotationInterval` and `gracePeriod`, in seconds. */
|
|
5
|
+
const signingKeyRotation = ({ signingKeyDays = 30, signingKeyGraceDays = 7 } = {}) => {
|
|
6
|
+
if (!(signingKeyDays > 0)) throw new Error("signingKeyDays must be more than 0");
|
|
7
|
+
if (!(signingKeyGraceDays >= 1)) throw new Error("signingKeyGraceDays must be at least 1: tokens of `protobase token` last up to a day");
|
|
8
|
+
return {
|
|
9
|
+
rotationInterval: Math.round(signingKeyDays * daySeconds),
|
|
10
|
+
gracePeriod: Math.round(signingKeyGraceDays * daySeconds)
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
const isPrimary = (key) => key.alg === null || key.alg === void 0 || key.alg === "EdDSA";
|
|
14
|
+
const marginMs = 6e4;
|
|
15
|
+
const signingPaths = /* @__PURE__ */ new Set(["/token", "/oauth2/token"]);
|
|
16
|
+
/**
|
|
17
|
+
* Keeps a live EdDSA key for the app's tokens. The JWT plugin signs with the newest live key of the primary algorithm,
|
|
18
|
+
* else with the newest live key of any: once the EdDSA key expired while the ES256 one of the GoTrue-compatible
|
|
19
|
+
* tokens still lived, it would sign the app's tokens ES256 until that one expired too. So before every signing, a new
|
|
20
|
+
* EdDSA key is made when none lives; a key made before rotation was on (without an expiry) gets the one it would have
|
|
21
|
+
* had, its creation plus the rotation interval, so it rotates too. A key past its grace period, which no longer
|
|
22
|
+
* verifies, is deleted, so the store keeps a few keys (Better Auth reads at most 100). The key set is read once per
|
|
23
|
+
* key's lifetime: until the newest EdDSA key expires, signing reads nothing more.
|
|
24
|
+
*/
|
|
25
|
+
const signingKeys = (jwt) => {
|
|
26
|
+
const intervalMs = jwt.jwks.rotationInterval * 1e3;
|
|
27
|
+
const graceMs = jwt.jwks.gracePeriod * 1e3;
|
|
28
|
+
let liveUntil = 0;
|
|
29
|
+
let pending;
|
|
30
|
+
const check = async (ctx) => {
|
|
31
|
+
const now = Date.now();
|
|
32
|
+
const { adapter } = ctx.context;
|
|
33
|
+
const dated = (await adapter.findMany({ model: "jwks" })).map((key) => ({
|
|
34
|
+
...key,
|
|
35
|
+
undated: !key.expiresAt,
|
|
36
|
+
expiresAt: key.expiresAt ?? new Date(key.createdAt.getTime() + intervalMs)
|
|
37
|
+
}));
|
|
38
|
+
const retired = dated.filter((key) => key.expiresAt.getTime() + graceMs <= now);
|
|
39
|
+
if (retired.length > 0) await adapter.deleteMany({
|
|
40
|
+
model: "jwks",
|
|
41
|
+
where: [{
|
|
42
|
+
field: "id",
|
|
43
|
+
operator: "in",
|
|
44
|
+
value: retired.map((key) => key.id)
|
|
45
|
+
}]
|
|
46
|
+
});
|
|
47
|
+
const keys = dated.filter((key) => !retired.includes(key));
|
|
48
|
+
await Promise.all(keys.filter((key) => key.undated).map((key) => adapter.update({
|
|
49
|
+
model: "jwks",
|
|
50
|
+
where: [{
|
|
51
|
+
field: "id",
|
|
52
|
+
value: key.id
|
|
53
|
+
}],
|
|
54
|
+
update: { expiresAt: key.expiresAt }
|
|
55
|
+
})));
|
|
56
|
+
liveUntil = (keys.filter((key) => isPrimary(key) && key.expiresAt.getTime() - marginMs > now).sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime())[0] ?? await createJwk(ctx, jwt)).expiresAt.getTime() - marginMs;
|
|
57
|
+
};
|
|
58
|
+
/** Makes sure a live EdDSA key signs the next token; concurrent callers share one check. */
|
|
59
|
+
const ensure = async (ctx) => {
|
|
60
|
+
if (Date.now() < liveUntil) return;
|
|
61
|
+
pending ??= check(ctx).finally(() => {
|
|
62
|
+
pending = void 0;
|
|
63
|
+
});
|
|
64
|
+
await pending;
|
|
65
|
+
};
|
|
66
|
+
return {
|
|
67
|
+
plugin: {
|
|
68
|
+
id: "protobase-signing-keys",
|
|
69
|
+
endpoints: {
|
|
70
|
+
/** Makes sure a live EdDSA key signs the next token, for signing outside the plugin's paths (`issueToken`). */
|
|
71
|
+
ensureSigningKey: createAuthEndpoint.serverOnly({ method: "POST" }, async (ctx) => {
|
|
72
|
+
await ensure(ctx);
|
|
73
|
+
return ctx.json({ ok: true });
|
|
74
|
+
}) },
|
|
75
|
+
hooks: { before: [{
|
|
76
|
+
matcher: (ctx) => signingPaths.has(ctx.path ?? ""),
|
|
77
|
+
handler: createAuthMiddleware(async (ctx) => {
|
|
78
|
+
await ensure(ctx);
|
|
79
|
+
})
|
|
80
|
+
}] }
|
|
81
|
+
},
|
|
82
|
+
ensure
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
//#endregion
|
|
86
|
+
export { signingKeyRotation, signingKeys };
|
|
@@ -24,6 +24,7 @@ const issueToken = async (auth, options) => {
|
|
|
24
24
|
if (user.banned) throw new Error(`${options.email} is banned`);
|
|
25
25
|
const issuedAt = Math.floor(Date.now() / 1e3);
|
|
26
26
|
const { role } = narrowClaims({ role: parseRoles(user.role).join(",") }, [user.lastRole], Boolean(auth.organizations));
|
|
27
|
+
await auth.api.ensureSigningKey();
|
|
27
28
|
const { token } = await auth.api.signJWT({ body: { payload: {
|
|
28
29
|
iat: issuedAt,
|
|
29
30
|
exp: issuedAt + ttl,
|
|
@@ -16,7 +16,7 @@ const userFields = {
|
|
|
16
16
|
last_role: "lastRole",
|
|
17
17
|
last_organization_id: "lastOrganizationId"
|
|
18
18
|
};
|
|
19
|
-
/** The user table's names, from `
|
|
19
|
+
/** The user table's names, from `auth.users` option; unknown columns are an error. */
|
|
20
20
|
const userTable = ({ table = "user", columns = {}, metadata } = {}) => {
|
|
21
21
|
const unknown = Object.keys(columns).find((name) => !(name in userFields));
|
|
22
22
|
if (unknown !== void 0) throw new Error(`users.columns names "${unknown}", which is not a column of the user table: ${Object.keys(userFields).join(", ")}`);
|
|
@@ -10,7 +10,7 @@ export type LinkedAccount = {
|
|
|
10
10
|
};
|
|
11
11
|
/**
|
|
12
12
|
* Without `password` the user signs in by emailed code, passkey or a sign-in provider only. `metadata` lands in the
|
|
13
|
-
* user metadata column, which `
|
|
13
|
+
* user metadata column, which `auth.users.metadata` names; it needs one.
|
|
14
14
|
*/
|
|
15
15
|
export type NewUser = {
|
|
16
16
|
email: string;
|
package/dist/create-admin.d.ts
CHANGED
|
@@ -35,6 +35,8 @@ export type CreateAdminInput = {
|
|
|
35
35
|
auth?: AdminAuth;
|
|
36
36
|
/** API functions of the app's own, each served at `<systemPath>/functions/<name>` (see `defineFunction`). */
|
|
37
37
|
functions?: Record<string, FunctionSource>;
|
|
38
|
+
/** The app's secret (`secret`): it signs public forms' bot checks, and upload tickets unless `files.secret` names another. */
|
|
39
|
+
secret?: string;
|
|
38
40
|
/** Where file fields keep their bytes (see `FilesOptions`). */
|
|
39
41
|
files?: FilesOptions;
|
|
40
42
|
/** Where the changes that resources' events are raised from are captured (see `EventsOptions`). */
|
|
@@ -45,9 +47,9 @@ export type CreateAdminInput = {
|
|
|
45
47
|
jobs?: JobDefinition[];
|
|
46
48
|
/** Where the resources' events are delivered (`subscription(...)` exports of the config module). */
|
|
47
49
|
subscriptions?: SubscriptionDefinition[];
|
|
48
|
-
/** Webhook subscriptions made in the admin app, from `
|
|
50
|
+
/** Webhook subscriptions made in the admin app, from `webhooks: {}` (see `WebhooksOptions`). */
|
|
49
51
|
webhooks?: WebhooksOptions;
|
|
50
|
-
/** Each user's devices and the endpoints that register them, from `
|
|
52
|
+
/** Each user's devices and the endpoints that register them, from `notifications: {}` (see `NotificationsOptions`). */
|
|
51
53
|
notifications?: NotificationsOptions;
|
|
52
54
|
/**
|
|
53
55
|
* The app's iOS and Android build (see `MobileConfig`): the API answers its Capacitor origins through CORS, and sign-in
|
|
@@ -88,5 +90,5 @@ export type CreateAdminInput = {
|
|
|
88
90
|
upgradeWebSocket?: UpgradeWebSocket;
|
|
89
91
|
};
|
|
90
92
|
/** The admin REST API as a Hono app. It uses only Web APIs, so it runs on Node, Workers and anywhere else Hono does. */
|
|
91
|
-
export declare const createAdmin: ({ resources: appResources, views: appViews, pages, userMenu, bottomBars, db, authenticate, auth, functions, files: filesOptions, events, history: historyOptions, jobs, subscriptions, webhooks: webhooksOptions, notifications, mobile, app: identity, icons, bundlePlugins, fieldTypes, options, formsDifficulty, commentUsers: givenCommentUsers, verifyToken, upgradeWebSocket }: CreateAdminInput) => Admin;
|
|
93
|
+
export declare const createAdmin: ({ resources: appResources, views: appViews, pages, userMenu, bottomBars, db, authenticate, auth, functions, secret, files: filesOptions, events, history: historyOptions, jobs, subscriptions, webhooks: webhooksOptions, notifications, mobile, app: identity, icons, bundlePlugins, fieldTypes, options, formsDifficulty, commentUsers: givenCommentUsers, verifyToken, upgradeWebSocket }: CreateAdminInput) => Admin;
|
|
92
94
|
//#endregion
|
package/dist/create-admin.js
CHANGED
|
@@ -103,7 +103,7 @@ const declaredRoles = (auth, roles) => {
|
|
|
103
103
|
return names.length > 0 ? [...new Set(names)] : void 0;
|
|
104
104
|
};
|
|
105
105
|
/** The admin REST API as a Hono app. It uses only Web APIs, so it runs on Node, Workers and anywhere else Hono does. */
|
|
106
|
-
const createAdmin = ({ resources: appResources, views: appViews = [], pages = [], userMenu, bottomBars = [], db, authenticate, auth, functions = {}, files: filesOptions, events, history: historyOptions, jobs = [], subscriptions = [], webhooks: webhooksOptions, notifications, mobile, app: identity, icons, bundlePlugins = [], fieldTypes = {}, options = {}, formsDifficulty, commentUsers: givenCommentUsers, verifyToken, upgradeWebSocket }) => {
|
|
106
|
+
const createAdmin = ({ resources: appResources, views: appViews = [], pages = [], userMenu, bottomBars = [], db, authenticate, auth, functions = {}, secret, files: filesOptions, events, history: historyOptions, jobs = [], subscriptions = [], webhooks: webhooksOptions, notifications, mobile, app: identity, icons, bundlePlugins = [], fieldTypes = {}, options = {}, formsDifficulty, commentUsers: givenCommentUsers, verifyToken, upgradeWebSocket }) => {
|
|
107
107
|
const basePath = options.basePath ?? "/api/v1";
|
|
108
108
|
const appModels = appResources.map((resource) => resource.toModel());
|
|
109
109
|
const withComments = appModels.some((model) => model.comments);
|
|
@@ -154,6 +154,7 @@ const createAdmin = ({ resources: appResources, views: appViews = [], pages = []
|
|
|
154
154
|
views: viewModels,
|
|
155
155
|
limits: options.roles?.limits ?? [],
|
|
156
156
|
env: globalThis.process?.env ?? {},
|
|
157
|
+
...secret && { secret },
|
|
157
158
|
...formsDifficulty && { difficulty: formsDifficulty }
|
|
158
159
|
});
|
|
159
160
|
const systemPath = basePath.slice(0, basePath.lastIndexOf("/"));
|
|
@@ -178,6 +179,7 @@ const createAdmin = ({ resources: appResources, views: appViews = [], pages = []
|
|
|
178
179
|
});
|
|
179
180
|
const files = createFilesRuntime({
|
|
180
181
|
...filesOptions && { options: filesOptions },
|
|
182
|
+
...secret && { secret },
|
|
181
183
|
env: globalThis.process?.env ?? {},
|
|
182
184
|
models: registry.entries.map((entry) => entry.model),
|
|
183
185
|
systemPath,
|
|
@@ -27,7 +27,7 @@ const entriesOf = (env) => {
|
|
|
27
27
|
}))];
|
|
28
28
|
};
|
|
29
29
|
const checkApart = (entries, env) => {
|
|
30
|
-
for (const name of ["
|
|
30
|
+
for (const name of ["PROTOBASE_SECRET", "PROTOBASE_SECRET_KEY"]) {
|
|
31
31
|
const secret = env[name]?.trim();
|
|
32
32
|
const same = secret && entries.find((entry) => entry.text === secret);
|
|
33
33
|
if (same) throw new Error(`${same.where} is the same as ${name}: give encryption a key of its own`);
|
package/dist/files/options.d.ts
CHANGED
|
@@ -1,21 +1,18 @@
|
|
|
1
1
|
import { Sharp } from "./images.js";
|
|
2
2
|
import { FileProvider } from "./store.js";
|
|
3
3
|
//#region src/files/options.d.ts
|
|
4
|
-
/** `files`
|
|
4
|
+
/** Where file fields keep their bytes, as the API runs with them: `files` of `protobase.config.ts` with its providers made. Environment variables override it (see `resolveProviders`). */
|
|
5
5
|
export type FilesOptions = {
|
|
6
6
|
/**
|
|
7
|
-
* Providers by name
|
|
8
|
-
*
|
|
7
|
+
* Providers by name. A name is part of every stored value, so name the role (`archive`), not the vendor. Without
|
|
8
|
+
* config, `private` and `public` are folders under `data/files`.
|
|
9
9
|
*/
|
|
10
10
|
providers?: Record<string, FileProvider>;
|
|
11
11
|
/** How long bytes outlive their last reference, for restores; default `1 day`. Public providers default to 0. */
|
|
12
12
|
retention?: number | string;
|
|
13
|
-
/** Signs upload tickets and download URLs; default `PROTOBASE_FILES_SECRET`, then `
|
|
13
|
+
/** Signs upload tickets and download URLs; default `PROTOBASE_FILES_SECRET`, then the app's `secret` (`PROTOBASE_SECRET`). */
|
|
14
14
|
secret?: string;
|
|
15
|
-
/**
|
|
16
|
-
* The image library that makes the variants and placeholders of image fields: `import sharp from 'sharp'` in the
|
|
17
|
-
* config, so a built bundle carries it with its native add-on.
|
|
18
|
-
*/
|
|
15
|
+
/** The image library that makes the variants and placeholders of image fields: sharp's default export. */
|
|
19
16
|
sharp?: Sharp;
|
|
20
17
|
/**
|
|
21
18
|
* Hosts whose images the admin app draws with the page's referrer, besides the app's own and those its providers link
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { FileProvider } from "./store.js";
|
|
2
|
+
import { LocalFilesOptions } from "./local-files.js";
|
|
3
|
+
import { S3FilesOptions } from "./s3-files.js";
|
|
4
|
+
//#region src/files/provider-settings.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* A built-in file provider in `files.providers`, as data: `{ kind: 'local', dir }`, a folder on local disk, or
|
|
7
|
+
* `{ kind: 's3', bucket }`, an S3-compatible bucket. The provider is made when the app serves.
|
|
8
|
+
*/
|
|
9
|
+
export type FileProviderSettings = ({
|
|
10
|
+
kind: 'local';
|
|
11
|
+
} & LocalFilesOptions) | ({
|
|
12
|
+
kind: 's3';
|
|
13
|
+
} & S3FilesOptions);
|
|
14
|
+
/** The provider the settings describe. */
|
|
15
|
+
export declare const fileProviderOf: (name: string, settings: FileProviderSettings) => FileProvider;
|
|
16
|
+
//#endregion
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { localFiles } from "./local-files.js";
|
|
2
|
+
import { s3Files } from "./s3-files.js";
|
|
3
|
+
//#region src/files/provider-settings.ts
|
|
4
|
+
/** The provider the settings describe. */
|
|
5
|
+
const fileProviderOf = (name, settings) => {
|
|
6
|
+
if (settings.kind === "local") {
|
|
7
|
+
const { kind: _, ...options } = settings;
|
|
8
|
+
return localFiles(options);
|
|
9
|
+
}
|
|
10
|
+
if (settings.kind === "s3") {
|
|
11
|
+
const { kind: _, ...options } = settings;
|
|
12
|
+
return s3Files(options);
|
|
13
|
+
}
|
|
14
|
+
throw new Error(`files.providers.${name}: kind is "local", "s3" or "custom", whose provider is the default export of files/${name}.ts`);
|
|
15
|
+
};
|
|
16
|
+
//#endregion
|
|
17
|
+
export { fileProviderOf };
|
package/dist/files/runtime.js
CHANGED
|
@@ -13,7 +13,7 @@ const imageFields = (models) => models.flatMap((model) => Object.values(model.fi
|
|
|
13
13
|
* The runtime, when a resource has a file field, the config names providers or the app serves `/api/sb/storage/v1`. It fails at startup when a field's
|
|
14
14
|
* provider is not configured, nothing signs uploads, or a field makes image variants or placeholders without sharp.
|
|
15
15
|
*/
|
|
16
|
-
const createFilesRuntime = ({ options = {}, env, models, systemPath, storage: servesStorage = false }) => {
|
|
16
|
+
const createFilesRuntime = ({ options = {}, env, secret: appSecret, models, systemPath, storage: servesStorage = false }) => {
|
|
17
17
|
const storageName = servesStorage ? storageProviderName(options) : void 0;
|
|
18
18
|
const storage = storageName && options.storage !== false ? {
|
|
19
19
|
provider: storageName,
|
|
@@ -22,10 +22,10 @@ const createFilesRuntime = ({ options = {}, env, models, systemPath, storage: se
|
|
|
22
22
|
const fieldProviders = models.flatMap((model) => Object.values(model.fields).flatMap((field) => field.file ? [field.file.provider] : []));
|
|
23
23
|
const used = [.../* @__PURE__ */ new Set([...fieldProviders, ...storage ? [storage.provider] : []])];
|
|
24
24
|
if (used.length === 0 && !options.providers) return void 0;
|
|
25
|
-
const secret = options.secret ?? env.PROTOBASE_FILES_SECRET ?? env.
|
|
26
|
-
if (!secret) throw new Error("File fields and /api/sb/storage/v1 need a secret to sign uploads: set
|
|
25
|
+
const secret = options.secret ?? env.PROTOBASE_FILES_SECRET ?? appSecret ?? env.PROTOBASE_SECRET;
|
|
26
|
+
if (!secret) throw new Error("File fields and /api/sb/storage/v1 need a secret to sign uploads: set secret in protobase.config.ts, files.secret or PROTOBASE_FILES_SECRET");
|
|
27
27
|
const images = imageFields(models);
|
|
28
|
-
if (images.length > 0 && !options.sharp) throw new Error(`${images.join(", ")} make image variants or placeholders, which need sharp: add it to the project (bun add sharp), then
|
|
28
|
+
if (images.length > 0 && !options.sharp) throw new Error(`${images.join(", ")} make image variants or placeholders, which need sharp: add it to the project (bun add sharp), then give the config files: { sharp: () => import('sharp') }`);
|
|
29
29
|
const providers = resolveProviders(options, env, used);
|
|
30
30
|
const retention = retentionOf(options, env);
|
|
31
31
|
return {
|
package/dist/forms/runtime.js
CHANGED
|
@@ -12,15 +12,15 @@ const anonymousCreates = (limits) => (resource) => {
|
|
|
12
12
|
* The public forms of the views, checked, with the challenges that guard them and their rate limit; `undefined` without
|
|
13
13
|
* any. Fails at startup on a form that cannot be served and when nothing signs the challenges.
|
|
14
14
|
*/
|
|
15
|
-
const createFormsRuntime = ({ registry, views, limits, env, difficulty }) => {
|
|
15
|
+
const createFormsRuntime = ({ registry, views, limits, env, secret: appSecret, difficulty }) => {
|
|
16
16
|
const declared = [...views].sort((a, b) => Number(a.roles !== void 0) - Number(b.roles !== void 0)).flatMap((view) => (view.forms ?? []).map((form) => ({
|
|
17
17
|
form,
|
|
18
18
|
view
|
|
19
19
|
})));
|
|
20
20
|
if (declared.length === 0) return void 0;
|
|
21
21
|
const forms = checkForms(registry, declared, anonymousCreates(limits));
|
|
22
|
-
const secret = env.PROTOBASE_FORMS_SECRET ?? env.
|
|
23
|
-
if (!secret) throw new Error("Public forms need a secret to sign their bot checks: set
|
|
22
|
+
const secret = env.PROTOBASE_FORMS_SECRET ?? appSecret ?? env.PROTOBASE_SECRET;
|
|
23
|
+
if (!secret) throw new Error("Public forms need a secret to sign their bot checks: set secret in protobase.config.ts, or PROTOBASE_FORMS_SECRET");
|
|
24
24
|
return {
|
|
25
25
|
forms,
|
|
26
26
|
challenges: createFormChallenges(secret, { ...difficulty && { difficulty } }),
|
|
@@ -4,7 +4,7 @@ import { goTrueUser } from "./user-json.js";
|
|
|
4
4
|
import { accessClaims, goTrueSession } from "./session-json.js";
|
|
5
5
|
import * as z$1 from "zod";
|
|
6
6
|
import { APIError, createAuthEndpoint } from "better-auth/api";
|
|
7
|
-
import {
|
|
7
|
+
import { signJWT } from "better-auth/plugins";
|
|
8
8
|
import { generateRandomString } from "better-auth/crypto";
|
|
9
9
|
//#region src/gotrue/sessions-plugin.ts
|
|
10
10
|
const refreshTokenNotFound = () => new APIError("BAD_REQUEST", {
|
|
@@ -16,13 +16,7 @@ const refreshTokenNotFound = () => new APIError("BAD_REQUEST", {
|
|
|
16
16
|
* so signing out anywhere, a ban or a revoked session ends it, and refreshing gives the session a new token, so each
|
|
17
17
|
* refresh token works once. Server-side endpoints only, for `goTrueRoutes`.
|
|
18
18
|
*/
|
|
19
|
-
const goTrueSessionsPlugin = ({ issuer, jwt, policy }) => {
|
|
20
|
-
let primaryKeyMade = false;
|
|
21
|
-
const makePrimaryKey = async (ctx) => {
|
|
22
|
-
if (primaryKeyMade) return;
|
|
23
|
-
if (!(await ctx.context.adapter.findMany({ model: "jwks" })).some((key) => key.alg === null || key.alg === void 0 || key.alg === "EdDSA")) await createJwk(ctx, jwt);
|
|
24
|
-
primaryKeyMade = true;
|
|
25
|
-
};
|
|
19
|
+
const goTrueSessionsPlugin = ({ issuer, jwt, signingKey, policy }) => {
|
|
26
20
|
const sessionOf = async (ctx, sessionToken) => {
|
|
27
21
|
const found = await ctx.context.internalAdapter.findSession(sessionToken);
|
|
28
22
|
if (!found) throw refreshTokenNotFound();
|
|
@@ -31,7 +25,7 @@ const goTrueSessionsPlugin = ({ issuer, jwt, policy }) => {
|
|
|
31
25
|
if (refusal) throw new APIError("FORBIDDEN", refusal);
|
|
32
26
|
const accounts = await ctx.context.internalAdapter.findAccounts(user.id);
|
|
33
27
|
const now = Math.floor(Date.now() / 1e3);
|
|
34
|
-
await
|
|
28
|
+
await signingKey(ctx);
|
|
35
29
|
const accessToken = await signJWT(ctx, {
|
|
36
30
|
options: jwt,
|
|
37
31
|
payload: accessClaims({
|
package/dist/index.d.ts
CHANGED
|
@@ -51,20 +51,25 @@ import { RuntimeOptions, runtimeUrl, runtimeVariable, seesRuntime } from "./runt
|
|
|
51
51
|
import { AdminOptions } from "./admin-options.js";
|
|
52
52
|
import { CreateAdminInput, createAdmin } from "./create-admin.js";
|
|
53
53
|
import { handleDroppedConnections } from "./dropped-connections.js";
|
|
54
|
-
import { AppPoolConfig, PgModule,
|
|
54
|
+
import { AppPoolConfig, PgModule, poolWaitMs, readDbConnections } from "./app-pool.js";
|
|
55
55
|
import { ConnectionsBusy } from "./connections-busy.js";
|
|
56
56
|
import { isBackgroundWork, runInBackground, wantsLongQueries } from "./background-work.js";
|
|
57
57
|
import { longQueryTimeoutMs } from "./statement-timeout.js";
|
|
58
58
|
import { checkViewQueries } from "./check-view-queries.js";
|
|
59
|
-
import { ProjectConfig, defineConfig, mergeConfig } from "./project-config.js";
|
|
60
59
|
import { consoleAuditQueue } from "./audit/console-queue.js";
|
|
61
60
|
import { JwtOptions, JwtVerifyOptions, jwtAuthenticator, jwtVerifier } from "./auth/jwt.js";
|
|
61
|
+
import { SignInPolicy, SignInRule, StaffAccessRule, defaultSignInPolicy, signInPolicyMethods } from "./better-auth/sign-in-policy.js";
|
|
62
|
+
import { StaffSignIn } from "./better-auth/staff-log.js";
|
|
63
|
+
import { RoleDefinition, RolesInput } from "./better-auth/organizations/role-definitions.js";
|
|
64
|
+
import { OrganizationRole, StoredMember, StoredOrganization } from "./better-auth/organizations/store.js";
|
|
65
|
+
import { OrganizationsOptions } from "./better-auth/organizations/options.js";
|
|
66
|
+
import { AuthHooks, AuthSettings, HookContext } from "./better-auth/auth-settings.js";
|
|
62
67
|
import { TrustedApp, withTrustedApps } from "./better-auth/app-tokens.js";
|
|
63
|
-
import { BetterAuthAuthenticator, BetterAuthAuthenticatorOptions,
|
|
68
|
+
import { BetterAuthAuthenticator, BetterAuthAuthenticatorOptions, betterAuthTokens } from "./better-auth/authenticator.js";
|
|
69
|
+
import { AuthenticateSettings } from "./better-auth/authenticate-settings.js";
|
|
64
70
|
import { parseRoles } from "./better-auth/parse-roles.js";
|
|
65
71
|
import { LinkedAccount, NewUser, StoredUser, createUser, deleteUser, hasUsers, listUsers, roleChoices, setUserBanned, setUserRole } from "./better-auth/users.js";
|
|
66
72
|
import { IssueTokenOptions, issueToken, maxTokenTtlSeconds } from "./better-auth/tokens.js";
|
|
67
|
-
import { SignInPolicy, SignInRule, StaffAccessRule, defaultSignInPolicy, signInPolicyMethods } from "./better-auth/sign-in-policy.js";
|
|
68
73
|
import { passwordLength } from "./better-auth/new-account-password.js";
|
|
69
74
|
import { OperatorProvider, readOperatorSettings } from "./better-auth/operator-provider.js";
|
|
70
75
|
import { isOAuthWellKnownPath, oauthWellKnownPaths, webauthnPath } from "./better-auth/origins.js";
|
|
@@ -72,7 +77,7 @@ import { goTruePath } from "./gotrue/keys.js";
|
|
|
72
77
|
import { supabasePath } from "./supabase-paths.js";
|
|
73
78
|
import { realtimeLimits } from "./realtime/realtime-limits.js";
|
|
74
79
|
import { capSocketMessages, honorSocketMessageCaps, socketMessageCapOf } from "./functions/socket-message-cap.js";
|
|
75
|
-
import { defaultAppName, shownAppName } from "./app-name.js";
|
|
80
|
+
import { appNameOver, defaultAppName, shownAppName } from "./app-name.js";
|
|
76
81
|
import { webManifestPath } from "./web-app/web-manifest-route.js";
|
|
77
82
|
import { PlatformSignIn, readPlatformSignIn } from "./better-auth/platform-sign-in.js";
|
|
78
83
|
import { authSchemaMigration, checkAuthSchema } from "./better-auth/auth-schema.js";
|
|
@@ -86,12 +91,10 @@ import { ResourceChange, recordOf, resourceChange } from "./changes/resource-cha
|
|
|
86
91
|
import { eventMatcher } from "./changes/match-events.js";
|
|
87
92
|
import { parseColumns, readOutbox } from "./changes/outbox.js";
|
|
88
93
|
import { newWebhookSecret } from "./webhooks/standard-webhooks.js";
|
|
89
|
-
import { webhooks } from "./webhooks/table/plugin.js";
|
|
90
94
|
import { checkWebhooksSchema, webhooksMigration } from "./webhooks/table/schema.js";
|
|
91
95
|
import { checkComments, commentsMigration } from "./comments/comments-sql.js";
|
|
92
96
|
import { CheckAiInput, checkAi } from "./ai/check-ai.js";
|
|
93
97
|
import { CommentItem } from "./comments/comment-item.js";
|
|
94
|
-
import { notifications } from "./notifications/plugin.js";
|
|
95
98
|
import { checkNotificationsSchema, notificationsMigration } from "./notifications/schema.js";
|
|
96
99
|
import { deviceStore, removeDevicesWithUsers } from "./notifications/device-store-of.js";
|
|
97
100
|
import { DeviceStoreError, postgresDeviceStore } from "./notifications/postgres-store.js";
|
|
@@ -105,11 +108,7 @@ import { sendNotification } from "./notifications/send-notification.js";
|
|
|
105
108
|
import { VapidSettings, readVapidSettings, vapidPrivateKeyVariable, vapidPublicKeyVariable, vapidSubjectVariable } from "./notifications/web-push/vapid-settings.js";
|
|
106
109
|
import { WebPushOptions, webPushSender } from "./notifications/web-push/web-push-sender.js";
|
|
107
110
|
import { generateVapidKeys } from "./notifications/web-push/keys.js";
|
|
108
|
-
import { RoleDefinition, RolesInput } from "./better-auth/organizations/role-definitions.js";
|
|
109
|
-
import { OrganizationRole, StoredMember, StoredOrganization } from "./better-auth/organizations/store.js";
|
|
110
|
-
import { OrganizationsOptions } from "./better-auth/organizations/options.js";
|
|
111
111
|
import { MemberInput, NewOrganization, addAppRoleToOwners, addMember, createOrganization, listOrganizations, removeMember, setMemberRoles } from "./better-auth/organizations/host.js";
|
|
112
|
-
import { StaffSignIn } from "./better-auth/staff-log.js";
|
|
113
112
|
import { AssistantBackend, assistantProtocolRoutes } from "./assistant/protocol-routes.js";
|
|
114
113
|
import { fileConversationStore } from "./assistant/file-conversation-store.js";
|
|
115
114
|
import { withCacheBreakpoints } from "./assistant/cache-breakpoints.js";
|
|
@@ -139,9 +138,10 @@ import { SignatureOptions, StandardWebhookOptions, verifySignature, verifyStanda
|
|
|
139
138
|
import { requireEnv } from "./functions/require-env.js";
|
|
140
139
|
import { backgroundSettled, waitUntil } from "./functions/wait-until.js";
|
|
141
140
|
import { FileLimits, limitedFileStore, storeUsage } from "./files/limits.js";
|
|
142
|
-
import { LocalFilesOptions, localFileStore
|
|
141
|
+
import { LocalFilesOptions, localFileStore } from "./files/local-files.js";
|
|
142
|
+
import { S3Bucket, S3FilesOptions, S3ListPage, S3Object, s3FileStore } from "./files/s3-files.js";
|
|
143
|
+
import { FileProviderSettings } from "./files/provider-settings.js";
|
|
143
144
|
import { StoreFileInput, storeFile } from "./files/store-file.js";
|
|
144
|
-
import { S3Bucket, S3FilesOptions, S3ListPage, S3Object, s3FileStore, s3Files } from "./files/s3-files.js";
|
|
145
145
|
import { storageProvider } from "./files/storage-provider.js";
|
|
146
146
|
import { objectKey } from "./storage/object-key.js";
|
|
147
147
|
import { FileCleanupInput, createFileCleanup } from "./files/file-cleanup.js";
|
|
@@ -154,6 +154,7 @@ import { FileRef, formatUri, variantPath } from "./files/uri.js";
|
|
|
154
154
|
import { aspectRatio, fileSize, fileType, imageSize, processor } from "./files/processors.js";
|
|
155
155
|
import { defineJob, isJobDefinition, jobDefinitions } from "./jobs/define-job.js";
|
|
156
156
|
import { FatalJobError } from "./jobs/run-job.js";
|
|
157
|
+
import { JobDeclaration, JobRun, enqueueJob } from "./jobs/declared-job.js";
|
|
157
158
|
import { isSchedule } from "./jobs/schedule.js";
|
|
158
159
|
import { EmailComponent, EmailOptions, EmailTemplate, RenderedEmail, defineEmail } from "./mail/define-email.js";
|
|
159
160
|
import { DrainResult, JobsRuntime, StartJobsOptions, startJobs } from "./jobs/runtime.js";
|
|
@@ -162,5 +163,5 @@ import { checkJobsSchema, jobsSchema, jobsSchemaMigration } from "./jobs/schema.
|
|
|
162
163
|
import { MobileRelease, ReleaseFile, ServedReleaseFile, composeRelease, releaseManifest } from "./mobile-release/release.js";
|
|
163
164
|
import { MobileReleaseAppInput, OfferedRelease, mobileReleaseApp } from "./mobile-release/release-app.js";
|
|
164
165
|
import { mobileSigningKeyVariable, readSigningKey } from "./mobile-release/signing-key.js";
|
|
165
|
-
import { AdminAuth, CreateAuthOptions, UserCreatedHook,
|
|
166
|
-
export { type Admin, type AdminAuth, type AdminOptions, type ApiFunction, type ApiKeys, type ApiKeysOptions, type ApnsEnvironment, type AppIcons, type AppIdentity, type AppPoolConfig, type ApplyOptions, type ApplyResult, type ApprovalAnswer, type ApprovalRequest, type AssistantBackend, type AssistantOptions, type AssistantSettings, type AssistantTool, type AuditEvent, type AuditQueue, type Authenticator, type BatchOperation, type BatchResult, type BetterAuthAuthenticator, type BetterAuthAuthenticatorOptions, type Caller, type CallerOptions, type CapturedRow, type CascadingKey, type ChatMessage, type ChatTextPart, type CheckAiInput, type CleanupEntry, type CleanupReport, type CleanupSchedule, type CoalescedChange, type CommentItem, type CommentUsers, type Completion, type CompletionOptions, ConnectionsBusy, type Conversation, type ConversationRecord, type ConversationStore, type ConversationsOptions, type CorsOptions, type CorsOrigins, type CreateAdminInput, type CreateAuthOptions, type Device, type DeviceColumn, type DeviceKind, type DeviceStore, DeviceStoreError, type DrainResult, type EmailComponent, type EmailOptions, type EmailTemplate, type EncryptionStatus, type EncryptionTools, type EncryptionToolsInput, type EnqueueOptions, type ErrorReporter, type ErrorReportingOptions, type ErrorReportingSettings, type EventData, type EventsOptions, FatalJobError, type FieldApplied, type FieldStatus, type FileCleanupInput, type FileLimits, type FileObject, type FileProvider, type FileRef, type FileStore, type FileVariantObject, type FilesOptions, type FunctionApp, type FunctionCaller, type FunctionContext, type FunctionEnv, type FunctionHandler, type FunctionOptions, type FunctionRecords, type FunctionSocket, type FunctionSource, type HistoryColumn, type HistoryOptions, type HistoryPosition, type HistoryStore, HistoryStoreError, HttpProblem, type IssueTokenOptions, type JobContext, type JobDefinition, type JobOptions, type JobsRuntime, type JsonObject, type JsonValue, type JwtOptions, type JwtVerifyOptions, type KeyFunctionContext, type LinkedAccount, type ListParams, type LocalFilesOptions, type MailMessage, type Mailer, type MapLayer, type MapOptions, type MapSettings, type McpApprovals, type McpGateInput, type McpHandlerInput, type McpRoutesInput, type McpServerInput, type McpToolsInput, type McpWrites, type MemberInput, type Membership, MissingCredentials, type MobileConfig, type MobileRelease, type MobileReleaseAppInput, ModelError, type ModelSettings, type NewDevice, type NewNotification, type NewOrganization, type NewUser, type NotificationRecipients, NotificationSendError, type NotificationsOptions, type OfferedRelease, type OperatorProvider, type OrganizationRole, type OrganizationsOptions, type PgModule, type PipelineHook, type PlatformSignIn, type PluginOption, type PluginRef, type PngIcon, type
|
|
166
|
+
import { AdminAuth, CreateAuthOptions, UserCreatedHook, normalizeRoles } from "./better-auth/create-auth.js";
|
|
167
|
+
export { type Admin, type AdminAuth, type AdminOptions, type ApiFunction, type ApiKeys, type ApiKeysOptions, type ApnsEnvironment, type AppIcons, type AppIdentity, type AppPoolConfig, type ApplyOptions, type ApplyResult, type ApprovalAnswer, type ApprovalRequest, type AssistantBackend, type AssistantOptions, type AssistantSettings, type AssistantTool, type AuditEvent, type AuditQueue, type AuthHooks, type AuthSettings, type AuthenticateSettings, type Authenticator, type BatchOperation, type BatchResult, type BetterAuthAuthenticator, type BetterAuthAuthenticatorOptions, type Caller, type CallerOptions, type CapturedRow, type CascadingKey, type ChatMessage, type ChatTextPart, type CheckAiInput, type CleanupEntry, type CleanupReport, type CleanupSchedule, type CoalescedChange, type CommentItem, type CommentUsers, type Completion, type CompletionOptions, ConnectionsBusy, type Conversation, type ConversationRecord, type ConversationStore, type ConversationsOptions, type CorsOptions, type CorsOrigins, type CreateAdminInput, type CreateAuthOptions, type Device, type DeviceColumn, type DeviceKind, type DeviceStore, DeviceStoreError, type DrainResult, type EmailComponent, type EmailOptions, type EmailTemplate, type EncryptionStatus, type EncryptionTools, type EncryptionToolsInput, type EnqueueOptions, type ErrorReporter, type ErrorReportingOptions, type ErrorReportingSettings, type EventData, type EventsOptions, FatalJobError, type FieldApplied, type FieldStatus, type FileCleanupInput, type FileLimits, type FileObject, type FileProvider, type FileProviderSettings, type FileRef, type FileStore, type FileVariantObject, type FilesOptions, type FunctionApp, type FunctionCaller, type FunctionContext, type FunctionEnv, type FunctionHandler, type FunctionOptions, type FunctionRecords, type FunctionSocket, type FunctionSource, type HistoryColumn, type HistoryOptions, type HistoryPosition, type HistoryStore, HistoryStoreError, type HookContext, HttpProblem, type IssueTokenOptions, type JobContext, type JobDeclaration, type JobDefinition, type JobOptions, type JobRun, type JobsRuntime, type JsonObject, type JsonValue, type JwtOptions, type JwtVerifyOptions, type KeyFunctionContext, type LinkedAccount, type ListParams, type LocalFilesOptions, type MailMessage, type Mailer, type MapLayer, type MapOptions, type MapSettings, type McpApprovals, type McpGateInput, type McpHandlerInput, type McpRoutesInput, type McpServerInput, type McpToolsInput, type McpWrites, type MemberInput, type Membership, MissingCredentials, type MobileConfig, type MobileRelease, type MobileReleaseAppInput, ModelError, type ModelSettings, type NewDevice, type NewNotification, type NewOrganization, type NewUser, type NotificationRecipients, NotificationSendError, type NotificationsOptions, type OfferedRelease, type OperatorProvider, type OrganizationRole, type OrganizationsOptions, type PgModule, type PipelineHook, type PlatformSignIn, type PluginOption, type PluginRef, type PngIcon, type ProtectedFunctionOptions, type PublicFunctionContext, type PublicFunctionEnv, type PublicFunctionHandler, type PublicFunctionOptions, type PushAnswer, type PushMessage, PushMessageError, type PushSender, type QueryOptions, type QueryResult, type ReadableResources, type ReasoningDetail, type ReasoningEffort, type RebindOption, type RecordKeyInput, type RecordPage, type ReleaseFile, type RenderedEmail, type ResourceChange, type ResourceSource, type RoleDefinition, type RolesInput, type RunContext, type RuntimeOptions, type S3Bucket, type S3FilesOptions, type S3ListPage, type S3Object, type ScanGuardMode, type ScheduledDelete, type SendNotification, type ServedReleaseFile, type Session, type SessionOrganization, type Sharp, type SignInPolicy, type SignInRule, type SignatureOptions, type SocketEvents, type SourceOption, type SourceRef, type StaffAccessRule, type StaffSignIn, type StandardSchema, type StandardWebhookOptions, type StartJobsOptions, type StoreFileInput, type StoredMember, type StoredNotification, type StoredObject, type StoredOrganization, type StoredUser, type StrayValues, type SubscriptionDefinition, type SubscriptionEvent, type SubscriptionOptions, type TenantValue, type ToolAnnotations, type ToolCall, type ToolContext, type ToolRecord, type ToolRecords, type ToolSpec, type TrustedApp, type TurnOptions, type UnreadableEntry, type Urgency, type User, type UserCreatedHook, type VapidSettings, type ViewSource, type WebPushFields, type WebPushOptions, type WebhooksOptions, type WidgetOptions, type WriteEvent, type WriteOperation, type WriteRecordToolsInput, addAppRoleToOwners, addMember, apiKeyCaller, apiKeySettings, apiKeyVariables, appNameOver, aspectRatio, assistantProtocolRoutes, assistantRoles, assistantSettings, assistantVariables, authSchemaDrift, authSchemaMigration, authStoreTables, backgroundSettled, badRequest, batchWriteTool, beforeSignInPluginsVariable, betterAuthTokens, capSocketMessages, changesMigration, checkAi, checkAuthSchema, checkChanges, checkComments, checkComputed, checkJobsSchema, checkNotificationsSchema, checkQueryRunner, checkResourcesOutsideAuthStore, checkSourceNames, checkViewQueries, checkWebhooksSchema, coalesce, commentsMigration, composeRelease, computedMigration, configExports, consoleAuditQueue, conversationKey, createAdmin, createConversations, createEncryptionTools, createFileCleanup, createOrganization, createRecordTool, createUser, defaultAppName, defaultHistoryPage, defaultSignInPolicy, defineEmail, defineFunction, defineJob, defineTool, deleteRecordTool, deleteUser, deviceIdParam, deviceStore, devicesPath, enqueueJob, errorReportingSettings, errorReportingVariable, eventMatcher, fileConversationStore, fileSize, fileType, forbidden, formatUri, functionApp, generateVapidKeys, getRecordTool, goTruePath, handleDroppedConnections, hasUsers, historyIdParam, historyIdPattern, historyLimits, historyPath, historyStore, honorSocketMessageCaps, imageSize, isBackgroundWork, isCaptured, isJobDefinition, isOAuthWellKnownPath, isSchedule, issueToken, jobDefinitions, jobsDrainApp, jobsSchema, jobsSchemaMigration, jwtAuthenticator, jwtVerifier, limitedFileStore, listOrganizations, listRecordsTool, listResourcesTool, listUsers, localFileStore, longQueryTimeoutMs, mapSettings, mapStyleUrl, mapStyleVariable, maxDevicesPerUser, maxHistoryPage, maxMessageBytes, maxRecipients, maxTokenTtlSeconds, maxTtlSeconds, maxUnreadCount, maxWidgetPropsBytes, mcpApprovals, mcpGate, mcpHandler, mcpRoutes, mcpServer, mcpToolContext, mcpTools, migrationCommand, mobileReleaseApp, mobileSigningKeyVariable, newWebhookSecret, normalizeRoles, notFound, notificationSenders, notificationsMigration, oauthWellKnownPaths, objectKey, parseColumns, parseRoles, passwordLength, pluginOptions, pluginsBeforeSignIn, pluginsFor, pluginsVariable, pngIcons, poolWaitMs, postgresDeviceStore, postgresHistoryStore, processor, pushMessage, queryRunnerMigration, readDbConnections, readJson, readOnlyQueryTool, readOperatorSettings, readOutbox, readPlatformSignIn, readRecordTools, readSigningKey, readVapidSettings, readWriteQueryTool, readableResources, realtimeLimits, recordOf, releaseManifest, removeDevicesWithUsers, removeHistoryWithUsers, removeMember, renderVariant, requestApproval, requireEnv, resourceChange, roleChoices, runInBackground, runReadOnlyQuery, runReadWriteQuery, runTurn, runtimeUrl, runtimeVariable, s3FileStore, seesAssistant, seesRuntime, sendNotification, sessionOf, setMemberRoles, setUserBanned, setUserRole, shownAppName, signInPolicyMethods, socketMessageCapOf, sourceOptions, sourcesFor, sourcesVariable, startErrorReporting, startJobs, storageCleanupSchedule, storageProvider, storeFile, storeUsage, streamChatCompletion, subscription, supabasePath, thumbHash, unauthorized, updateRecordTool, urgencies, vapidPrivateKeyVariable, vapidPublicKeyVariable, vapidSubjectVariable, variantPath, verifySignature, verifyStandardWebhook, waitUntil, wantsLongQueries, webManifestPath, webPushSender, webauthnPath, webhooksMigration, widget, withCacheBreakpoints, withTrustedApps, writeRecordTools };
|